From dbd4ab3457dd001ab4bbcec14315047b815f7dfe Mon Sep 17 00:00:00 2001 From: Stephan Bösebeck Date: Thu, 31 Mar 2016 23:15:59 +0200 Subject: fixed de_osx prefix in keymap include to avoid conflicts --- quantum/keymap_extras/keymap_german_osx.h | 156 +++++++++++++++--------------- 1 file changed, 78 insertions(+), 78 deletions(-) (limited to 'quantum') diff --git a/quantum/keymap_extras/keymap_german_osx.h b/quantum/keymap_extras/keymap_german_osx.h index da91b4bf4..d0b77fb80 100644 --- a/quantum/keymap_extras/keymap_german_osx.h +++ b/quantum/keymap_extras/keymap_german_osx.h @@ -9,92 +9,92 @@ // Alt gr // normal characters -#define DE_Z KC_Y -#define DE_Y KC_Z +#define DE_OSX_Z KC_Y +#define DE_OSX_Y KC_Z -#define DE_A KC_A -#define DE_B KC_B -#define DE_C KC_C -#define DE_D KC_D -#define DE_E KC_E -#define DE_F KC_F -#define DE_G KC_G -#define DE_H KC_H -#define DE_I KC_I -#define DE_J KC_J -#define DE_K KC_K -#define DE_L KC_L -#define DE_M KC_M -#define DE_N KC_N -#define DE_O KC_O -#define DE_P KC_P -#define DE_Q KC_Q -#define DE_R KC_R -#define DE_S KC_S -#define DE_T KC_T -#define DE_U KC_U -#define DE_V KC_V -#define DE_W KC_W -#define DE_X KC_X +#define DE_OSX_A KC_A +#define DE_OSX_B KC_B +#define DE_OSX_C KC_C +#define DE_OSX_D KC_D +#define DE_OSX_E KC_E +#define DE_OSX_F KC_F +#define DE_OSX_G KC_G +#define DE_OSX_H KC_H +#define DE_OSX_I KC_I +#define DE_OSX_J KC_J +#define DE_OSX_K KC_K +#define DE_OSX_L KC_L +#define DE_OSX_M KC_M +#define DE_OSX_N KC_N +#define DE_OSX_O KC_O +#define DE_OSX_P KC_P +#define DE_OSX_Q KC_Q +#define DE_OSX_R KC_R +#define DE_OSX_S KC_S +#define DE_OSX_T KC_T +#define DE_OSX_U KC_U +#define DE_OSX_V KC_V +#define DE_OSX_W KC_W +#define DE_OSX_X KC_X -#define DE_0 KC_0 -#define DE_1 KC_1 -#define DE_2 KC_2 -#define DE_3 KC_3 -#define DE_4 KC_4 -#define DE_5 KC_5 -#define DE_6 KC_6 -#define DE_7 KC_7 -#define DE_8 KC_8 -#define DE_9 KC_9 +#define DE_OSX_0 KC_0 +#define DE_OSX_1 KC_1 +#define DE_OSX_2 KC_2 +#define DE_OSX_3 KC_3 +#define DE_OSX_4 KC_4 +#define DE_OSX_5 KC_5 +#define DE_OSX_6 KC_6 +#define DE_OSX_7 KC_7 +#define DE_OSX_8 KC_8 +#define DE_OSX_9 KC_9 -#define DE_DOT KC_DOT -#define DE_COMM KC_COMM +#define DE_OSX_DOT KC_DOT +#define DE_OSX_COMM KC_COMM -#define DE_SS KC_MINS -#define DE_AE KC_QUOT -#define DE_UE KC_LBRC -#define DE_OE KC_SCLN +#define DE_OSX_SS KC_MINS +#define DE_OSX_AE KC_QUOT +#define DE_OSX_UE KC_LBRC +#define DE_OSX_OE KC_SCLN -#define DE_CIRC KC_NUBS // accent circumflex ^ and ring ° -#define DE_ACUT KC_EQL // accent acute ´ and grave ` -#define DE_PLUS KC_RBRC // + and * and ~ -#define DE_HASH KC_BSLS // # and ' -#define DE_LESS KC_GRV // < and > and | -#define DE_MINS KC_SLSH // - and _ +#define DE_OSX_CIRC KC_NUBS // accent circumflex ^ and ring ° +#define DE_OSX_ACUT KC_EQL // accent acute ´ and grave ` +#define DE_OSX_PLUS KC_RBRC // + and * and ~ +#define DE_OSX_HASH KC_BSLS // # and ' +#define DE_OSX_LESS KC_GRV // < and > and | +#define DE_OSX_MINS KC_SLSH // - and _ // shifted characters -#define DE_RING LSFT(DE_CIRC) // ° -#define DE_EXLM LSFT(KC_1) // ! -#define DE_DQOT LSFT(KC_2) // " -#define DE_PARA LSFT(KC_3) // § -#define DE_DLR LSFT(KC_4) // $ -#define DE_PERC LSFT(KC_5) // % -#define DE_AMPR LSFT(KC_6) // & -#define DE_SLSH LSFT(KC_7) // / -#define DE_LPRN LSFT(KC_8) // ( -#define DE_RPRN LSFT(KC_9) // ) -#define DE_EQL LSFT(KC_0) // = -#define DE_QST LSFT(DE_SS) // ? -#define DE_GRV LSFT(DE_ACUT) // ` -#define DE_ASTR LSFT(DE_PLUS) // * -#define DE_QUOT LSFT(DE_HASH) // ' -#define DE_MORE LSFT(DE_LESS) // > -#define DE_COLN LSFT(KC_DOT) // : -#define DE_SCLN LSFT(KC_COMM) // ; -#define DE_UNDS LSFT(DE_MINS) // _ +#define DE_OSX_RING LSFT(DE_OSX_CIRC) // ° +#define DE_OSX_EXLM LSFT(KC_1) // ! +#define DE_OSX_DQOT LSFT(KC_2) // " +#define DE_OSX_PARA LSFT(KC_3) // § +#define DE_OSX_DLR LSFT(KC_4) // $ +#define DE_OSX_PERC LSFT(KC_5) // % +#define DE_OSX_AMPR LSFT(KC_6) // & +#define DE_OSX_SLSH LSFT(KC_7) // / +#define DE_OSX_LPRN LSFT(KC_8) // ( +#define DE_OSX_RPRN LSFT(KC_9) // ) +#define DE_OSX_EQL LSFT(KC_0) // = +#define DE_OSX_QST LSFT(DE_OSX_SS) // ? +#define DE_OSX_GRV LSFT(DE_OSX_ACUT) // ` +#define DE_OSX_ASTR LSFT(DE_OSX_PLUS) // * +#define DE_OSX_QUOT LSFT(DE_OSX_HASH) // ' +#define DE_OSX_MORE LSFT(DE_OSX_LESS) // > +#define DE_OSX_COLN LSFT(KC_DOT) // : +#define DE_OSX_SCLN LSFT(KC_COMM) // ; +#define DE_OSX_UNDS LSFT(DE_OSX_MINS) // _ // Alt-ed characters -#define DE_SQ2 LALT(KC_2) // ² -#define DE_SQ3 LALT(KC_3) // ³ -#define DE_LCBR LALT(KC_8) // { -#define DE_LBRC LALT(KC_5) // [ -#define DE_RBRC LALT(KC_6) // ] -#define DE_RCBR LALT(KC_9) // } -#define DE_BSLS LALT(LSFT(KC_7)) // backslash -#define DE_AT LALT(DE_L) // @ -#define DE_EURO LALT(KC_E) // € -#define DE_TILD LALT(DE_N) // ~ -#define DE_PIPE LALT(DE_7) // | +#define DE_OSX_SQ2 LALT(KC_2) // ² +#define DE_OSX_SQ3 LALT(KC_3) // ³ +#define DE_OSX_LCBR LALT(KC_8) // { +#define DE_OSX_LBRC LALT(KC_5) // [ +#define DE_OSX_RBRC LALT(KC_6) // ] +#define DE_OSX_RCBR LALT(KC_9) // } +#define DE_OSX_BSLS LALT(LSFT(KC_7)) // backslash +#define DE_OSX_AT LALT(DE_OSX_L) // @ +#define DE_OSX_EURO LALT(KC_E) // € +#define DE_OSX_TILD LALT(DE_OSX_N) // ~ +#define DE_OSX_PIPE LALT(DE_OSX_7) // | #endif -- cgit v1.2.3-24-g4f1b From 976d0a327b563ff83d0f7bcee41b2360877bface Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Tue, 5 Apr 2016 09:21:44 -0400 Subject: add silent notes --- quantum/audio.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'quantum') diff --git a/quantum/audio.c b/quantum/audio.c index 3a3a1a491..f29d941d7 100644 --- a/quantum/audio.c +++ b/quantum/audio.c @@ -247,6 +247,9 @@ ISR(TIMER3_COMPA_vect) { if (note_frequency > 0) { ICR3 = (int)(((double)F_CPU) / note_frequency); // Set max to the period OCR3A = (int)(((double)F_CPU) / note_frequency) >> 1; // Set compare to half the period + } else { + ICR3 = 0; + OCR3A = 0; } #endif -- cgit v1.2.3-24-g4f1b From 9cfc74c35b940884618b0fe1e6fd25c570e1c974 Mon Sep 17 00:00:00 2001 From: Erez Zukerman Date: Thu, 7 Apr 2016 15:21:06 +0300 Subject: [Erez & Jack] Makes tri-layer available across Quantum --- quantum/keymap_common.c | 8 ++++++++ quantum/keymap_common.h | 4 ++++ 2 files changed, 12 insertions(+) (limited to 'quantum') diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c index e3030a886..3a00d36f0 100644 --- a/quantum/keymap_common.c +++ b/quantum/keymap_common.c @@ -291,3 +291,11 @@ action_t keymap_func_to_action(uint16_t keycode) // For FUNC without 8bit limit return (action_t){ .code = pgm_read_word(&fn_actions[(int)keycode]) }; } + +void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3) { + if (IS_LAYER_ON(layer1) && IS_LAYER_ON(layer2)) { + layer_on(layer3); + } else { + layer_off(layer3); + } +} diff --git a/quantum/keymap_common.h b/quantum/keymap_common.h index 4a877d2a7..7452a1ff3 100644 --- a/quantum/keymap_common.h +++ b/quantum/keymap_common.h @@ -208,5 +208,9 @@ extern const uint16_t fn_actions[]; #define UNICODE(n) (n | 0x8000) #define UC(n) UNICODE(n) +// For tri-layer +void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3); +#define IS_LAYER_ON(layer) ((layer_state) & (1UL<<(layer))) +#define IS_LAYER_OFF(layer) ((!layer_state) & (1UL<<(layer))) #endif -- cgit v1.2.3-24-g4f1b From 97f8f378761506914b69d4fd2d5661bfcae28295 Mon Sep 17 00:00:00 2001 From: skullY Date: Sun, 10 Apr 2016 21:16:49 -0700 Subject: Fixup RGBLIGHT support for clueboard2 --- quantum/rgblight.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'quantum') diff --git a/quantum/rgblight.c b/quantum/rgblight.c index 2215cf5cd..6adc9e278 100644 --- a/quantum/rgblight.c +++ b/quantum/rgblight.c @@ -190,7 +190,7 @@ void rgblight_mode(uint8_t mode) { rgblight_config.mode = mode; } eeconfig_write_rgblight(rgblight_config.raw); - dprintf("rgblight mode: %u\n", rgblight_config.mode); + xprintf("rgblight mode: %u\n", rgblight_config.mode); if (rgblight_config.mode == 1) { rgblight_timer_disable(); } else if (rgblight_config.mode >=2 && rgblight_config.mode <=23) { @@ -207,7 +207,7 @@ void rgblight_mode(uint8_t mode) { void rgblight_toggle(void) { rgblight_config.enable ^= 1; eeconfig_write_rgblight(rgblight_config.raw); - dprintf("rgblight toggle: rgblight_config.enable = %u\n", rgblight_config.enable); + xprintf("rgblight toggle: rgblight_config.enable = %u\n", rgblight_config.enable); if (rgblight_config.enable) { rgblight_mode(rgblight_config.mode); } else { @@ -300,7 +300,7 @@ void rgblight_sethsv(uint16_t hue, uint8_t sat, uint8_t val){ rgblight_config.sat = sat; rgblight_config.val = val; eeconfig_write_rgblight(rgblight_config.raw); - dprintf("rgblight set hsv [EEPROM]: %u,%u,%u\n", rgblight_config.hue, rgblight_config.sat, rgblight_config.val); + xprintf("rgblight set hsv [EEPROM]: %u,%u,%u\n", rgblight_config.hue, rgblight_config.sat, rgblight_config.val); } } -- cgit v1.2.3-24-g4f1b From 3755ef5ddbdad9f25a53fee951c3eb78035b52c3 Mon Sep 17 00:00:00 2001 From: IBNobody Date: Wed, 13 Apr 2016 20:57:51 -0500 Subject: Compiler Warnings / Atomic TLC Corrected compiler warnings for a number of issues. Gave Atomic some TLC. --- quantum/keymap_common.c | 6 ++++-- quantum/keymap_common.h | 2 -- quantum/keymap_midi.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'quantum') diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c index 2eef4f15a..ae6cddb34 100644 --- a/quantum/keymap_common.c +++ b/quantum/keymap_common.c @@ -87,6 +87,7 @@ action_t action_for_key(uint8_t layer, keypos_t key) return action; #endif } else if (keycode == RESET) { // RESET is 0x5000, which is why this is here + action_t action; clear_keyboard(); #ifdef AUDIO_ENABLE play_notes(&goodbye, 5, false); @@ -96,12 +97,13 @@ action_t action_for_key(uint8_t layer, keypos_t key) *(uint16_t *)0x0800 = 0x7777; // these two are a-star-specific #endif bootloader_jump(); - return; + return action; } else if (keycode == DEBUG) { // DEBUG is 0x5001 // TODO: Does this actually work? + action_t action; print("\nDEBUG: enabled.\n"); debug_enable = true; - return; + return action; } else if (keycode >= 0x5000 && keycode < 0x6000) { // Layer movement shortcuts // See .h to see constraints/usage diff --git a/quantum/keymap_common.h b/quantum/keymap_common.h index 3db40772e..4a877d2a7 100644 --- a/quantum/keymap_common.h +++ b/quantum/keymap_common.h @@ -184,8 +184,6 @@ extern const uint16_t fn_actions[]; // Toggle to layer - 256 layer max #define TG(layer) (layer | 0x5400) -#define MIDI(n) (n | 0x6000) - // M-od, T-ap - 256 keycode max #define MT(mod, kc) (kc | 0x7000 | ((mod & 0xF) << 8)) #define CTL_T(kc) MT(0x1, kc) diff --git a/quantum/keymap_midi.h b/quantum/keymap_midi.h index a89420ce2..436fb2eb5 100644 --- a/quantum/keymap_midi.h +++ b/quantum/keymap_midi.h @@ -20,7 +20,7 @@ along with this program. If not, see . #include -#define MIDI 0x6000 +#define MIDI(n) (n | 0x6000) #define MIDI12 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000 #define CHNL(note, channel) (note + (channel << 8)) -- cgit v1.2.3-24-g4f1b From 2900b4884598b06ed59371c48ecea9d3f0bff5ac Mon Sep 17 00:00:00 2001 From: IBNobody Date: Wed, 13 Apr 2016 22:04:44 -0500 Subject: Added parenthesis to midi macro. --- quantum/keymap_midi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'quantum') diff --git a/quantum/keymap_midi.h b/quantum/keymap_midi.h index 436fb2eb5..795f26380 100644 --- a/quantum/keymap_midi.h +++ b/quantum/keymap_midi.h @@ -20,7 +20,7 @@ along with this program. If not, see . #include -#define MIDI(n) (n | 0x6000) +#define MIDI(n) ((n) | 0x6000) #define MIDI12 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000 #define CHNL(note, channel) (note + (channel << 8)) -- cgit v1.2.3-24-g4f1b From 63462bf8c12cea1c13ca1bd1f105fe53f556806e Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Thu, 14 Apr 2016 20:42:14 -0400 Subject: changing up the makefile a bit --- quantum/quantum.mk | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'quantum') diff --git a/quantum/quantum.mk b/quantum/quantum.mk index de93af7e8..3069f582c 100644 --- a/quantum/quantum.mk +++ b/quantum/quantum.mk @@ -23,19 +23,19 @@ ifndef CUSTOM_MATRIX SRC += $(QUANTUM_DIR)/matrix.c endif -ifdef MIDI_ENABLE +ifeq ($(MIDI_ENABLE), yes) SRC += $(QUANTUM_DIR)/keymap_midi.c endif -ifdef AUDIO_ENABLE +ifeq ($(AUDIO_ENABLE), yes) SRC += $(QUANTUM_DIR)/audio.c endif -ifdef UNICODE_ENABLE +ifeq ($(UNICODE_ENABLE), yes) SRC += $(QUANTUM_DIR)/keymap_unicode.c endif -ifdef RGBLIGHT_ENABLE +ifeq ($(RGBLIGHT_ENABLE), yes) SRC += $(QUANTUM_DIR)/light_ws2812.c SRC += $(QUANTUM_DIR)/rgblight.c OPT_DEFS += -DRGBLIGHT_ENABLE -- cgit v1.2.3-24-g4f1b From bb0836c62016f482f517771a9f5a8dbc68bd0a1c Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Fri, 15 Apr 2016 00:26:22 -0400 Subject: the spacessss --- quantum/quantum.mk | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'quantum') diff --git a/quantum/quantum.mk b/quantum/quantum.mk index 3069f582c..17bb50171 100644 --- a/quantum/quantum.mk +++ b/quantum/quantum.mk @@ -23,19 +23,19 @@ ifndef CUSTOM_MATRIX SRC += $(QUANTUM_DIR)/matrix.c endif -ifeq ($(MIDI_ENABLE), yes) +ifeq ($(strip $(MIDI_ENABLE)), yes) SRC += $(QUANTUM_DIR)/keymap_midi.c endif -ifeq ($(AUDIO_ENABLE), yes) +ifeq ($(strip $(AUDIO_ENABLE)), yes) SRC += $(QUANTUM_DIR)/audio.c endif -ifeq ($(UNICODE_ENABLE), yes) +ifeq ($(strip $(UNICODE_ENABLE)), yes) SRC += $(QUANTUM_DIR)/keymap_unicode.c endif -ifeq ($(RGBLIGHT_ENABLE), yes) +ifeq ($(strip $(RGBLIGHT_ENABLE)), yes) SRC += $(QUANTUM_DIR)/light_ws2812.c SRC += $(QUANTUM_DIR)/rgblight.c OPT_DEFS += -DRGBLIGHT_ENABLE -- cgit v1.2.3-24-g4f1b From ee2ee7f4f049dda385a9db7dddd8e7e91681315b Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Fri, 15 Apr 2016 13:44:07 -0400 Subject: audio note length fixes --- quantum/audio.c | 7 ++++++- quantum/keymap_common.c | 10 ++++------ 2 files changed, 10 insertions(+), 7 deletions(-) (limited to 'quantum') diff --git a/quantum/audio.c b/quantum/audio.c index f29d941d7..50e5505fe 100644 --- a/quantum/audio.c +++ b/quantum/audio.c @@ -255,7 +255,12 @@ ISR(TIMER3_COMPA_vect) { note_position++; - if (note_position >= note_length) { + bool end_of_note = false; + if (ICR3 > 0) + end_of_note = (note_position >= (note_length / ICR3 * 0xFFFF)); + else + end_of_note = (note_position >= (note_length * 0x7FF)); + if (end_of_note) { current_note++; if (current_note >= notes_length) { if (notes_repeat) { diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c index ae6cddb34..e3030a886 100644 --- a/quantum/keymap_common.c +++ b/quantum/keymap_common.c @@ -33,11 +33,9 @@ along with this program. If not, see . #include "audio.h" float goodbye[][2] = { - {440.0*pow(2.0,(67)/12.0), 400}, - {0, 50}, - {440.0*pow(2.0,(60)/12.0), 400}, - {0, 50}, - {440.0*pow(2.0,(55)/12.0), 600}, + {440.0*pow(2.0,(67)/12.0), 8}, + {440.0*pow(2.0,(60)/12.0), 8}, + {440.0*pow(2.0,(55)/12.0), 12}, }; #endif @@ -90,7 +88,7 @@ action_t action_for_key(uint8_t layer, keypos_t key) action_t action; clear_keyboard(); #ifdef AUDIO_ENABLE - play_notes(&goodbye, 5, false); + play_notes(&goodbye, 3, false); #endif _delay_ms(250); #ifdef ATREUS_ASTAR -- cgit v1.2.3-24-g4f1b From 8f85117aa9e060371177e3b523bc89dc7aad19e8 Mon Sep 17 00:00:00 2001 From: IBNobody Date: Fri, 15 Apr 2016 14:42:50 -0500 Subject: Added Audio to my Atomic --- quantum/audio.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'quantum') diff --git a/quantum/audio.h b/quantum/audio.h index 99203cea7..31f9a3579 100644 --- a/quantum/audio.h +++ b/quantum/audio.h @@ -6,6 +6,6 @@ void play_sample(uint8_t * s, uint16_t l, bool r); void play_note(double freq, int vol); void stop_note(double freq); -void stop_all_notes(); -void init_notes(); +void stop_all_notes(void); +void init_notes(void); void play_notes(float (*np)[][2], uint8_t n_length, bool n_repeat); \ No newline at end of file -- cgit v1.2.3-24-g4f1b From 0faa18eab996c2cfcc5da0b60b702f52335c5854 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Fri, 15 Apr 2016 23:38:21 -0400 Subject: audio enable stored in eeprom --- quantum/audio.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++- quantum/audio.h | 14 +++++++++++++- 2 files changed, 60 insertions(+), 2 deletions(-) (limited to 'quantum') diff --git a/quantum/audio.c b/quantum/audio.c index 50e5505fe..73985479c 100644 --- a/quantum/audio.c +++ b/quantum/audio.c @@ -8,6 +8,8 @@ #include "audio.h" #include "keymap_common.h" +#include "eeconfig.h" + #define PI 3.14159265 // #define PWM_AUDIO @@ -57,6 +59,25 @@ uint8_t notes_length; bool notes_repeat; uint8_t current_note = 0; +audio_config_t audio_config; + + +void audio_toggle(void) { + audio_config.enable ^= 1; + eeconfig_write_audio(audio_config.raw); +} + +void audio_on(void) { + audio_config.enable = 1; + eeconfig_write_audio(audio_config.raw); +} + +void audio_off(void) { + audio_config.enable = 0; + eeconfig_write_audio(audio_config.raw); +} + + void stop_all_notes() { voices = 0; #ifdef PWM_AUDIO @@ -129,6 +150,12 @@ void stop_note(double freq) { void init_notes() { + /* check signature */ + if (!eeconfig_is_enabled()) { + eeconfig_init(); + } + audio_config.raw = eeconfig_read_audio(); + #ifdef PWM_AUDIO PLLFRQ = _BV(PDIV2); PLLCSR = _BV(PLLE); @@ -160,7 +187,6 @@ void init_notes() { ISR(TIMER3_COMPA_vect) { - if (note) { #ifdef PWM_AUDIO if (voices == 1) { @@ -288,9 +314,16 @@ ISR(TIMER3_COMPA_vect) { } + if (!audio_config.enable) { + notes = false; + note = false; + } } void play_notes(float (*np)[][2], uint8_t n_length, bool n_repeat) { + +if (audio_config.enable) { + if (note) stop_all_notes(); notes = true; @@ -319,7 +352,12 @@ void play_notes(float (*np)[][2], uint8_t n_length, bool n_repeat) { #endif } +} + void play_sample(uint8_t * s, uint16_t l, bool r) { + +if (audio_config.enable) { + stop_all_notes(); place_int = 0; sample = s; @@ -330,9 +368,15 @@ void play_sample(uint8_t * s, uint16_t l, bool r) { TIMSK3 |= _BV(OCIE3A); #else #endif + +} + } void play_note(double freq, int vol) { + +if (audio_config.enable) { + if (notes) stop_all_notes(); note = true; @@ -367,4 +411,6 @@ void play_note(double freq, int vol) { TCCR3A |= _BV(COM3A1); #endif +} + } \ No newline at end of file diff --git a/quantum/audio.h b/quantum/audio.h index 99203cea7..58270015d 100644 --- a/quantum/audio.h +++ b/quantum/audio.h @@ -3,9 +3,21 @@ #include #include +typedef union { + uint8_t raw; + struct { + bool enable :1; + uint8_t level :7; + }; +} audio_config_t; + +void audio_toggle(void); +void audio_on(void); +void audio_off(void); + void play_sample(uint8_t * s, uint16_t l, bool r); void play_note(double freq, int vol); void stop_note(double freq); void stop_all_notes(); void init_notes(); -void play_notes(float (*np)[][2], uint8_t n_length, bool n_repeat); \ No newline at end of file +void play_notes(float (*np)[][2], uint8_t n_length, bool n_repeat); -- cgit v1.2.3-24-g4f1b From 0b0ec82427aff54481103559066213056b6d7598 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Sat, 16 Apr 2016 00:01:22 -0400 Subject: eeprom reset tool --- quantum/tools/README.md | 6 ++++++ quantum/tools/eeprom_reset.hex | 9 +++++++++ 2 files changed, 15 insertions(+) create mode 100644 quantum/tools/README.md create mode 100644 quantum/tools/eeprom_reset.hex (limited to 'quantum') diff --git a/quantum/tools/README.md b/quantum/tools/README.md new file mode 100644 index 000000000..070214423 --- /dev/null +++ b/quantum/tools/README.md @@ -0,0 +1,6 @@ +`eeprom_reset.hex` is to reset the eeprom on the Atmega32u4, like this: + + dfu-programmer atmega32u4 erase + dfu-programmer atmega32u4 flash --eeprom eeprom-reset.bin + + You'll need to reflash afterwards, because DFU requires the flash to be erased before messing with the eeprom. \ No newline at end of file diff --git a/quantum/tools/eeprom_reset.hex b/quantum/tools/eeprom_reset.hex new file mode 100644 index 000000000..a8a75389f --- /dev/null +++ b/quantum/tools/eeprom_reset.hex @@ -0,0 +1,9 @@ +:10000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +:10001000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 +:10002000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 +:10003000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +:10004000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 +:10005000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +:10006000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 +:10007000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +:00000001FF -- cgit v1.2.3-24-g4f1b From 142ce47698613bb8fb757f13c29928a572a4d9d9 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Sat, 16 Apr 2016 01:23:08 -0400 Subject: added keymap_extras to path --- quantum/quantum.mk | 1 + 1 file changed, 1 insertion(+) (limited to 'quantum') diff --git a/quantum/quantum.mk b/quantum/quantum.mk index 17bb50171..1fe7390eb 100644 --- a/quantum/quantum.mk +++ b/quantum/quantum.mk @@ -46,6 +46,7 @@ endif # Search Path VPATH += $(TOP_DIR)/$(QUANTUM_DIR) +VPATH += $(TOP_DIR)/$(QUANTUM_DIR)/keymap_extras include $(TMK_DIR)/protocol/lufa.mk -- cgit v1.2.3-24-g4f1b From 86169833c597fa5f2b5226e1587c48a6692ec017 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Sat, 16 Apr 2016 15:47:17 -0400 Subject: updates to preonic default, music mode integrated --- quantum/audio.c | 100 +++++++++++++++++++++++++++++++------------------------- 1 file changed, 55 insertions(+), 45 deletions(-) (limited to 'quantum') diff --git a/quantum/audio.c b/quantum/audio.c index 73985479c..5edcccdbe 100644 --- a/quantum/audio.c +++ b/quantum/audio.c @@ -32,6 +32,8 @@ int voice_place = 0; double frequency = 0; int volume = 0; long position = 0; +int duty_place = 1; +int duty_counter = 0; double frequencies[8] = {0, 0, 0, 0, 0, 0, 0, 0}; int volumes[8] = {0, 0, 0, 0, 0, 0, 0, 0}; @@ -98,53 +100,55 @@ void stop_all_notes() { } void stop_note(double freq) { - #ifdef PWM_AUDIO - freq = freq / SAMPLE_RATE; - #endif - for (int i = 7; i >= 0; i--) { - if (frequencies[i] == freq) { - frequencies[i] = 0; - volumes[i] = 0; - for (int j = i; (j < 7); j++) { - frequencies[j] = frequencies[j+1]; - frequencies[j+1] = 0; - volumes[j] = volumes[j+1]; - volumes[j+1] = 0; - } - } - } - voices--; - if (voices < 0) - voices = 0; - if (voices == 0) { + if (note) { #ifdef PWM_AUDIO - TIMSK3 &= ~_BV(OCIE3A); - #else - TIMSK3 &= ~_BV(OCIE3A); - TCCR3A &= ~_BV(COM3A1); + freq = freq / SAMPLE_RATE; #endif - frequency = 0; - volume = 0; - note = false; - } else { - double freq = frequencies[voices - 1]; - int vol = volumes[voices - 1]; - double starting_f = frequency; - if (frequency < freq) { - sliding = true; - for (double f = starting_f; f <= freq; f += ((freq - starting_f) / 2000.0)) { - frequency = f; + for (int i = 7; i >= 0; i--) { + if (frequencies[i] == freq) { + frequencies[i] = 0; + volumes[i] = 0; + for (int j = i; (j < 7); j++) { + frequencies[j] = frequencies[j+1]; + frequencies[j+1] = 0; + volumes[j] = volumes[j+1]; + volumes[j+1] = 0; + } } - sliding = false; - } else if (frequency > freq) { - sliding = true; - for (double f = starting_f; f >= freq; f -= ((starting_f - freq) / 2000.0)) { - frequency = f; + } + voices--; + if (voices < 0) + voices = 0; + if (voices == 0) { + #ifdef PWM_AUDIO + TIMSK3 &= ~_BV(OCIE3A); + #else + TIMSK3 &= ~_BV(OCIE3A); + TCCR3A &= ~_BV(COM3A1); + #endif + frequency = 0; + volume = 0; + note = false; + } else { + double freq = frequencies[voices - 1]; + int vol = volumes[voices - 1]; + double starting_f = frequency; + if (frequency < freq) { + sliding = true; + for (double f = starting_f; f <= freq; f += ((freq - starting_f) / 2000.0)) { + frequency = f; + } + sliding = false; + } else if (frequency > freq) { + sliding = true; + for (double f = starting_f; f >= freq; f -= ((starting_f - freq) / 2000.0)) { + frequency = f; + } + sliding = false; } - sliding = false; + frequency = freq; + volume = vol; } - frequency = freq; - volume = vol; } } @@ -239,13 +243,19 @@ ISR(TIMER3_COMPA_vect) { if (frequency > 0) { // ICR3 = (int)(((double)F_CPU) / frequency); // Set max to the period // OCR3A = (int)(((double)F_CPU) / frequency) >> 1; // Set compare to half the period - if (place > 10) { + voice_place %= voices; + if (place > (frequencies[voice_place] / 500)) { voice_place = (voice_place + 1) % voices; place = 0.0; } ICR3 = (int)(((double)F_CPU) / frequencies[voice_place]); // Set max to the period - OCR3A = (int)(((double)F_CPU) / frequencies[voice_place]) >> 1; // Set compare to half the period + OCR3A = (int)(((double)F_CPU) / frequencies[voice_place]) >> 1 * duty_place; // Set compare to half the period place++; + // if (duty_counter > (frequencies[voice_place] / 500)) { + // duty_place = (duty_place % 3) + 1; + // duty_counter = 0; + // } + // duty_counter++; } #endif } @@ -375,7 +385,7 @@ if (audio_config.enable) { void play_note(double freq, int vol) { -if (audio_config.enable) { +if (audio_config.enable && voices < 8) { if (notes) stop_all_notes(); -- cgit v1.2.3-24-g4f1b From ab19ebd08a8b955775e6fa94cdf6b8d128d8b43c Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Sat, 16 Apr 2016 18:51:58 -0400 Subject: MAGIC functionality, AG swap in default layout --- quantum/keymap_common.c | 250 ++++++++++++++++++++++++++---------------------- quantum/keymap_common.h | 28 +++++- 2 files changed, 163 insertions(+), 115 deletions(-) (limited to 'quantum') diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c index 3a00d36f0..b91916685 100644 --- a/quantum/keymap_common.c +++ b/quantum/keymap_common.c @@ -27,6 +27,8 @@ along with this program. If not, see . #include "keymap_midi.h" #include "bootloader.h" +extern keymap_config_t keymap_config; + #include #include #ifdef AUDIO_ENABLE @@ -47,120 +49,9 @@ action_t action_for_key(uint8_t layer, keypos_t key) // 16bit keycodes - important uint16_t keycode = keymap_key_to_keycode(layer, key); - if (keycode >= 0x0100 && keycode < 0x2000) { - // Has a modifier - action_t action; - // Split it up - action.code = ACTION_MODS_KEY(keycode >> 8, keycode & 0xFF); // adds modifier to key - return action; - } else if (keycode >= 0x2000 && keycode < 0x3000) { - // Is a shortcut for function layer, pull last 12bits - // This means we have 4,096 FN macros at our disposal - return keymap_func_to_action(keycode & 0xFFF); - } else if (keycode >= 0x3000 && keycode < 0x4000) { - // When the code starts with 3, it's an action macro. - action_t action; - action.code = ACTION_MACRO(keycode & 0xFF); - return action; -#ifdef BACKLIGHT_ENABLE - } else if (keycode >= BL_0 && keycode <= BL_15) { - action_t action; - action.code = ACTION_BACKLIGHT_LEVEL(keycode & 0x000F); - return action; - } else if (keycode == BL_DEC) { - action_t action; - action.code = ACTION_BACKLIGHT_DECREASE(); - return action; - } else if (keycode == BL_INC) { - action_t action; - action.code = ACTION_BACKLIGHT_INCREASE(); - return action; - } else if (keycode == BL_TOGG) { - action_t action; - action.code = ACTION_BACKLIGHT_TOGGLE(); - return action; - } else if (keycode == BL_STEP) { - action_t action; - action.code = ACTION_BACKLIGHT_STEP(); - return action; -#endif - } else if (keycode == RESET) { // RESET is 0x5000, which is why this is here - action_t action; - clear_keyboard(); - #ifdef AUDIO_ENABLE - play_notes(&goodbye, 3, false); - #endif - _delay_ms(250); - #ifdef ATREUS_ASTAR - *(uint16_t *)0x0800 = 0x7777; // these two are a-star-specific - #endif - bootloader_jump(); - return action; - } else if (keycode == DEBUG) { // DEBUG is 0x5001 - // TODO: Does this actually work? - action_t action; - print("\nDEBUG: enabled.\n"); - debug_enable = true; - return action; - } else if (keycode >= 0x5000 && keycode < 0x6000) { - // Layer movement shortcuts - // See .h to see constraints/usage - int type = (keycode >> 0x8) & 0xF; - if (type == 0x1) { - // Layer set "GOTO" - int when = (keycode >> 0x4) & 0x3; - int layer = keycode & 0xF; - action_t action; - action.code = ACTION_LAYER_SET(layer, when); - return action; - } else if (type == 0x2) { - // Momentary layer - int layer = keycode & 0xFF; - action_t action; - action.code = ACTION_LAYER_MOMENTARY(layer); - return action; - } else if (type == 0x3) { - // Set default layer - int layer = keycode & 0xFF; - action_t action; - action.code = ACTION_DEFAULT_LAYER_SET(layer); - return action; - } else if (type == 0x4) { - // Set default layer - int layer = keycode & 0xFF; - action_t action; - action.code = ACTION_LAYER_TOGGLE(layer); - return action; - } -#ifdef MIDI_ENABLE - } else if (keycode >= 0x6000 && keycode < 0x7000) { - action_t action; - action.code = ACTION_FUNCTION_OPT(keycode & 0xFF, (keycode & 0x0F00) >> 8); - return action; -#endif - } else if (keycode >= 0x7000 && keycode < 0x8000) { - action_t action; - action.code = ACTION_MODS_TAP_KEY((keycode >> 0x8) & 0xF, keycode & 0xFF); - return action; - } else if (keycode >= 0x8000 && keycode < 0x9000) { - action_t action; - action.code = ACTION_LAYER_TAP_KEY((keycode >> 0x8) & 0xF, keycode & 0xFF); - return action; -#ifdef UNICODE_ENABLE - } else if (keycode >= 0x8000000) { - action_t action; - uint16_t unicode = keycode & ~(0x8000); - action.code = ACTION_FUNCTION_OPT(unicode & 0xFF, (unicode & 0xFF00) >> 8); - return action; -#endif - } else { - - } - switch (keycode) { case KC_FN0 ... KC_FN31: return keymap_fn_to_action(keycode); -#ifdef BOOTMAGIC_ENABLE case KC_CAPSLOCK: case KC_LOCKING_CAPS: if (keymap_config.swap_control_capslock || keymap_config.capslock_to_control) { @@ -224,7 +115,6 @@ action_t action_for_key(uint8_t layer, keypos_t key) return keycode_to_action(KC_BSLASH); } return keycode_to_action(KC_BSPACE); -#endif default: return keycode_to_action(keycode); } @@ -265,6 +155,142 @@ static action_t keycode_to_action(uint16_t keycode) case KC_TRNS: action.code = ACTION_TRANSPARENT; break; + case 0x0100 ... 0x1FFF: ; + // Has a modifier + // Split it up + action.code = ACTION_MODS_KEY(keycode >> 8, keycode & 0xFF); // adds modifier to key + break; + case 0x2000 ... 0x2FFF: + // Is a shortcut for function layer, pull last 12bits + // This means we have 4,096 FN macros at our disposal + return keymap_func_to_action(keycode & 0xFFF); + break; + case 0x3000 ... 0x3FFF: ; + // When the code starts with 3, it's an action macro. + action.code = ACTION_MACRO(keycode & 0xFF); + break; + #ifdef BACKLIGHT_ENABLE + case BL_0 ... BL_15: + action.code = ACTION_BACKLIGHT_LEVEL(keycode & 0x000F); + break; + case BL_DEC: + action.code = ACTION_BACKLIGHT_DECREASE(); + break; + case BL_INC: + action.code = ACTION_BACKLIGHT_INCREASE(); + break; + case BL_TOGG: + action.code = ACTION_BACKLIGHT_TOGGLE(); + break; + case BL_STEP: + action.code = ACTION_BACKLIGHT_STEP(); + break; + #endif + case RESET: ; // RESET is 0x5000, which is why this is here + clear_keyboard(); + #ifdef AUDIO_ENABLE + play_notes(&goodbye, 3, false); + #endif + _delay_ms(250); + #ifdef ATREUS_ASTAR + *(uint16_t *)0x0800 = 0x7777; // these two are a-star-specific + #endif + bootloader_jump(); + break; + case DEBUG: ; // DEBUG is 0x5001 + print("\nDEBUG: enabled.\n"); + debug_enable = true; + break; + case 0x5002 ... 0x50FF: + // MAGIC actions (BOOTMAGIC without the boot) + if (!eeconfig_is_enabled()) { + eeconfig_init(); + } + /* keymap config */ + keymap_config.raw = eeconfig_read_keymap(); + if (keycode == MAGIC_SWAP_CONTROL_CAPSLOCK) { + keymap_config.swap_control_capslock = 1; + } else if (keycode == MAGIC_CAPSLOCK_TO_CONTROL) { + keymap_config.capslock_to_control = 1; + } else if (keycode == MAGIC_SWAP_LALT_LGUI) { + keymap_config.swap_lalt_lgui = 1; + } else if (keycode == MAGIC_SWAP_RALT_RGUI) { + keymap_config.swap_ralt_rgui = 1; + } else if (keycode == MAGIC_NO_GUI) { + keymap_config.no_gui = 1; + } else if (keycode == MAGIC_SWAP_GRAVE_ESC) { + keymap_config.swap_grave_esc = 1; + } else if (keycode == MAGIC_SWAP_BACKSLASH_BACKSPACE) { + keymap_config.swap_backslash_backspace = 1; + } else if (keycode == MAGIC_HOST_NKRO) { + keymap_config.nkro = 1; + } else if (keycode == MAGIC_SWAP_ALT_GUI) { + keymap_config.swap_lalt_lgui = 1; + keymap_config.swap_ralt_rgui = 1; + } + /* UNs */ + else if (keycode == MAGIC_UNSWAP_CONTROL_CAPSLOCK) { + keymap_config.swap_control_capslock = 0; + } else if (keycode == MAGIC_UNCAPSLOCK_TO_CONTROL) { + keymap_config.capslock_to_control = 0; + } else if (keycode == MAGIC_UNSWAP_LALT_LGUI) { + keymap_config.swap_lalt_lgui = 0; + } else if (keycode == MAGIC_UNSWAP_RALT_RGUI) { + keymap_config.swap_ralt_rgui = 0; + } else if (keycode == MAGIC_UNNO_GUI) { + keymap_config.no_gui = 0; + } else if (keycode == MAGIC_UNSWAP_GRAVE_ESC) { + keymap_config.swap_grave_esc = 0; + } else if (keycode == MAGIC_UNSWAP_BACKSLASH_BACKSPACE) { + keymap_config.swap_backslash_backspace = 0; + } else if (keycode == MAGIC_UNHOST_NKRO) { + keymap_config.nkro = 0; + } else if (keycode == MAGIC_UNSWAP_ALT_GUI) { + keymap_config.swap_lalt_lgui = 0; + keymap_config.swap_ralt_rgui = 0; + } + eeconfig_write_keymap(keymap_config.raw); + break; + case 0x5100 ... 0x5FFF: ; + // Layer movement shortcuts + // See .h to see constraints/usage + int type = (keycode >> 0x8) & 0xF; + if (type == 0x1) { + // Layer set "GOTO" + int when = (keycode >> 0x4) & 0x3; + int layer = keycode & 0xF; + action.code = ACTION_LAYER_SET(layer, when); + } else if (type == 0x2) { + // Momentary layer + int layer = keycode & 0xFF; + action.code = ACTION_LAYER_MOMENTARY(layer); + } else if (type == 0x3) { + // Set default layer + int layer = keycode & 0xFF; + action.code = ACTION_DEFAULT_LAYER_SET(layer); + } else if (type == 0x4) { + // Set default layer + int layer = keycode & 0xFF; + action.code = ACTION_LAYER_TOGGLE(layer); + } + break; + #ifdef MIDI_ENABLE + case 0x6000 ... 0x6FFF: + action.code = ACTION_FUNCTION_OPT(keycode & 0xFF, (keycode & 0x0F00) >> 8); + break; + #endif + case 0x7000 ... 0x7FFF: + action.code = ACTION_MODS_TAP_KEY((keycode >> 0x8) & 0xF, keycode & 0xFF); + break; + case 0x8000 ... 0x8FFF: + action.code = ACTION_LAYER_TAP_KEY((keycode >> 0x8) & 0xF, keycode & 0xFF); + break; + #ifdef UNICODE_ENABLE + case 0x8000000 ... 0x8FFFFFF: + uint16_t unicode = keycode & ~(0x8000); + action.code = ACTION_FUNCTION_OPT(unicode & 0xFF, (unicode & 0xFF00) >> 8); + break; + #endif default: action.code = ACTION_NO; break; diff --git a/quantum/keymap_common.h b/quantum/keymap_common.h index 7452a1ff3..ce87e4770 100644 --- a/quantum/keymap_common.h +++ b/quantum/keymap_common.h @@ -30,7 +30,6 @@ along with this program. If not, see . // #include "print.h" #include "debug.h" -#ifdef BOOTMAGIC_ENABLE /* NOTE: Not portable. Bit field order depends on implementation */ typedef union { uint16_t raw; @@ -45,8 +44,6 @@ typedef union { bool nkro:1; }; } keymap_config_t; -keymap_config_t keymap_config; -#endif /* translates key to keycode */ @@ -168,6 +165,30 @@ extern const uint16_t fn_actions[]; #define RESET 0x5000 #define DEBUG 0x5001 +// MAGIC keycodes +#define MAGIC_SWAP_CONTROL_CAPSLOCK 0x5002 +#define MAGIC_UNSWAP_CONTROL_CAPSLOCK 0x5003 +#define MAGIC_CAPSLOCK_TO_CONTROL 0x5004 +#define MAGIC_UNCAPSLOCK_TO_CONTROL 0x5005 +#define MAGIC_SWAP_LALT_LGUI 0x5006 +#define MAGIC_UNSWAP_LALT_LGUI 0x5007 +#define MAGIC_SWAP_RALT_RGUI 0x5008 +#define MAGIC_UNSWAP_RALT_RGUI 0x5009 +#define MAGIC_NO_GUI 0x500a +#define MAGIC_UNNO_GUI 0x500b +#define MAGIC_SWAP_GRAVE_ESC 0x500c +#define MAGIC_UNSWAP_GRAVE_ESC 0x500d +#define MAGIC_SWAP_BACKSLASH_BACKSPACE 0x500e +#define MAGIC_UNSWAP_BACKSLASH_BACKSPACE 0x500f +#define MAGIC_HOST_NKRO 0x5010 +#define MAGIC_UNHOST_NKRO 0x5011 +#define MAGIC_SWAP_ALT_GUI 0x5012 +#define MAGIC_UNSWAP_ALT_GUI 0x5013 + +#define AG_SWAP MAGIC_SWAP_ALT_GUI +#define AG_NORM MAGIC_UNSWAP_ALT_GUI + + // GOTO layer - 16 layers max // when: // ON_PRESS = 1 @@ -213,4 +234,5 @@ void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3); #define IS_LAYER_ON(layer) ((layer_state) & (1UL<<(layer))) #define IS_LAYER_OFF(layer) ((!layer_state) & (1UL<<(layer))) + #endif -- cgit v1.2.3-24-g4f1b From c83aa16f1d614c1c10f7597a67ffb9f2ae871951 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Sat, 16 Apr 2016 20:26:02 -0400 Subject: fixes audio prescaler to emit correct freq --- quantum/audio.c | 12 +++++++----- quantum/keymap_common.c | 6 +++--- 2 files changed, 10 insertions(+), 8 deletions(-) (limited to 'quantum') diff --git a/quantum/audio.c b/quantum/audio.c index 5edcccdbe..470dc8e0c 100644 --- a/quantum/audio.c +++ b/quantum/audio.c @@ -12,6 +12,8 @@ #define PI 3.14159265 +#define CPU_PRESCALER 8 + // #define PWM_AUDIO #ifdef PWM_AUDIO @@ -244,12 +246,12 @@ ISR(TIMER3_COMPA_vect) { // ICR3 = (int)(((double)F_CPU) / frequency); // Set max to the period // OCR3A = (int)(((double)F_CPU) / frequency) >> 1; // Set compare to half the period voice_place %= voices; - if (place > (frequencies[voice_place] / 500)) { + if (place > (frequencies[voice_place] / 50)) { voice_place = (voice_place + 1) % voices; place = 0.0; } - ICR3 = (int)(((double)F_CPU) / frequencies[voice_place]); // Set max to the period - OCR3A = (int)(((double)F_CPU) / frequencies[voice_place]) >> 1 * duty_place; // Set compare to half the period + ICR3 = (int)(((double)F_CPU) / (frequencies[voice_place] * CPU_PRESCALER)); // Set max to the period + OCR3A = (int)(((double)F_CPU) / (frequencies[voice_place] * CPU_PRESCALER)) >> 1 * duty_place; // Set compare to half the period place++; // if (duty_counter > (frequencies[voice_place] / 500)) { // duty_place = (duty_place % 3) + 1; @@ -281,8 +283,8 @@ ISR(TIMER3_COMPA_vect) { place -= SINE_LENGTH; #else if (note_frequency > 0) { - ICR3 = (int)(((double)F_CPU) / note_frequency); // Set max to the period - OCR3A = (int)(((double)F_CPU) / note_frequency) >> 1; // Set compare to half the period + ICR3 = (int)(((double)F_CPU) / (note_frequency * CPU_PRESCALER)); // Set max to the period + OCR3A = (int)(((double)F_CPU) / (note_frequency * CPU_PRESCALER)) >> 1; // Set compare to half the period } else { ICR3 = 0; OCR3A = 0; diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c index b91916685..899437f44 100644 --- a/quantum/keymap_common.c +++ b/quantum/keymap_common.c @@ -35,9 +35,9 @@ extern keymap_config_t keymap_config; #include "audio.h" float goodbye[][2] = { - {440.0*pow(2.0,(67)/12.0), 8}, - {440.0*pow(2.0,(60)/12.0), 8}, - {440.0*pow(2.0,(55)/12.0), 12}, + {440.0*pow(2.0,(31)/12.0), 8}, + {440.0*pow(2.0,(24)/12.0), 8}, + {440.0*pow(2.0,(19)/12.0), 12}, }; #endif -- cgit v1.2.3-24-g4f1b From 41cc35425ab32c9a9492006da8b667d01d32dfa6 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Sat, 16 Apr 2016 21:31:40 -0400 Subject: rests between notes as an argument --- quantum/audio.c | 29 +++++++++++++++++++++-------- quantum/audio.h | 3 ++- quantum/keymap_common.c | 2 +- 3 files changed, 24 insertions(+), 10 deletions(-) (limited to 'quantum') diff --git a/quantum/audio.c b/quantum/audio.c index 470dc8e0c..40d09d62f 100644 --- a/quantum/audio.c +++ b/quantum/audio.c @@ -61,7 +61,11 @@ uint16_t note_position = 0; float (* notes_pointer)[][2]; uint8_t notes_length; bool notes_repeat; +float notes_rest; +bool note_resting = false; + uint8_t current_note = 0; +uint8_t rest_counter = 0; audio_config_t audio_config; @@ -314,13 +318,21 @@ ISR(TIMER3_COMPA_vect) { return; } } - #ifdef PWM_AUDIO - note_frequency = (*notes_pointer)[current_note][0] / SAMPLE_RATE; - note_length = (*notes_pointer)[current_note][1]; - #else - note_frequency = (*notes_pointer)[current_note][0]; - note_length = (*notes_pointer)[current_note][1] / 4; - #endif + if (!note_resting && ((int)notes_rest != 0)) { + note_resting = true; + note_frequency = 0; + note_length = notes_rest; + current_note--; + } else { + note_resting = false; + #ifdef PWM_AUDIO + note_frequency = (*notes_pointer)[current_note][0] / SAMPLE_RATE; + note_length = (*notes_pointer)[current_note][1]; + #else + note_frequency = (*notes_pointer)[current_note][0]; + note_length = (*notes_pointer)[current_note][1] / 4; + #endif + } note_position = 0; } @@ -332,7 +344,7 @@ ISR(TIMER3_COMPA_vect) { } } -void play_notes(float (*np)[][2], uint8_t n_length, bool n_repeat) { +void play_notes(float (*np)[][2], uint8_t n_length, bool n_repeat, float n_rest) { if (audio_config.enable) { @@ -343,6 +355,7 @@ if (audio_config.enable) { notes_pointer = np; notes_length = n_length; notes_repeat = n_repeat; + notes_rest = n_rest; place = 0; current_note = 0; diff --git a/quantum/audio.h b/quantum/audio.h index 58270015d..65a6f9434 100644 --- a/quantum/audio.h +++ b/quantum/audio.h @@ -2,6 +2,7 @@ #include #include #include +#include "musical_notes.h" typedef union { uint8_t raw; @@ -20,4 +21,4 @@ void play_note(double freq, int vol); void stop_note(double freq); void stop_all_notes(); void init_notes(); -void play_notes(float (*np)[][2], uint8_t n_length, bool n_repeat); +void play_notes(float (*np)[][2], uint8_t n_length, bool n_repeat, float n_rest); diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c index 899437f44..457f70a44 100644 --- a/quantum/keymap_common.c +++ b/quantum/keymap_common.c @@ -189,7 +189,7 @@ static action_t keycode_to_action(uint16_t keycode) case RESET: ; // RESET is 0x5000, which is why this is here clear_keyboard(); #ifdef AUDIO_ENABLE - play_notes(&goodbye, 3, false); + play_notes(&goodbye, 3, false, 0); #endif _delay_ms(250); #ifdef ATREUS_ASTAR -- cgit v1.2.3-24-g4f1b From 8bbd064cf52a76508589579f19595607a1f3af21 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Sat, 16 Apr 2016 23:07:50 -0400 Subject: changes to play_notes, goodbye --- quantum/audio.c | 2 +- quantum/keymap_common.c | 16 +++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) (limited to 'quantum') diff --git a/quantum/audio.c b/quantum/audio.c index 40d09d62f..773edfd8e 100644 --- a/quantum/audio.c +++ b/quantum/audio.c @@ -318,7 +318,7 @@ ISR(TIMER3_COMPA_vect) { return; } } - if (!note_resting && ((int)notes_rest != 0)) { + if (!note_resting && (notes_rest > 0)) { note_resting = true; note_frequency = 0; note_length = notes_rest; diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c index 457f70a44..8f35521a2 100644 --- a/quantum/keymap_common.c +++ b/quantum/keymap_common.c @@ -33,12 +33,14 @@ extern keymap_config_t keymap_config; #include #ifdef AUDIO_ENABLE #include "audio.h" - - float goodbye[][2] = { - {440.0*pow(2.0,(31)/12.0), 8}, - {440.0*pow(2.0,(24)/12.0), 8}, - {440.0*pow(2.0,(19)/12.0), 12}, - }; + #ifndef GOODBYE_TUNE + #define GOODBYE_TUNE { \ + {440.0*pow(2.0,(31)/12.0), 8}, \ + {440.0*pow(2.0,(24)/12.0), 8}, \ + {440.0*pow(2.0,(19)/12.0), 12}, \ + } + #endif + float goodbye_tune[][2] = GOODBYE_TUNE; #endif static action_t keycode_to_action(uint16_t keycode); @@ -189,7 +191,7 @@ static action_t keycode_to_action(uint16_t keycode) case RESET: ; // RESET is 0x5000, which is why this is here clear_keyboard(); #ifdef AUDIO_ENABLE - play_notes(&goodbye, 3, false, 0); + play_notes(&goodbye_tune, false, 0); #endif _delay_ms(250); #ifdef ATREUS_ASTAR -- cgit v1.2.3-24-g4f1b From 45f10b4c4b308226fa1568277654a13853a03ab4 Mon Sep 17 00:00:00 2001 From: IBNobody Date: Sat, 16 Apr 2016 22:10:18 -0500 Subject: Fixed how note arrays are used. --- quantum/audio.c | 14 +++++++------- quantum/audio.h | 17 +++++++++++++++-- quantum/keymap_common.c | 4 ++-- quantum/musical_notes.h | 7 ++++++- 4 files changed, 30 insertions(+), 12 deletions(-) (limited to 'quantum') diff --git a/quantum/audio.c b/quantum/audio.c index 40d09d62f..90f3c5a13 100644 --- a/quantum/audio.c +++ b/quantum/audio.c @@ -181,7 +181,7 @@ void init_notes() { DDRC |= _BV(PORTC6); TIMSK3 &= ~_BV(OCIE3A); // Turn off 3A interputs - + TCCR3A = 0x0; // Options not needed TCCR3B = _BV(CS31) | _BV(CS30) | _BV(WGM32); // 64th prescaling and CTC OCR3A = SAMPLE_DIVIDER - 1; // Correct count/compare, related to sample playback @@ -202,14 +202,14 @@ ISR(TIMER3_COMPA_vect) { if (voices == 1) { // SINE OCR4A = pgm_read_byte(&sinewave[(uint16_t)place]) >> 2; - + // SQUARE // if (((int)place) >= 1024){ // OCR4A = 0xFF >> 2; // } else { // OCR4A = 0x00; // } - + // SAWTOOTH // OCR4A = (int)place / 4; @@ -298,9 +298,9 @@ ISR(TIMER3_COMPA_vect) { note_position++; bool end_of_note = false; - if (ICR3 > 0) + if (ICR3 > 0) end_of_note = (note_position >= (note_length / ICR3 * 0xFFFF)); - else + else end_of_note = (note_position >= (note_length * 0x7FF)); if (end_of_note) { current_note++; @@ -318,7 +318,7 @@ ISR(TIMER3_COMPA_vect) { return; } } - if (!note_resting && ((int)notes_rest != 0)) { + if (!note_resting && (notes_rest > 0)) { note_resting = true; note_frequency = 0; note_length = notes_rest; @@ -412,7 +412,7 @@ if (audio_config.enable && voices < 8) { if (frequency != 0) { double starting_f = frequency; if (frequency < freq) { - for (double f = starting_f; f <= freq; f += ((freq - starting_f) / 2000.0)) { + for (double f = starting_f; f <= freq; f += ((freq - starting_f) / 2000.0)) { frequency = f; } } else if (frequency > freq) { diff --git a/quantum/audio.h b/quantum/audio.h index 65a6f9434..762c98064 100644 --- a/quantum/audio.h +++ b/quantum/audio.h @@ -4,6 +4,9 @@ #include #include "musical_notes.h" +#ifndef AUDIO_H +#define AUDIO_H + typedef union { uint8_t raw; struct { @@ -19,6 +22,16 @@ void audio_off(void); void play_sample(uint8_t * s, uint16_t l, bool r); void play_note(double freq, int vol); void stop_note(double freq); -void stop_all_notes(); -void init_notes(); +void stop_all_notes(void); +void init_notes(void); void play_notes(float (*np)[][2], uint8_t n_length, bool n_repeat, float n_rest); + + +// These macros are used to allow play_notes to play an array of indeterminate +// length. This works around the limitation of C's sizeof operation on pointers. +// The global float array for the song must be used here. +#define NOTE_ARRAY_SIZE(x) ((int)(sizeof(x) / (sizeof(x[0])))) +#define PLAY_NOTE_ARRAY(note_array, note_repeat, note_rest_style) play_notes(¬e_array, NOTE_ARRAY_SIZE((note_array)), (note_repeat), (note_rest_style)); + + +#endif \ No newline at end of file diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c index 457f70a44..61a51aedb 100644 --- a/quantum/keymap_common.c +++ b/quantum/keymap_common.c @@ -189,7 +189,7 @@ static action_t keycode_to_action(uint16_t keycode) case RESET: ; // RESET is 0x5000, which is why this is here clear_keyboard(); #ifdef AUDIO_ENABLE - play_notes(&goodbye, 3, false, 0); + PLAY_NOTE_ARRAY(goodbye, false, 0); #endif _delay_ms(250); #ifdef ATREUS_ASTAR @@ -202,7 +202,7 @@ static action_t keycode_to_action(uint16_t keycode) debug_enable = true; break; case 0x5002 ... 0x50FF: - // MAGIC actions (BOOTMAGIC without the boot) + // MAGIC actions (BOOTMAGIC without the boot) if (!eeconfig_is_enabled()) { eeconfig_init(); } diff --git a/quantum/musical_notes.h b/quantum/musical_notes.h index 79f04fd98..837f6a069 100644 --- a/quantum/musical_notes.h +++ b/quantum/musical_notes.h @@ -9,7 +9,7 @@ #define WHOLE_NOTE(note) {(NOTE##note), 64} #define HALF_NOTE(note) {(NOTE##note), 32} #define QUARTER_NOTE(note) {(NOTE##note), 16} -#define EIGTH_NOTE(note) {(NOTE##note), 8} +#define EIGHTH_NOTE(note) {(NOTE##note), 8} #define SIXTEENTH_NOTE(note) {(NOTE##note), 4} // Note Types Short @@ -19,6 +19,11 @@ #define E_NOTE(n) EIGTH_NOTE(n) #define S_NOTE(n) SIXTEENTH_NOTE(n) +// Note Styles +// Staccato makes sure there is a rest between each note. Think: TA TA TA +// Legato makes notes flow together. Think: TAAA +#define STACCATO 0.01 +#define LEGATO 0 // Notes - # = Octave #define NOTE_REST 0.00 -- cgit v1.2.3-24-g4f1b From a67d425f4d5278595e7ab785a0f246b83fb1a09f Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Sun, 17 Apr 2016 01:00:39 -0400 Subject: planck default layout updates --- quantum/audio.c | 5 +++-- quantum/keymap_common.c | 8 ++++---- 2 files changed, 7 insertions(+), 6 deletions(-) (limited to 'quantum') diff --git a/quantum/audio.c b/quantum/audio.c index 90f3c5a13..6bd6532a3 100644 --- a/quantum/audio.c +++ b/quantum/audio.c @@ -350,7 +350,6 @@ if (audio_config.enable) { if (note) stop_all_notes(); - notes = true; notes_pointer = np; notes_length = n_length; @@ -375,6 +374,8 @@ if (audio_config.enable) { TIMSK3 |= _BV(OCIE3A); TCCR3A |= _BV(COM3A1); #endif + + notes = true; } } @@ -404,7 +405,6 @@ if (audio_config.enable && voices < 8) { if (notes) stop_all_notes(); - note = true; #ifdef PWM_AUDIO freq = freq / SAMPLE_RATE; #endif @@ -436,6 +436,7 @@ if (audio_config.enable && voices < 8) { TCCR3A |= _BV(COM3A1); #endif + note = true; } } \ No newline at end of file diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c index 02d3c74be..d38e6fdb2 100644 --- a/quantum/keymap_common.c +++ b/quantum/keymap_common.c @@ -33,14 +33,14 @@ extern keymap_config_t keymap_config; #include #ifdef AUDIO_ENABLE #include "audio.h" - #ifndef GOODBYE_TUNE - #define GOODBYE_TUNE { \ + #ifndef TONE_GOODBYE + #define TONE_GOODBYE { \ {440.0*pow(2.0,(31)/12.0), 8}, \ {440.0*pow(2.0,(24)/12.0), 8}, \ {440.0*pow(2.0,(19)/12.0), 12}, \ } #endif - float goodbye_tune[][2] = GOODBYE_TUNE; + float tone_goodbye[][2] = TONE_GOODBYE; #endif static action_t keycode_to_action(uint16_t keycode); @@ -191,7 +191,7 @@ static action_t keycode_to_action(uint16_t keycode) case RESET: ; // RESET is 0x5000, which is why this is here clear_keyboard(); #ifdef AUDIO_ENABLE - PLAY_NOTE_ARRAY(goodbye_tune, false, 0); + PLAY_NOTE_ARRAY(tone_goodbye, false, 0); #endif _delay_ms(250); #ifdef ATREUS_ASTAR -- cgit v1.2.3-24-g4f1b From 943b5b770955be937a89016680052be56d874c4a Mon Sep 17 00:00:00 2001 From: IBNobody Date: Sun, 17 Apr 2016 00:24:58 -0500 Subject: Adding folding to #if, etc --- quantum/audio.c | 3 ++- quantum/musical_notes.h | 38 +++++++++++++++++++++++++++----------- quantum/song_list.h | 12 ++++++++++++ 3 files changed, 41 insertions(+), 12 deletions(-) create mode 100644 quantum/song_list.h (limited to 'quantum') diff --git a/quantum/audio.c b/quantum/audio.c index 90f3c5a13..119bd9229 100644 --- a/quantum/audio.c +++ b/quantum/audio.c @@ -288,7 +288,8 @@ ISR(TIMER3_COMPA_vect) { #else if (note_frequency > 0) { ICR3 = (int)(((double)F_CPU) / (note_frequency * CPU_PRESCALER)); // Set max to the period - OCR3A = (int)(((double)F_CPU) / (note_frequency * CPU_PRESCALER)) >> 1; // Set compare to half the period + //OCR3A = (int)(((double)F_CPU) / (note_frequency * CPU_PRESCALER)) >> 1; // Set compare to half the period + OCR3A = (int)(((double)F_CPU) / (note_frequency * CPU_PRESCALER)) >> 2; // Set compare to half the period } else { ICR3 = 0; OCR3A = 0; diff --git a/quantum/musical_notes.h b/quantum/musical_notes.h index 837f6a069..d2256a773 100644 --- a/quantum/musical_notes.h +++ b/quantum/musical_notes.h @@ -4,20 +4,36 @@ // Tempo Placeholder #define TEMPO 120 +#define SONG(notes...) { notes } + // Note Types -#define WHOLE_NOTE(note) {(NOTE##note), 64} -#define HALF_NOTE(note) {(NOTE##note), 32} -#define QUARTER_NOTE(note) {(NOTE##note), 16} -#define EIGHTH_NOTE(note) {(NOTE##note), 8} -#define SIXTEENTH_NOTE(note) {(NOTE##note), 4} +#define MUSICAL_NOTE(note, duration) {(NOTE##note), duration} +#define WHOLE_NOTE(note) MUSICAL_NOTE(note, 64) +#define HALF_NOTE(note) MUSICAL_NOTE(note, 32) +#define QUARTER_NOTE(note) MUSICAL_NOTE(note, 16) +#define EIGHTH_NOTE(note) MUSICAL_NOTE(note, 8) +#define SIXTEENTH_NOTE(note) MUSICAL_NOTE(note, 4) + +#define WHOLE_DOT_NOTE(note) MUSICAL_NOTE(note, 64+32) +#define HALF_DOT_NOTE(note) MUSICAL_NOTE(note, 32+16) +#define QUARTER_DOT_NOTE(note) MUSICAL_NOTE(note, 16+8) +#define EIGHTH_DOT_NOTE(note) MUSICAL_NOTE(note, 8+4) +#define SIXTEENTH_DOT_NOTE(note) MUSICAL_NOTE(note, 4+2) + -// Note Types Short -#define W_NOTE(n) WHOLE_NOTE(n) -#define H_NOTE(n) HALF_NOTE(n) -#define Q_NOTE(n) QUARTER_NOTE(n) -#define E_NOTE(n) EIGTH_NOTE(n) -#define S_NOTE(n) SIXTEENTH_NOTE(n) +// Note Type Shortcuts +#define M__NOTE(note, duration) MUSICAL_NOTE(note, duration) +#define W__NOTE(n) WHOLE_NOTE(n) +#define H__NOTE(n) HALF_NOTE(n) +#define Q__NOTE(n) QUARTER_NOTE(n) +#define E__NOTE(n) EIGHTH_NOTE(n) +#define S__NOTE(n) SIXTEENTH_NOTE(n) +#define WD_NOTE(n) WHOLE_DOT_NOTE(n) +#define HD_NOTE(n) HALF_DOT_NOTE(n) +#define QD_NOTE(n) QUARTER_DOT_NOTE(n) +#define ED_NOTE(n) EIGTH_DOT_NOTE(n) +#define SD_NOTE(n) SIXTEENTH_DOT_NOTE(n) // Note Styles // Staccato makes sure there is a rest between each note. Think: TA TA TA diff --git a/quantum/song_list.h b/quantum/song_list.h new file mode 100644 index 000000000..ef25eac35 --- /dev/null +++ b/quantum/song_list.h @@ -0,0 +1,12 @@ +#include "musical_notes.h" + +#ifndef SONG_LIST_H +#define SONG_LIST_H + +#define ODE_TO_JOY \ + Q__NOTE(_E4), Q__NOTE(_E4), Q__NOTE(_F4), Q__NOTE(_G4), \ + Q__NOTE(_G4), Q__NOTE(_F4), Q__NOTE(_E4), Q__NOTE(_D4), \ + Q__NOTE(_C4), Q__NOTE(_C4), Q__NOTE(_D4), Q__NOTE(_E4), \ + QD_NOTE(_E4), E__NOTE(_D4), H__NOTE(_D4), + +#endif \ No newline at end of file -- cgit v1.2.3-24-g4f1b From 29e495be2a57d1eb41699909b204c12ac6bc4c0e Mon Sep 17 00:00:00 2001 From: IBNobody Date: Sun, 17 Apr 2016 02:52:38 -0500 Subject: Added trimble and tempo adjustments! --- quantum/audio.c | 56 +++++++++++++++++++++++++++++++++++++------------ quantum/audio.h | 6 +++++- quantum/musical_notes.h | 13 ++++++++++-- quantum/song_list.h | 6 ++++++ 4 files changed, 65 insertions(+), 16 deletions(-) (limited to 'quantum') diff --git a/quantum/audio.c b/quantum/audio.c index 119bd9229..9b9589f13 100644 --- a/quantum/audio.c +++ b/quantum/audio.c @@ -4,7 +4,7 @@ #include #include #include - +#include "print.h" #include "audio.h" #include "keymap_common.h" @@ -57,9 +57,11 @@ bool notes = false; bool note = false; float note_frequency = 0; float note_length = 0; +float note_tempo = TEMPO_DEFAULT; +float note_timbre = TIMBRE_DEFAULT; uint16_t note_position = 0; float (* notes_pointer)[][2]; -uint8_t notes_length; +uint8_t notes_count; bool notes_repeat; float notes_rest; bool note_resting = false; @@ -255,7 +257,8 @@ ISR(TIMER3_COMPA_vect) { place = 0.0; } ICR3 = (int)(((double)F_CPU) / (frequencies[voice_place] * CPU_PRESCALER)); // Set max to the period - OCR3A = (int)(((double)F_CPU) / (frequencies[voice_place] * CPU_PRESCALER)) >> 1 * duty_place; // Set compare to half the period + OCR3A = (int)((((double)F_CPU) / (note_frequency * CPU_PRESCALER)) * note_timbre); // Set compare to half the period + //OCR3A = (int)(((double)F_CPU) / (frequencies[voice_place] * CPU_PRESCALER)) >> 1 * duty_place; // Set compare to half the period place++; // if (duty_counter > (frequencies[voice_place] / 500)) { // duty_place = (duty_place % 3) + 1; @@ -288,8 +291,7 @@ ISR(TIMER3_COMPA_vect) { #else if (note_frequency > 0) { ICR3 = (int)(((double)F_CPU) / (note_frequency * CPU_PRESCALER)); // Set max to the period - //OCR3A = (int)(((double)F_CPU) / (note_frequency * CPU_PRESCALER)) >> 1; // Set compare to half the period - OCR3A = (int)(((double)F_CPU) / (note_frequency * CPU_PRESCALER)) >> 2; // Set compare to half the period + OCR3A = (int)((((double)F_CPU) / (note_frequency * CPU_PRESCALER)) * note_timbre); // Set compare to half the period } else { ICR3 = 0; OCR3A = 0; @@ -305,7 +307,7 @@ ISR(TIMER3_COMPA_vect) { end_of_note = (note_position >= (note_length * 0x7FF)); if (end_of_note) { current_note++; - if (current_note >= notes_length) { + if (current_note >= notes_count) { if (notes_repeat) { current_note = 0; } else { @@ -328,10 +330,10 @@ ISR(TIMER3_COMPA_vect) { note_resting = false; #ifdef PWM_AUDIO note_frequency = (*notes_pointer)[current_note][0] / SAMPLE_RATE; - note_length = (*notes_pointer)[current_note][1]; + note_length = (*notes_pointer)[current_note][1] * (note_tempo / 100); #else note_frequency = (*notes_pointer)[current_note][0]; - note_length = (*notes_pointer)[current_note][1] / 4; + note_length = ((*notes_pointer)[current_note][1] / 4) * (note_tempo / 100); #endif } note_position = 0; @@ -345,7 +347,7 @@ ISR(TIMER3_COMPA_vect) { } } -void play_notes(float (*np)[][2], uint8_t n_length, bool n_repeat, float n_rest) { +void play_notes(float (*np)[][2], uint8_t n_count, bool n_repeat, float n_rest) { if (audio_config.enable) { @@ -354,7 +356,7 @@ if (audio_config.enable) { notes = true; notes_pointer = np; - notes_length = n_length; + notes_count = n_count; notes_repeat = n_repeat; notes_rest = n_rest; @@ -362,10 +364,10 @@ if (audio_config.enable) { current_note = 0; #ifdef PWM_AUDIO note_frequency = (*notes_pointer)[current_note][0] / SAMPLE_RATE; - note_length = (*notes_pointer)[current_note][1]; + note_length = (*notes_pointer)[current_note][1] * (note_tempo / 100); #else note_frequency = (*notes_pointer)[current_note][0]; - note_length = (*notes_pointer)[current_note][1] / 4; + note_length = ((*notes_pointer)[current_note][1] / 4) * (note_tempo / 100); #endif note_position = 0; @@ -439,4 +441,32 @@ if (audio_config.enable && voices < 8) { } -} \ No newline at end of file +} + +void set_timbre(float timbre) +{ + note_timbre = timbre; +} + +void set_tempo(float tempo) +{ + note_tempo = tempo; +} + +void decrease_tempo(uint8_t tempo_change) +{ + note_tempo += (float) tempo_change; +} + +void increase_tempo(uint8_t tempo_change) +{ + if (note_tempo - (float) tempo_change < 10) + { + note_tempo = 10; + } + else + { + note_tempo -= (float) tempo_change; + } +} + diff --git a/quantum/audio.h b/quantum/audio.h index 762c98064..8012aa6bf 100644 --- a/quantum/audio.h +++ b/quantum/audio.h @@ -24,8 +24,12 @@ void play_note(double freq, int vol); void stop_note(double freq); void stop_all_notes(void); void init_notes(void); -void play_notes(float (*np)[][2], uint8_t n_length, bool n_repeat, float n_rest); +void play_notes(float (*np)[][2], uint8_t n_count, bool n_repeat, float n_rest); +void set_timbre(float timbre); +void set_tempo(float tempo); +void increase_tempo(uint8_t tempo_change); +void decrease_tempo(uint8_t tempo_change); // These macros are used to allow play_notes to play an array of indeterminate // length. This works around the limitation of C's sizeof operation on pointers. diff --git a/quantum/musical_notes.h b/quantum/musical_notes.h index d2256a773..2170f3f18 100644 --- a/quantum/musical_notes.h +++ b/quantum/musical_notes.h @@ -2,7 +2,8 @@ #define MUSICAL_NOTES_H // Tempo Placeholder -#define TEMPO 120 +#define TEMPO_DEFAULT 100 + #define SONG(notes...) { notes } @@ -21,7 +22,6 @@ #define EIGHTH_DOT_NOTE(note) MUSICAL_NOTE(note, 8+4) #define SIXTEENTH_DOT_NOTE(note) MUSICAL_NOTE(note, 4+2) - // Note Type Shortcuts #define M__NOTE(note, duration) MUSICAL_NOTE(note, duration) #define W__NOTE(n) WHOLE_NOTE(n) @@ -41,6 +41,15 @@ #define STACCATO 0.01 #define LEGATO 0 +// Note Timbre +// Changes how the notes sound +#define TIMBRE_12 0.125 +#define TIMBRE_25 0.250 +#define TIMBRE_50 0.500 +#define TIMBRE_75 0.750 +#define TIMBRE_DEFAULT TIMBRE_50 + + // Notes - # = Octave #define NOTE_REST 0.00 #define NOTE_C0 16.35 diff --git a/quantum/song_list.h b/quantum/song_list.h index ef25eac35..ef36a1cdd 100644 --- a/quantum/song_list.h +++ b/quantum/song_list.h @@ -9,4 +9,10 @@ Q__NOTE(_C4), Q__NOTE(_C4), Q__NOTE(_D4), Q__NOTE(_E4), \ QD_NOTE(_E4), E__NOTE(_D4), H__NOTE(_D4), +#define ROCK_A_BYE_BABY \ + QD_NOTE(_B4), E__NOTE(_D4), Q__NOTE(_B5), \ + H__NOTE(_A5), Q__NOTE(_G5), \ + QD_NOTE(_B4), E__NOTE(_D5), Q__NOTE(_G5), \ + H__NOTE(_FS5), + #endif \ No newline at end of file -- cgit v1.2.3-24-g4f1b From c940e87235c9fe26f5c7451464af54a493270a68 Mon Sep 17 00:00:00 2001 From: IBNobody Date: Sun, 17 Apr 2016 10:41:07 -0500 Subject: fixed single note play copy/paste bug --- quantum/audio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'quantum') diff --git a/quantum/audio.c b/quantum/audio.c index 9b9589f13..58b9ab76b 100644 --- a/quantum/audio.c +++ b/quantum/audio.c @@ -257,7 +257,7 @@ ISR(TIMER3_COMPA_vect) { place = 0.0; } ICR3 = (int)(((double)F_CPU) / (frequencies[voice_place] * CPU_PRESCALER)); // Set max to the period - OCR3A = (int)((((double)F_CPU) / (note_frequency * CPU_PRESCALER)) * note_timbre); // Set compare to half the period + OCR3A = (int)((((double)F_CPU) /(frequencies[voice_place] * CPU_PRESCALER)) * note_timbre); // Set compare to half the period //OCR3A = (int)(((double)F_CPU) / (frequencies[voice_place] * CPU_PRESCALER)) >> 1 * duty_place; // Set compare to half the period place++; // if (duty_counter > (frequencies[voice_place] / 500)) { -- cgit v1.2.3-24-g4f1b From 90289aa53fe06a867c773d447c6d3a950575d69a Mon Sep 17 00:00:00 2001 From: a0-c Date: Sun, 17 Apr 2016 06:51:39 -1000 Subject: __attribute__ ((weak)) added to led_set __attribute__ ((weak)) added to led_set --- quantum/led.c | 1 + 1 file changed, 1 insertion(+) (limited to 'quantum') diff --git a/quantum/led.c b/quantum/led.c index 9cdb8a5c2..208e348f3 100644 --- a/quantum/led.c +++ b/quantum/led.c @@ -24,6 +24,7 @@ void led_set_kb(uint8_t usb_led) { } +__attribute__ ((weak)) void led_set(uint8_t usb_led) { -- cgit v1.2.3-24-g4f1b From d5b72e7bde5ede25f7d5699b50b7d9eb6f31ba92 Mon Sep 17 00:00:00 2001 From: IBNobody Date: Sun, 17 Apr 2016 12:54:32 -0500 Subject: Fixed many compiler warnings related to print being disabled --- quantum/keymap_common.c | 1 + 1 file changed, 1 insertion(+) (limited to 'quantum') diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c index 61a51aedb..ce1d007f3 100644 --- a/quantum/keymap_common.c +++ b/quantum/keymap_common.c @@ -26,6 +26,7 @@ along with this program. If not, see . #include "backlight.h" #include "keymap_midi.h" #include "bootloader.h" +#include "eeconfig.h" extern keymap_config_t keymap_config; -- cgit v1.2.3-24-g4f1b From 23231fa577f7c6c585124226a83f21a7668e62dd Mon Sep 17 00:00:00 2001 From: IBNobody Date: Sun, 17 Apr 2016 14:16:03 -0500 Subject: Converted goodbye to notes, fixed eighth dotted note macro --- quantum/audio.h | 1 + quantum/keymap_common.c | 14 ++++++-------- quantum/musical_notes.h | 2 +- quantum/song_list.h | 7 ++++++- 4 files changed, 14 insertions(+), 10 deletions(-) (limited to 'quantum') diff --git a/quantum/audio.h b/quantum/audio.h index 3aba8370a..05d314c94 100644 --- a/quantum/audio.h +++ b/quantum/audio.h @@ -3,6 +3,7 @@ #include #include #include "musical_notes.h" +#include "song_list.h" #ifndef AUDIO_H #define AUDIO_H diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c index c705b7a73..2001438b9 100644 --- a/quantum/keymap_common.c +++ b/quantum/keymap_common.c @@ -34,15 +34,13 @@ extern keymap_config_t keymap_config; #include #ifdef AUDIO_ENABLE #include "audio.h" + #ifndef TONE_GOODBYE - #define TONE_GOODBYE { \ - {440.0*pow(2.0,(31)/12.0), 8}, \ - {440.0*pow(2.0,(24)/12.0), 8}, \ - {440.0*pow(2.0,(19)/12.0), 12}, \ - } - #endif - float tone_goodbye[][2] = TONE_GOODBYE; -#endif + #define TONE_GOODBYE OLKB_GOODBYE + #endif /*! TONE_GOODBYE */ + + float tone_goodbye[][2] = SONG(TONE_GOODBYE); +#endif /* AUDIO_ENABLE */ static action_t keycode_to_action(uint16_t keycode); diff --git a/quantum/musical_notes.h b/quantum/musical_notes.h index 2170f3f18..ccdc34f27 100644 --- a/quantum/musical_notes.h +++ b/quantum/musical_notes.h @@ -32,7 +32,7 @@ #define WD_NOTE(n) WHOLE_DOT_NOTE(n) #define HD_NOTE(n) HALF_DOT_NOTE(n) #define QD_NOTE(n) QUARTER_DOT_NOTE(n) -#define ED_NOTE(n) EIGTH_DOT_NOTE(n) +#define ED_NOTE(n) EIGHTH_DOT_NOTE(n) #define SD_NOTE(n) SIXTEENTH_DOT_NOTE(n) // Note Styles diff --git a/quantum/song_list.h b/quantum/song_list.h index ef36a1cdd..b626c3fa6 100644 --- a/quantum/song_list.h +++ b/quantum/song_list.h @@ -15,4 +15,9 @@ QD_NOTE(_B4), E__NOTE(_D5), Q__NOTE(_G5), \ H__NOTE(_FS5), -#endif \ No newline at end of file +#define OLKB_GOODBYE \ + E__NOTE(_E7), \ + E__NOTE(_A6), \ + ED_NOTE(_E6), + +#endif -- cgit v1.2.3-24-g4f1b From 6d40f7c5060f608068b0c4fc90871687c70b4f05 Mon Sep 17 00:00:00 2001 From: Stephan Bösebeck Date: Sun, 17 Apr 2016 22:19:47 +0200 Subject: added new experimental layout - works with ErgodoxLayoutGenerator --- quantum/keymap_extras/keymap_german_osx.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'quantum') diff --git a/quantum/keymap_extras/keymap_german_osx.h b/quantum/keymap_extras/keymap_german_osx.h index d0b77fb80..ee725bad5 100644 --- a/quantum/keymap_extras/keymap_german_osx.h +++ b/quantum/keymap_extras/keymap_german_osx.h @@ -85,8 +85,8 @@ #define DE_OSX_UNDS LSFT(DE_OSX_MINS) // _ // Alt-ed characters -#define DE_OSX_SQ2 LALT(KC_2) // ² -#define DE_OSX_SQ3 LALT(KC_3) // ³ +//#define DE_OSX_SQ2 LALT(KC_2) // ² +//#define DE_OSX_SQ3 LALT(KC_3) // ³ #define DE_OSX_LCBR LALT(KC_8) // { #define DE_OSX_LBRC LALT(KC_5) // [ #define DE_OSX_RBRC LALT(KC_6) // ] -- cgit v1.2.3-24-g4f1b From ce463ef424c5bd26b84ead7de5f31eab366f98eb Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Sun, 17 Apr 2016 18:14:42 -0400 Subject: audio fixes --- quantum/audio.c | 6 +++--- quantum/audio.h | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'quantum') diff --git a/quantum/audio.c b/quantum/audio.c index 855e97361..e0413051a 100644 --- a/quantum/audio.c +++ b/quantum/audio.c @@ -257,7 +257,7 @@ ISR(TIMER3_COMPA_vect) { place = 0.0; } ICR3 = (int)(((double)F_CPU) / (frequencies[voice_place] * CPU_PRESCALER)); // Set max to the period - OCR3A = (int)((((double)F_CPU) / (note_frequency * CPU_PRESCALER)) * note_timbre); // Set compare to half the period + OCR3A = (int)((((double)F_CPU) / (frequencies[voice_place] * CPU_PRESCALER)) * note_timbre); // Set compare to half the period //OCR3A = (int)(((double)F_CPU) / (frequencies[voice_place] * CPU_PRESCALER)) >> 1 * duty_place; // Set compare to half the period place++; // if (duty_counter > (frequencies[voice_place] / 500)) { @@ -353,6 +353,7 @@ if (audio_config.enable) { if (note) stop_all_notes(); + notes = true; notes_pointer = np; notes_count = n_count; @@ -378,7 +379,6 @@ if (audio_config.enable) { TCCR3A |= _BV(COM3A1); #endif - notes = true; } } @@ -408,6 +408,7 @@ if (audio_config.enable && voices < 8) { if (notes) stop_all_notes(); + note = true; #ifdef PWM_AUDIO freq = freq / SAMPLE_RATE; #endif @@ -439,7 +440,6 @@ if (audio_config.enable && voices < 8) { TCCR3A |= _BV(COM3A1); #endif - note = true; } } diff --git a/quantum/audio.h b/quantum/audio.h index 3aba8370a..05d314c94 100644 --- a/quantum/audio.h +++ b/quantum/audio.h @@ -3,6 +3,7 @@ #include #include #include "musical_notes.h" +#include "song_list.h" #ifndef AUDIO_H #define AUDIO_H -- cgit v1.2.3-24-g4f1b From 5c98ad59606ee95b82c27bf2525383a9ec88542b Mon Sep 17 00:00:00 2001 From: IBNobody Date: Sun, 17 Apr 2016 20:14:37 -0500 Subject: Added extra songs, LED indicator notes --- quantum/audio.c | 17 +++++++- quantum/audio.h | 2 + quantum/keymap_common.c | 14 ++----- quantum/musical_notes.h | 5 +++ quantum/song_list.h | 104 ++++++++++++++++++++++++++++++++++++++++++------ 5 files changed, 117 insertions(+), 25 deletions(-) (limited to 'quantum') diff --git a/quantum/audio.c b/quantum/audio.c index 3ccd5ab9b..602366973 100644 --- a/quantum/audio.c +++ b/quantum/audio.c @@ -351,7 +351,7 @@ void play_notes(float (*np)[][2], uint8_t n_count, bool n_repeat, float n_rest) if (audio_config.enable) { - if (note) + if (note || notes) stop_all_notes(); notes_pointer = np; @@ -406,7 +406,7 @@ void play_note(double freq, int vol) { if (audio_config.enable && voices < 8) { - if (notes) + if (note || notes) stop_all_notes(); #ifdef PWM_AUDIO freq = freq / SAMPLE_RATE; @@ -471,3 +471,16 @@ void increase_tempo(uint8_t tempo_change) } } +//------------------------------------------------------------------------------ +// Override these functions in your keymap file to play different tunes on +// startup and bootloader jump +__attribute__ ((weak)) +void play_startup_tone() +{ +} + +__attribute__ ((weak)) +void play_goodbye_tone() +{ +} +//------------------------------------------------------------------------------ diff --git a/quantum/audio.h b/quantum/audio.h index 05d314c94..44cafccd6 100644 --- a/quantum/audio.h +++ b/quantum/audio.h @@ -44,5 +44,7 @@ void decrease_tempo(uint8_t tempo_change); #define NOTE_ARRAY_SIZE(x) ((int)(sizeof(x) / (sizeof(x[0])))) #define PLAY_NOTE_ARRAY(note_array, note_repeat, note_rest_style) play_notes(¬e_array, NOTE_ARRAY_SIZE((note_array)), (note_repeat), (note_rest_style)); +void play_goodbye_tone(void); +void play_startup_tone(void); #endif \ No newline at end of file diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c index 2001438b9..4ee290ad0 100644 --- a/quantum/keymap_common.c +++ b/quantum/keymap_common.c @@ -34,12 +34,6 @@ extern keymap_config_t keymap_config; #include #ifdef AUDIO_ENABLE #include "audio.h" - - #ifndef TONE_GOODBYE - #define TONE_GOODBYE OLKB_GOODBYE - #endif /*! TONE_GOODBYE */ - - float tone_goodbye[][2] = SONG(TONE_GOODBYE); #endif /* AUDIO_ENABLE */ static action_t keycode_to_action(uint16_t keycode); @@ -47,7 +41,7 @@ static action_t keycode_to_action(uint16_t keycode); /* converts key to action */ action_t action_for_key(uint8_t layer, keypos_t key) { - // 16bit keycodes - important + // 16bit keycodes - important uint16_t keycode = keymap_key_to_keycode(layer, key); switch (keycode) { @@ -190,7 +184,7 @@ static action_t keycode_to_action(uint16_t keycode) case RESET: ; // RESET is 0x5000, which is why this is here clear_keyboard(); #ifdef AUDIO_ENABLE - PLAY_NOTE_ARRAY(tone_goodbye, false, 0); + play_goodbye_tone(); #endif _delay_ms(250); #ifdef ATREUS_ASTAR @@ -303,7 +297,7 @@ static action_t keycode_to_action(uint16_t keycode) /* translates key to keycode */ uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key) { - // Read entire word (16bits) + // Read entire word (16bits) return pgm_read_word(&keymaps[(layer)][(key.row)][(key.col)]); } @@ -315,7 +309,7 @@ action_t keymap_fn_to_action(uint16_t keycode) action_t keymap_func_to_action(uint16_t keycode) { - // For FUNC without 8bit limit + // For FUNC without 8bit limit return (action_t){ .code = pgm_read_word(&fn_actions[(int)keycode]) }; } diff --git a/quantum/musical_notes.h b/quantum/musical_notes.h index ccdc34f27..b08d16a6f 100644 --- a/quantum/musical_notes.h +++ b/quantum/musical_notes.h @@ -51,7 +51,10 @@ // Notes - # = Octave + #define NOTE_REST 0.00 + +/* These notes are currently bugged #define NOTE_C0 16.35 #define NOTE_CS0 17.32 #define NOTE_D0 18.35 @@ -75,6 +78,8 @@ #define NOTE_GS1 51.91 #define NOTE_A1 55.00 #define NOTE_AS1 58.27 +*/ + #define NOTE_B1 61.74 #define NOTE_C2 65.41 #define NOTE_CS2 69.30 diff --git a/quantum/song_list.h b/quantum/song_list.h index b626c3fa6..e992bd18a 100644 --- a/quantum/song_list.h +++ b/quantum/song_list.h @@ -4,20 +4,98 @@ #define SONG_LIST_H #define ODE_TO_JOY \ - Q__NOTE(_E4), Q__NOTE(_E4), Q__NOTE(_F4), Q__NOTE(_G4), \ - Q__NOTE(_G4), Q__NOTE(_F4), Q__NOTE(_E4), Q__NOTE(_D4), \ - Q__NOTE(_C4), Q__NOTE(_C4), Q__NOTE(_D4), Q__NOTE(_E4), \ - QD_NOTE(_E4), E__NOTE(_D4), H__NOTE(_D4), + Q__NOTE(_E4), Q__NOTE(_E4), Q__NOTE(_F4), Q__NOTE(_G4), \ + Q__NOTE(_G4), Q__NOTE(_F4), Q__NOTE(_E4), Q__NOTE(_D4), \ + Q__NOTE(_C4), Q__NOTE(_C4), Q__NOTE(_D4), Q__NOTE(_E4), \ + QD_NOTE(_E4), E__NOTE(_D4), H__NOTE(_D4), #define ROCK_A_BYE_BABY \ - QD_NOTE(_B4), E__NOTE(_D4), Q__NOTE(_B5), \ - H__NOTE(_A5), Q__NOTE(_G5), \ - QD_NOTE(_B4), E__NOTE(_D5), Q__NOTE(_G5), \ - H__NOTE(_FS5), - -#define OLKB_GOODBYE \ - E__NOTE(_E7), \ - E__NOTE(_A6), \ - ED_NOTE(_E6), + QD_NOTE(_B4), E__NOTE(_D4), Q__NOTE(_B5), \ + H__NOTE(_A5), Q__NOTE(_G5), \ + QD_NOTE(_B4), E__NOTE(_D5), Q__NOTE(_G5), \ + H__NOTE(_FS5), + +#define CLOSE_ENCOUNTERS_5_NOTE \ + Q__NOTE(_D5), \ + Q__NOTE(_E5), \ + Q__NOTE(_C5), \ + Q__NOTE(_C4), \ + Q__NOTE(_G4), + +#define DOE_A_DEER \ + QD_NOTE(_C4), E__NOTE(_D4), \ + QD_NOTE(_E4), E__NOTE(_C4), \ + Q__NOTE(_E4), Q__NOTE(_C4), \ + Q__NOTE(_E4), + +#define GOODBYE_SOUND \ + E__NOTE(_E7), \ + E__NOTE(_A6), \ + ED_NOTE(_E6), + +#define STARTUP_SOUND \ + ED_NOTE(_E7 ), \ + E__NOTE(_CS7), \ + E__NOTE(_E6 ), \ + E__NOTE(_A6 ), \ + M__NOTE(_CS7, 20), + +#define QWERTY_SOUND \ + E__NOTE(_GS6 ), \ + E__NOTE(_A6 ), \ + S__NOTE(_REST), \ + Q__NOTE(_E7 ), + +#define COLEMAK_SOUND \ + E__NOTE(_GS6 ), \ + E__NOTE(_A6 ), \ + S__NOTE(_REST), \ + ED_NOTE(_E7 ), \ + S__NOTE(_REST), \ + ED_NOTE(_GS7 ), + +#define DVORAK_SOUND \ + E__NOTE(_GS6 ), \ + E__NOTE(_A6 ), \ + S__NOTE(_REST), \ + E__NOTE(_E7 ), \ + S__NOTE(_REST), \ + E__NOTE(_FS7 ), \ + S__NOTE(_REST), \ + E__NOTE(_E7 ), + +#define MUSIC_SCALE_SOUND \ + E__NOTE(_A5 ), \ + E__NOTE(_B5 ), \ + E__NOTE(_CS6), \ + E__NOTE(_D6 ), \ + E__NOTE(_E6 ), \ + E__NOTE(_FS6), \ + E__NOTE(_GS6), \ + E__NOTE(_A6 ), + +#define CAPS_LOCK_ON_SOUND \ + E__NOTE(_A3), \ + E__NOTE(_B3), + +#define CAPS_LOCK_OFF_SOUND \ + E__NOTE(_B3), \ + E__NOTE(_A3), + +#define SCROLL_LOCK_ON_SOUND \ + E__NOTE(_D4), \ + E__NOTE(_E4), + +#define SCROLL_LOCK_OFF_SOUND \ + E__NOTE(_E4), \ + E__NOTE(_D4), + +#define NUM_LOCK_ON_SOUND \ + E__NOTE(_D5), \ + E__NOTE(_E5), + +#define NUM_LOCK_OFF_SOUND \ + E__NOTE(_E5), \ + E__NOTE(_D5), #endif -- cgit v1.2.3-24-g4f1b From 89a78f4a11a8f04777b3407c958dc989b4d7d884 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Sun, 17 Apr 2016 21:26:06 -0400 Subject: audio fixes --- quantum/audio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'quantum') diff --git a/quantum/audio.c b/quantum/audio.c index 5805da46c..69c58ca6c 100644 --- a/quantum/audio.c +++ b/quantum/audio.c @@ -351,7 +351,7 @@ void play_notes(float (*np)[][2], uint8_t n_count, bool n_repeat, float n_rest) if (audio_config.enable) { - if (note || notes) + if (note) stop_all_notes(); notes = true; @@ -406,7 +406,7 @@ void play_note(double freq, int vol) { if (audio_config.enable && voices < 8) { - if (note || notes) + if (notes) stop_all_notes(); note = true; #ifdef PWM_AUDIO -- cgit v1.2.3-24-g4f1b From ef73ab662812232f5e73c8098a059439dcb201fa Mon Sep 17 00:00:00 2001 From: IBNobody Date: Sun, 17 Apr 2016 22:08:05 -0500 Subject: Notes Bugfix --- quantum/audio.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'quantum') diff --git a/quantum/audio.c b/quantum/audio.c index 602366973..ba85e418e 100644 --- a/quantum/audio.c +++ b/quantum/audio.c @@ -351,7 +351,8 @@ void play_notes(float (*np)[][2], uint8_t n_count, bool n_repeat, float n_rest) if (audio_config.enable) { - if (note || notes) + // Cancel note if a note is playing + if (note) stop_all_notes(); notes_pointer = np; @@ -406,7 +407,8 @@ void play_note(double freq, int vol) { if (audio_config.enable && voices < 8) { - if (note || notes) + // Cancel notes if notes are playing + if (notes) stop_all_notes(); #ifdef PWM_AUDIO freq = freq / SAMPLE_RATE; -- cgit v1.2.3-24-g4f1b From e49712b5593b887c8af18aeb7196513f1c7b7bcf Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Mon, 18 Apr 2016 21:01:48 -0400 Subject: note sliding - on right now --- quantum/audio.c | 81 +++++++++++++++++++++++-------------------------- quantum/keymap_common.c | 1 + 2 files changed, 39 insertions(+), 43 deletions(-) (limited to 'quantum') diff --git a/quantum/audio.c b/quantum/audio.c index 69c58ca6c..6a5d43013 100644 --- a/quantum/audio.c +++ b/quantum/audio.c @@ -65,6 +65,7 @@ uint8_t notes_count; bool notes_repeat; float notes_rest; bool note_resting = false; +int note_flipper = 0; uint8_t current_note = 0; uint8_t rest_counter = 0; @@ -127,6 +128,9 @@ void stop_note(double freq) { voices--; if (voices < 0) voices = 0; + if (voice_place >= voices) { + voice_place = 0; + } if (voices == 0) { #ifdef PWM_AUDIO TIMSK3 &= ~_BV(OCIE3A); @@ -137,25 +141,6 @@ void stop_note(double freq) { frequency = 0; volume = 0; note = false; - } else { - double freq = frequencies[voices - 1]; - int vol = volumes[voices - 1]; - double starting_f = frequency; - if (frequency < freq) { - sliding = true; - for (double f = starting_f; f <= freq; f += ((freq - starting_f) / 2000.0)) { - frequency = f; - } - sliding = false; - } else if (frequency > freq) { - sliding = true; - for (double f = starting_f; f >= freq; f -= ((starting_f - freq) / 2000.0)) { - frequency = f; - } - sliding = false; - } - frequency = freq; - volume = vol; } } } @@ -248,16 +233,41 @@ ISR(TIMER3_COMPA_vect) { OCR4A = sum; } #else - if (frequency > 0) { + if (frequencies[voice_place] > 0) { + // if (frequencies[voice_place] > 880.0) { + // if (note_flipper == 100) { + // note_flipper = 0; + // return; + // } + // note_flipper++; + // } else { + // note_flipper = 0; + // } // ICR3 = (int)(((double)F_CPU) / frequency); // Set max to the period // OCR3A = (int)(((double)F_CPU) / frequency) >> 1; // Set compare to half the period - voice_place %= voices; - if (place > (frequencies[voice_place] / 50)) { - voice_place = (voice_place + 1) % voices; - place = 0.0; + + double freq; + if (false) { + voice_place %= voices; + if (place > (frequencies[voice_place] / 50)) { + voice_place = (voice_place + 1) % voices; + place = 0.0; + } + freq = frequencies[voice_place]; + } else { + if (frequency != 0) { + if (frequency < frequencies[voices - 1]) { + frequency = frequency * 1.01454533494; + } else if (frequency > frequencies[voices - 1]) { + frequency = frequency * 0.98566319864; + } + } else { + frequency = frequencies[voices - 1]; + } + freq = frequency; } - ICR3 = (int)(((double)F_CPU) / (frequencies[voice_place] * CPU_PRESCALER)); // Set max to the period - OCR3A = (int)((((double)F_CPU) / (frequencies[voice_place] * CPU_PRESCALER)) * note_timbre); // Set compare to half the period + ICR3 = (int)(((double)F_CPU) / (freq * CPU_PRESCALER)); // Set max to the period + OCR3A = (int)((((double)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); // Set compare to half the period //OCR3A = (int)(((double)F_CPU) / (frequencies[voice_place] * CPU_PRESCALER)) >> 1 * duty_place; // Set compare to half the period place++; // if (duty_counter > (frequencies[voice_place] / 500)) { @@ -413,23 +423,8 @@ if (audio_config.enable && voices < 8) { freq = freq / SAMPLE_RATE; #endif if (freq > 0) { - if (frequency != 0) { - double starting_f = frequency; - if (frequency < freq) { - for (double f = starting_f; f <= freq; f += ((freq - starting_f) / 2000.0)) { - frequency = f; - } - } else if (frequency > freq) { - for (double f = starting_f; f >= freq; f -= ((starting_f - freq) / 2000.0)) { - frequency = f; - } - } - } - frequency = freq; - volume = vol; - - frequencies[voices] = frequency; - volumes[voices] = volume; + frequencies[voices] = freq; + volumes[voices] = vol; voices++; } diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c index 4ee290ad0..43debf4ef 100644 --- a/quantum/keymap_common.c +++ b/quantum/keymap_common.c @@ -184,6 +184,7 @@ static action_t keycode_to_action(uint16_t keycode) case RESET: ; // RESET is 0x5000, which is why this is here clear_keyboard(); #ifdef AUDIO_ENABLE + stop_all_notes(); play_goodbye_tone(); #endif _delay_ms(250); -- cgit v1.2.3-24-g4f1b From a2f31c886ff13c5e7adeccccfe672698c1c7efb9 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Tue, 19 Apr 2016 12:58:13 -0400 Subject: getting ready for getters and setters --- quantum/audio.c | 81 +++++++++++++++++++++++-------------------- quantum/audio.h | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 149 insertions(+), 36 deletions(-) (limited to 'quantum') diff --git a/quantum/audio.c b/quantum/audio.c index d8768f160..c92cb5373 100644 --- a/quantum/audio.c +++ b/quantum/audio.c @@ -34,8 +34,6 @@ int voice_place = 0; double frequency = 0; int volume = 0; long position = 0; -int duty_place = 1; -int duty_counter = 0; double frequencies[8] = {0, 0, 0, 0, 0, 0, 0, 0}; int volumes[8] = {0, 0, 0, 0, 0, 0, 0, 0}; @@ -51,7 +49,7 @@ uint16_t place_int = 0; bool repeat = true; uint8_t * sample; uint16_t sample_length = 0; - +double freq = 0; bool notes = false; bool note = false; @@ -65,11 +63,15 @@ uint8_t notes_count; bool notes_repeat; float notes_rest; bool note_resting = false; -int note_flipper = 0; uint8_t current_note = 0; uint8_t rest_counter = 0; +uint8_t vibrato_counter = 0; +float vibrato_strength = 0; + +float polyphony_rate = 0; + audio_config_t audio_config; @@ -182,6 +184,11 @@ void init_notes() { #endif } +float mod(float a, int b) +{ + float r = fmod(a, b); + return r < 0 ? r + b : r; +} ISR(TIMER3_COMPA_vect) { if (note) { @@ -233,48 +240,41 @@ ISR(TIMER3_COMPA_vect) { OCR4A = sum; } #else - if (frequencies[voice_place] > 0) { - // if (frequencies[voice_place] > 880.0) { - // if (note_flipper == 100) { - // note_flipper = 0; - // return; - // } - // note_flipper++; - // } else { - // note_flipper = 0; - // } - // ICR3 = (int)(((double)F_CPU) / frequency); // Set max to the period - // OCR3A = (int)(((double)F_CPU) / frequency) >> 1; // Set compare to half the period - - double freq; - if (false) { - voice_place %= voices; - if (place > (frequencies[voice_place] / 50)) { - voice_place = (voice_place + 1) % voices; - place = 0.0; + if (voices > 0) { + if (false && polyphony_rate > 0) { + if (voices > 1) { + voice_place %= voices; + if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER / voices)) { + voice_place = (voice_place + 1) % voices; + place = 0.0; + } } - freq = frequencies[voice_place]; + if (vibrato_strength > 0) { + freq = frequencies[voice_place] * pow(VIBRATO_LUT[(int)vibrato_counter], vibrato_strength); + vibrato_counter = mod((vibrato_counter + 1), VIBRATO_LUT_LENGTH); + } else { + freq = frequencies[voice_place]; + } } else { if (frequency != 0) { if (frequency < frequencies[voices - 1]) { - frequency = frequency * 1.01454533494; + frequency = frequency * pow(2, 440/frequencies[voices - 1]/12/4); } else if (frequency > frequencies[voices - 1]) { - frequency = frequency * 0.98566319864; + frequency = frequency * pow(2, -440/frequencies[voices - 1]/12/4); } } else { frequency = frequencies[voices - 1]; } - freq = frequency; + + if (false && vibrato_strength > 0) { + freq = frequency * pow(VIBRATO_LUT[(int)vibrato_counter], vibrato_strength); + vibrato_counter = mod((vibrato_counter + 1 + 440/frequencies[voices - 1]), VIBRATO_LUT_LENGTH); + } else { + freq = frequency; + } } ICR3 = (int)(((double)F_CPU) / (freq * CPU_PRESCALER)); // Set max to the period OCR3A = (int)((((double)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); // Set compare to half the period - //OCR3A = (int)(((double)F_CPU) / (frequencies[voice_place] * CPU_PRESCALER)) >> 1 * duty_place; // Set compare to half the period - place++; - // if (duty_counter > (frequencies[voice_place] / 500)) { - // duty_place = (duty_place % 3) + 1; - // duty_counter = 0; - // } - // duty_counter++; } #endif } @@ -300,8 +300,17 @@ ISR(TIMER3_COMPA_vect) { place -= SINE_LENGTH; #else if (note_frequency > 0) { - ICR3 = (int)(((double)F_CPU) / (note_frequency * CPU_PRESCALER)); // Set max to the period - OCR3A = (int)((((double)F_CPU) / (note_frequency * CPU_PRESCALER)) * note_timbre); // Set compare to half the period + float freq; + + if (false && vibrato_strength > 0) { + freq = note_frequency * pow(VIBRATO_LUT[(int)vibrato_counter], vibrato_strength); + vibrato_counter = mod((vibrato_counter + 1), VIBRATO_LUT_LENGTH); + } else { + freq = note_frequency; + } + + ICR3 = (int)(((double)F_CPU) / (freq * CPU_PRESCALER)); // Set max to the period + OCR3A = (int)((((double)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); // Set compare to half the period } else { ICR3 = 0; OCR3A = 0; diff --git a/quantum/audio.h b/quantum/audio.h index 44cafccd6..f705341d7 100644 --- a/quantum/audio.h +++ b/quantum/audio.h @@ -47,4 +47,108 @@ void decrease_tempo(uint8_t tempo_change); void play_goodbye_tone(void); void play_startup_tone(void); +#define VIBRATO_LUT (float []) { \ +1.00090714186239, \ +1.00181152169061, \ +1.00270955652027, \ +1.00359767896099, \ +1.00447235162891, \ +1.00533008160601, \ +1.00616743486158, \ +1.00698105056935, \ +1.00776765525194, \ +1.00852407668313, \ +1.0092472574777, \ +1.00993426829815, \ +1.01058232060837, \ +1.01118877890462, \ +1.01175117235612, \ +1.01226720578933, \ +1.01273476995269, \ +1.01315195100182, \ +1.0135170391489, \ +1.01382853642434, \ +1.01408516350345, \ +1.01428586555648, \ +1.0144298170856, \ +1.0145164257189, \ +1.01454533493752, \ +1.0145164257189, \ +1.0144298170856, \ +1.01428586555648, \ +1.01408516350345, \ +1.01382853642434, \ +1.0135170391489, \ +1.01315195100182, \ +1.01273476995269, \ +1.01226720578933, \ +1.01175117235612, \ +1.01118877890462, \ +1.01058232060837, \ +1.00993426829815, \ +1.0092472574777, \ +1.00852407668313, \ +1.00776765525194, \ +1.00698105056935, \ +1.00616743486158, \ +1.00533008160601, \ +1.00447235162891, \ +1.00359767896099, \ +1.00270955652027, \ +1.00181152169061, \ +1.00090714186239, \ +1, \ +0.999093680298157, \ +0.998191753986265, \ +0.997297765337276, \ +0.996415217934032, \ +0.995547561242821, \ +0.99469817754036, \ +0.993870369236874, \ +0.993067346634376, \ +0.992292216155724, \ +0.991547969076588, \ +0.990837470789065, \ +0.990163450622494, \ +0.989528492243954, \ +0.988935024658062, \ +0.988385313823004, \ +0.98788145489731, \ +0.987425365129624, \ +0.987018777401739, \ +0.986663234433381, \ +0.986360083655655, \ +0.986110472758728, \ +0.985915345918143, \ +0.985775440703176, \ +0.985691285669809, \ +0.985663198640188, \ +0.985691285669809, \ +0.985775440703176, \ +0.985915345918143, \ +0.986110472758728, \ +0.986360083655655, \ +0.986663234433381, \ +0.987018777401739, \ +0.987425365129624, \ +0.98788145489731, \ +0.988385313823004, \ +0.988935024658062, \ +0.989528492243954, \ +0.990163450622494, \ +0.990837470789065, \ +0.991547969076588, \ +0.992292216155724, \ +0.993067346634376, \ +0.993870369236874, \ +0.99469817754036, \ +0.99554756124282, \ +0.996415217934032, \ +0.997297765337276, \ +0.998191753986265, \ +0.999093680298157, \ +1, \ +} +#define VIBRATO_LUT_LENGTH NOTE_ARRAY_SIZE(VIBRATO_LUT) + #endif \ No newline at end of file -- cgit v1.2.3-24-g4f1b From fd49dfe5cb686f5966447c6b890800c9cd11d281 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Tue, 19 Apr 2016 17:00:45 -0400 Subject: vibrato and polyphony paratmeters --- quantum/audio.c | 160 ++++++++++++++++++++++++++++++++++---------------- quantum/audio.h | 140 ++++++++++--------------------------------- quantum/vibrato_lut.h | 108 ++++++++++++++++++++++++++++++++++ 3 files changed, 249 insertions(+), 159 deletions(-) create mode 100644 quantum/vibrato_lut.h (limited to 'quantum') diff --git a/quantum/audio.c b/quantum/audio.c index c92cb5373..8ea1bf6ff 100644 --- a/quantum/audio.c +++ b/quantum/audio.c @@ -10,10 +10,13 @@ #include "eeconfig.h" +#include "vibrato_lut.h" + #define PI 3.14159265 #define CPU_PRESCALER 8 +// Largely untested PWM audio mode (doesn't sound as good) // #define PWM_AUDIO #ifdef PWM_AUDIO @@ -67,10 +70,11 @@ bool note_resting = false; uint8_t current_note = 0; uint8_t rest_counter = 0; -uint8_t vibrato_counter = 0; -float vibrato_strength = 0; +float vibrato_counter = 0; +float vibrato_strength = .5; +float vibrato_rate = 0.125; -float polyphony_rate = 0; +float polyphony_rate = .5; audio_config_t audio_config; @@ -90,6 +94,81 @@ void audio_off(void) { eeconfig_write_audio(audio_config.raw); } +// Vibrato rate functions + +void set_vibrato_rate(float rate) { + vibrato_rate = rate; +} + +void increase_vibrato_rate(float change) { + vibrato_rate *= change; +} + +void decrease_vibrato_rate(float change) { + vibrato_rate /= change; +} + +#ifdef VIBRATO_STRENGTH_ENABLE + +void set_vibrato_strength(float strength) { + vibrato_strength = strength; +} + +void increase_vibrato_strength(float change) { + vibrato_strength *= change; +} + +void decrease_vibrato_strength(float change) { + vibrato_strength /= change; +} + +#endif + +// Polyphony functions + +void set_polyphony_rate(float rate) { + polyphony_rate = rate; +} + +void enable_polyphony() { + polyphony_rate = 5; +} + +void disable_polyphony() { + polyphony_rate = 0; +} + +void increase_polyphony_rate(float change) { + polyphony_rate *= change; +} + +void decrease_polyphony_rate(float change) { + polyphony_rate /= change; +} + +// Timbre function + +void set_timbre(float timbre) { + note_timbre = timbre; +} + +// Tempo functions + +void set_tempo(float tempo) { + note_tempo = tempo; +} + +void decrease_tempo(uint8_t tempo_change) { + note_tempo += (float) tempo_change; +} + +void increase_tempo(uint8_t tempo_change) { + if (note_tempo - (float) tempo_change < 10) { + note_tempo = 10; + } else { + note_tempo -= (float) tempo_change; + } +} void stop_all_notes() { voices = 0; @@ -112,6 +191,7 @@ void stop_all_notes() { void stop_note(double freq) { if (note) { + cli(); #ifdef PWM_AUDIO freq = freq / SAMPLE_RATE; #endif @@ -125,6 +205,7 @@ void stop_note(double freq) { volumes[j] = volumes[j+1]; volumes[j+1] = 0; } + break; } } voices--; @@ -144,6 +225,7 @@ void stop_note(double freq) { volume = 0; note = false; } + sei(); } } @@ -190,6 +272,16 @@ float mod(float a, int b) return r < 0 ? r + b : r; } +float vibrato(float average_freq) { + #ifdef VIBRATO_STRENGTH_ENABLE + float vibrated_freq = average_freq * pow(VIBRATO_LUT[(int)vibrato_counter], vibrato_strength); + #else + float vibrated_freq = average_freq * VIBRATO_LUT[(int)vibrato_counter]; + #endif + vibrato_counter = mod((vibrato_counter + vibrato_rate * (1.0 + 440.0/average_freq)), VIBRATO_LUT_LENGTH); + return vibrated_freq; +} + ISR(TIMER3_COMPA_vect) { if (note) { #ifdef PWM_AUDIO @@ -241,34 +333,30 @@ ISR(TIMER3_COMPA_vect) { } #else if (voices > 0) { - if (false && polyphony_rate > 0) { + if (polyphony_rate > 0) { if (voices > 1) { voice_place %= voices; - if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER / voices)) { + if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER)) { voice_place = (voice_place + 1) % voices; place = 0.0; } } if (vibrato_strength > 0) { - freq = frequencies[voice_place] * pow(VIBRATO_LUT[(int)vibrato_counter], vibrato_strength); - vibrato_counter = mod((vibrato_counter + 1), VIBRATO_LUT_LENGTH); + freq = vibrato(frequencies[voice_place]); } else { freq = frequencies[voice_place]; } } else { - if (frequency != 0) { - if (frequency < frequencies[voices - 1]) { - frequency = frequency * pow(2, 440/frequencies[voices - 1]/12/4); - } else if (frequency > frequencies[voices - 1]) { - frequency = frequency * pow(2, -440/frequencies[voices - 1]/12/4); - } + if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440/frequencies[voices - 1]/12/2)) { + frequency = frequency * pow(2, 440/frequency/12/2); + } else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440/frequencies[voices - 1]/12/2)) { + frequency = frequency * pow(2, -440/frequency/12/2); } else { frequency = frequencies[voices - 1]; } - if (false && vibrato_strength > 0) { - freq = frequency * pow(VIBRATO_LUT[(int)vibrato_counter], vibrato_strength); - vibrato_counter = mod((vibrato_counter + 1 + 440/frequencies[voices - 1]), VIBRATO_LUT_LENGTH); + if (vibrato_strength > 0) { + freq = vibrato(frequency); } else { freq = frequency; } @@ -302,9 +390,8 @@ ISR(TIMER3_COMPA_vect) { if (note_frequency > 0) { float freq; - if (false && vibrato_strength > 0) { - freq = note_frequency * pow(VIBRATO_LUT[(int)vibrato_counter], vibrato_strength); - vibrato_counter = mod((vibrato_counter + 1), VIBRATO_LUT_LENGTH); + if (vibrato_strength > 0) { + freq = vibrato(note_frequency); } else { freq = note_frequency; } @@ -369,7 +456,7 @@ ISR(TIMER3_COMPA_vect) { void play_notes(float (*np)[][2], uint8_t n_count, bool n_repeat, float n_rest) { if (audio_config.enable) { - + cli(); // Cancel note if a note is playing if (note) stop_all_notes(); @@ -398,7 +485,7 @@ if (audio_config.enable) { TIMSK3 |= _BV(OCIE3A); TCCR3A |= _BV(COM3A1); #endif - + sei(); } } @@ -425,7 +512,7 @@ if (audio_config.enable) { void play_note(double freq, int vol) { if (audio_config.enable && voices < 8) { - + cli(); // Cancel notes if notes are playing if (notes) stop_all_notes(); @@ -445,36 +532,9 @@ if (audio_config.enable && voices < 8) { TIMSK3 |= _BV(OCIE3A); TCCR3A |= _BV(COM3A1); #endif - -} - -} - -void set_timbre(float timbre) -{ - note_timbre = timbre; + sei(); } -void set_tempo(float tempo) -{ - note_tempo = tempo; -} - -void decrease_tempo(uint8_t tempo_change) -{ - note_tempo += (float) tempo_change; -} - -void increase_tempo(uint8_t tempo_change) -{ - if (note_tempo - (float) tempo_change < 10) - { - note_tempo = 10; - } - else - { - note_tempo -= (float) tempo_change; - } } //------------------------------------------------------------------------------ diff --git a/quantum/audio.h b/quantum/audio.h index f705341d7..85756af9d 100644 --- a/quantum/audio.h +++ b/quantum/audio.h @@ -8,6 +8,9 @@ #ifndef AUDIO_H #define AUDIO_H +// Enable vibrato strength/amplitude - slows down ISR too much +// #define VIBRATO_STRENGTH_ENABLE + typedef union { uint8_t raw; struct { @@ -20,6 +23,34 @@ void audio_toggle(void); void audio_on(void); void audio_off(void); +// Vibrato rate functions + +void set_vibrato_rate(float rate); +void increase_vibrato_rate(float change); +void decrease_vibrato_rate(float change); + +#ifdef VIBRATO_STRENGTH_ENABLE + +void set_vibrato_strength(float strength); +void increase_vibrato_strength(float change); +void decrease_vibrato_strength(float change); + +#endif + +// Polyphony functions + +void set_polyphony_rate(float rate); +void enable_polyphony(); +void disable_polyphony(); +void increase_polyphony_rate(float change); +void decrease_polyphony_rate(float change); + +void set_timbre(float timbre); +void set_tempo(float tempo); + +void increase_tempo(uint8_t tempo_change); +void decrease_tempo(uint8_t tempo_change); + void play_sample(uint8_t * s, uint16_t l, bool r); void play_note(double freq, int vol); void stop_note(double freq); @@ -27,11 +58,6 @@ void stop_all_notes(void); void init_notes(void); void play_notes(float (*np)[][2], uint8_t n_count, bool n_repeat, float n_rest); -void set_timbre(float timbre); -void set_tempo(float tempo); -void increase_tempo(uint8_t tempo_change); -void decrease_tempo(uint8_t tempo_change); - #define SCALE (int []){ 0 + (12*0), 2 + (12*0), 4 + (12*0), 5 + (12*0), 7 + (12*0), 9 + (12*0), 11 + (12*0), \ 0 + (12*1), 2 + (12*1), 4 + (12*1), 5 + (12*1), 7 + (12*1), 9 + (12*1), 11 + (12*1), \ 0 + (12*2), 2 + (12*2), 4 + (12*2), 5 + (12*2), 7 + (12*2), 9 + (12*2), 11 + (12*2), \ @@ -47,108 +73,4 @@ void decrease_tempo(uint8_t tempo_change); void play_goodbye_tone(void); void play_startup_tone(void); -#define VIBRATO_LUT (float []) { \ -1.00090714186239, \ -1.00181152169061, \ -1.00270955652027, \ -1.00359767896099, \ -1.00447235162891, \ -1.00533008160601, \ -1.00616743486158, \ -1.00698105056935, \ -1.00776765525194, \ -1.00852407668313, \ -1.0092472574777, \ -1.00993426829815, \ -1.01058232060837, \ -1.01118877890462, \ -1.01175117235612, \ -1.01226720578933, \ -1.01273476995269, \ -1.01315195100182, \ -1.0135170391489, \ -1.01382853642434, \ -1.01408516350345, \ -1.01428586555648, \ -1.0144298170856, \ -1.0145164257189, \ -1.01454533493752, \ -1.0145164257189, \ -1.0144298170856, \ -1.01428586555648, \ -1.01408516350345, \ -1.01382853642434, \ -1.0135170391489, \ -1.01315195100182, \ -1.01273476995269, \ -1.01226720578933, \ -1.01175117235612, \ -1.01118877890462, \ -1.01058232060837, \ -1.00993426829815, \ -1.0092472574777, \ -1.00852407668313, \ -1.00776765525194, \ -1.00698105056935, \ -1.00616743486158, \ -1.00533008160601, \ -1.00447235162891, \ -1.00359767896099, \ -1.00270955652027, \ -1.00181152169061, \ -1.00090714186239, \ -1, \ -0.999093680298157, \ -0.998191753986265, \ -0.997297765337276, \ -0.996415217934032, \ -0.995547561242821, \ -0.99469817754036, \ -0.993870369236874, \ -0.993067346634376, \ -0.992292216155724, \ -0.991547969076588, \ -0.990837470789065, \ -0.990163450622494, \ -0.989528492243954, \ -0.988935024658062, \ -0.988385313823004, \ -0.98788145489731, \ -0.987425365129624, \ -0.987018777401739, \ -0.986663234433381, \ -0.986360083655655, \ -0.986110472758728, \ -0.985915345918143, \ -0.985775440703176, \ -0.985691285669809, \ -0.985663198640188, \ -0.985691285669809, \ -0.985775440703176, \ -0.985915345918143, \ -0.986110472758728, \ -0.986360083655655, \ -0.986663234433381, \ -0.987018777401739, \ -0.987425365129624, \ -0.98788145489731, \ -0.988385313823004, \ -0.988935024658062, \ -0.989528492243954, \ -0.990163450622494, \ -0.990837470789065, \ -0.991547969076588, \ -0.992292216155724, \ -0.993067346634376, \ -0.993870369236874, \ -0.99469817754036, \ -0.99554756124282, \ -0.996415217934032, \ -0.997297765337276, \ -0.998191753986265, \ -0.999093680298157, \ -1, \ -} -#define VIBRATO_LUT_LENGTH NOTE_ARRAY_SIZE(VIBRATO_LUT) - #endif \ No newline at end of file diff --git a/quantum/vibrato_lut.h b/quantum/vibrato_lut.h new file mode 100644 index 000000000..4c267a626 --- /dev/null +++ b/quantum/vibrato_lut.h @@ -0,0 +1,108 @@ +#include +#include +#include + +#define VIBRATO_LUT_LENGTH 100 + +const float VIBRATO_LUT[VIBRATO_LUT_LENGTH] = { \ +1.00045346811453, +1.00090535101508, +1.00135386178926, +1.00179722447259, +1.00223368114872, +1.0026614990145, +1.00307897737994, +1.00348445457284, +1.00387631471807, +1.00425299436105, +1.00461298890553, +1.00495485883603, +1.00527723569589, +1.00557882779254, +1.00585842560279, +1.00611490685176, +1.00634724124066, +1.00655449479987, +1.00673583384565, +1.00689052852052, +1.00701795589922, +1.00711760264454, +1.0071890671992, +1.00723206150266, +1.0072464122237, +1.00723206150266, +1.0071890671992, +1.00711760264454, +1.00701795589922, +1.00689052852052, +1.00673583384565, +1.00655449479987, +1.00634724124066, +1.00611490685176, +1.00585842560279, +1.00557882779254, +1.00527723569589, +1.00495485883603, +1.00461298890553, +1.00425299436105, +1.00387631471807, +1.00348445457284, +1.00307897737994, +1.0026614990145, +1.00223368114872, +1.00179722447259, +1.00135386178926, +1.00090535101508, +1.00045346811453, +1, +0.999546737425598, +0.999095467903976, +0.998647968674285, +0.998205999748565, +0.99777129706302, +0.997345565759612, +0.996930473622346, +0.996527644691494, +0.996138653077835, +0.99576501699778, +0.995408193048995, +0.995069570744927, +0.994750467325326, +0.994452122858643, +0.994175695650927, +0.993922257974591, +0.99369279212925, +0.993488186845591, +0.993309234042139, +0.993156625943589, +0.993030952568311, +0.99293269959154, +0.992862246589715, +0.992819865670409, +0.992805720491269, +0.992819865670409, +0.992862246589715, +0.99293269959154, +0.993030952568311, +0.993156625943589, +0.993309234042139, +0.993488186845591, +0.99369279212925, +0.993922257974591, +0.994175695650927, +0.994452122858643, +0.994750467325326, +0.995069570744927, +0.995408193048995, +0.99576501699778, +0.996138653077835, +0.996527644691494, +0.996930473622346, +0.997345565759612, +0.99777129706302, +0.998205999748565, +0.998647968674285, +0.999095467903976, +0.999546737425598, +1 +}; \ No newline at end of file -- cgit v1.2.3-24-g4f1b From 462601f5e8de3476963c6fef44a88653e19fc3fd Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Tue, 19 Apr 2016 21:25:48 -0400 Subject: breaking changes - restructuring audio.c a little --- quantum/audio.c | 108 +++++++++++++++++++++++++++++++++----------------------- quantum/audio.h | 1 - 2 files changed, 63 insertions(+), 46 deletions(-) (limited to 'quantum') diff --git a/quantum/audio.c b/quantum/audio.c index 8ea1bf6ff..bbdbc824c 100644 --- a/quantum/audio.c +++ b/quantum/audio.c @@ -74,7 +74,9 @@ float vibrato_counter = 0; float vibrato_strength = .5; float vibrato_rate = 0.125; -float polyphony_rate = .5; +float polyphony_rate = 0; + +bool inited = false; audio_config_t audio_config; @@ -170,7 +172,49 @@ void increase_tempo(uint8_t tempo_change) { } } +void audio_init() { + + /* check signature */ + if (!eeconfig_is_enabled()) { + eeconfig_init(); + } + audio_config.raw = eeconfig_read_audio(); + + #ifdef PWM_AUDIO + PLLFRQ = _BV(PDIV2); + PLLCSR = _BV(PLLE); + while(!(PLLCSR & _BV(PLOCK))); + PLLFRQ |= _BV(PLLTM0); /* PCK 48MHz */ + + /* Init a fast PWM on Timer4 */ + TCCR4A = _BV(COM4A0) | _BV(PWM4A); /* Clear OC4A on Compare Match */ + TCCR4B = _BV(CS40); /* No prescaling => f = PCK/256 = 187500Hz */ + OCR4A = 0; + + /* Enable the OC4A output */ + DDRC |= _BV(PORTC6); + + TIMSK3 &= ~_BV(OCIE3A); // Turn off 3A interputs + + TCCR3A = 0x0; // Options not needed + TCCR3B = _BV(CS31) | _BV(CS30) | _BV(WGM32); // 64th prescaling and CTC + OCR3A = SAMPLE_DIVIDER - 1; // Correct count/compare, related to sample playback + #else + DDRC |= _BV(PORTC6); + + TIMSK3 &= ~_BV(OCIE3A); // Turn off 3A interputs + + TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30); + TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30); + #endif + + inited = true; +} + void stop_all_notes() { + if (!inited) { + audio_init(); + } voices = 0; #ifdef PWM_AUDIO TIMSK3 &= ~_BV(OCIE3A); @@ -191,7 +235,9 @@ void stop_all_notes() { void stop_note(double freq) { if (note) { - cli(); + if (!inited) { + audio_init(); + } #ifdef PWM_AUDIO freq = freq / SAMPLE_RATE; #endif @@ -225,47 +271,9 @@ void stop_note(double freq) { volume = 0; note = false; } - sei(); } } -void init_notes() { - - /* check signature */ - if (!eeconfig_is_enabled()) { - eeconfig_init(); - } - audio_config.raw = eeconfig_read_audio(); - - #ifdef PWM_AUDIO - PLLFRQ = _BV(PDIV2); - PLLCSR = _BV(PLLE); - while(!(PLLCSR & _BV(PLOCK))); - PLLFRQ |= _BV(PLLTM0); /* PCK 48MHz */ - - /* Init a fast PWM on Timer4 */ - TCCR4A = _BV(COM4A0) | _BV(PWM4A); /* Clear OC4A on Compare Match */ - TCCR4B = _BV(CS40); /* No prescaling => f = PCK/256 = 187500Hz */ - OCR4A = 0; - - /* Enable the OC4A output */ - DDRC |= _BV(PORTC6); - - TIMSK3 &= ~_BV(OCIE3A); // Turn off 3A interputs - - TCCR3A = 0x0; // Options not needed - TCCR3B = _BV(CS31) | _BV(CS30) | _BV(WGM32); // 64th prescaling and CTC - OCR3A = SAMPLE_DIVIDER - 1; // Correct count/compare, related to sample playback - #else - DDRC |= _BV(PORTC6); - - TIMSK3 &= ~_BV(OCIE3A); // Turn off 3A interputs - - TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30); - TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30); - #endif -} - float mod(float a, int b) { float r = fmod(a, b); @@ -456,7 +464,10 @@ ISR(TIMER3_COMPA_vect) { void play_notes(float (*np)[][2], uint8_t n_count, bool n_repeat, float n_rest) { if (audio_config.enable) { - cli(); + TIMSK3 &= ~_BV(OCIE3A); + if (!inited) { + audio_init(); + } // Cancel note if a note is playing if (note) stop_all_notes(); @@ -485,7 +496,6 @@ if (audio_config.enable) { TIMSK3 |= _BV(OCIE3A); TCCR3A |= _BV(COM3A1); #endif - sei(); } } @@ -493,7 +503,10 @@ if (audio_config.enable) { void play_sample(uint8_t * s, uint16_t l, bool r) { if (audio_config.enable) { - + TIMSK3 &= ~_BV(OCIE3A); + if (!inited) { + audio_init(); + } stop_all_notes(); place_int = 0; sample = s; @@ -512,7 +525,10 @@ if (audio_config.enable) { void play_note(double freq, int vol) { if (audio_config.enable && voices < 8) { - cli(); + TIMSK3 &= ~_BV(OCIE3A); + if (!inited) { + audio_init(); + } // Cancel notes if notes are playing if (notes) stop_all_notes(); @@ -532,7 +548,6 @@ if (audio_config.enable && voices < 8) { TIMSK3 |= _BV(OCIE3A); TCCR3A |= _BV(COM3A1); #endif - sei(); } } @@ -545,8 +560,11 @@ void play_startup_tone() { } + + __attribute__ ((weak)) void play_goodbye_tone() { + } //------------------------------------------------------------------------------ diff --git a/quantum/audio.h b/quantum/audio.h index 85756af9d..0fe3eac9a 100644 --- a/quantum/audio.h +++ b/quantum/audio.h @@ -55,7 +55,6 @@ void play_sample(uint8_t * s, uint16_t l, bool r); void play_note(double freq, int vol); void stop_note(double freq); void stop_all_notes(void); -void init_notes(void); void play_notes(float (*np)[][2], uint8_t n_count, bool n_repeat, float n_rest); #define SCALE (int []){ 0 + (12*0), 2 + (12*0), 4 + (12*0), 5 + (12*0), 7 + (12*0), 9 + (12*0), 11 + (12*0), \ -- cgit v1.2.3-24-g4f1b From de4690593cec908b19f97509f45c78534fd5440f Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Wed, 20 Apr 2016 01:08:17 -0400 Subject: fixed startup audio with a 500ms delay --- quantum/audio.c | 136 +++++++++++++++++++++++++++++--------------------- quantum/audio.h | 21 ++++++-- quantum/vibrato_lut.h | 82 +----------------------------- 3 files changed, 97 insertions(+), 142 deletions(-) (limited to 'quantum') diff --git a/quantum/audio.c b/quantum/audio.c index bbdbc824c..ab3444bc9 100644 --- a/quantum/audio.c +++ b/quantum/audio.c @@ -10,20 +10,23 @@ #include "eeconfig.h" -#include "vibrato_lut.h" +#ifdef VIBRATO_ENABLE + #include "vibrato_lut.h" +#endif #define PI 3.14159265 #define CPU_PRESCALER 8 -// Largely untested PWM audio mode (doesn't sound as good) -// #define PWM_AUDIO - #ifdef PWM_AUDIO #include "wave.h" #define SAMPLE_DIVIDER 39 #define SAMPLE_RATE (2000000.0/SAMPLE_DIVIDER/2048) // Resistor value of 1/ (2 * PI * 10nF * (2000000 hertz / SAMPLE_DIVIDER / 10)) for 10nF cap + + float places[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + uint16_t place_int = 0; + bool repeat = true; #endif void delay_us(int count) { @@ -34,25 +37,21 @@ void delay_us(int count) { int voices = 0; int voice_place = 0; -double frequency = 0; +float frequency = 0; int volume = 0; long position = 0; -double frequencies[8] = {0, 0, 0, 0, 0, 0, 0, 0}; +float frequencies[8] = {0, 0, 0, 0, 0, 0, 0, 0}; int volumes[8] = {0, 0, 0, 0, 0, 0, 0, 0}; bool sliding = false; int max = 0xFF; float sum = 0; -int value = 128; float place = 0; -float places[8] = {0, 0, 0, 0, 0, 0, 0, 0}; -uint16_t place_int = 0; -bool repeat = true; uint8_t * sample; uint16_t sample_length = 0; -double freq = 0; +// float freq = 0; bool notes = false; bool note = false; @@ -62,7 +61,7 @@ float note_tempo = TEMPO_DEFAULT; float note_timbre = TIMBRE_DEFAULT; uint16_t note_position = 0; float (* notes_pointer)[][2]; -uint8_t notes_count; +uint16_t notes_count; bool notes_repeat; float notes_rest; bool note_resting = false; @@ -70,9 +69,11 @@ bool note_resting = false; uint8_t current_note = 0; uint8_t rest_counter = 0; +#ifdef VIBRATO_ENABLE float vibrato_counter = 0; float vibrato_strength = .5; float vibrato_rate = 0.125; +#endif float polyphony_rate = 0; @@ -96,6 +97,7 @@ void audio_off(void) { eeconfig_write_audio(audio_config.raw); } +#ifdef VIBRATO_ENABLE // Vibrato rate functions void set_vibrato_rate(float rate) { @@ -126,6 +128,8 @@ void decrease_vibrato_strength(float change) { #endif +#endif + // Polyphony functions void set_polyphony_rate(float rate) { @@ -209,6 +213,7 @@ void audio_init() { #endif inited = true; + _delay_ms(500); } void stop_all_notes() { @@ -233,7 +238,7 @@ void stop_all_notes() { } } -void stop_note(double freq) { +void stop_note(float freq) { if (note) { if (!inited) { audio_init(); @@ -274,6 +279,8 @@ void stop_note(double freq) { } } +#ifdef VIBRATO_ENABLE + float mod(float a, int b) { float r = fmod(a, b); @@ -290,6 +297,8 @@ float vibrato(float average_freq) { return vibrated_freq; } +#endif + ISR(TIMER3_COMPA_vect) { if (note) { #ifdef PWM_AUDIO @@ -341,6 +350,7 @@ ISR(TIMER3_COMPA_vect) { } #else if (voices > 0) { + float freq; if (polyphony_rate > 0) { if (voices > 1) { voice_place %= voices; @@ -349,9 +359,13 @@ ISR(TIMER3_COMPA_vect) { place = 0.0; } } + #ifdef VIBRATO_ENABLE if (vibrato_strength > 0) { freq = vibrato(frequencies[voice_place]); } else { + #else + { + #endif freq = frequencies[voice_place]; } } else { @@ -363,9 +377,14 @@ ISR(TIMER3_COMPA_vect) { frequency = frequencies[voices - 1]; } + + #ifdef VIBRATO_ENABLE if (vibrato_strength > 0) { freq = vibrato(frequency); } else { + #else + { + #endif freq = frequency; } } @@ -398,9 +417,13 @@ ISR(TIMER3_COMPA_vect) { if (note_frequency > 0) { float freq; + #ifdef VIBRATO_ENABLE if (vibrato_strength > 0) { freq = vibrato(note_frequency); } else { + #else + { + #endif freq = note_frequency; } @@ -461,13 +484,45 @@ ISR(TIMER3_COMPA_vect) { } } -void play_notes(float (*np)[][2], uint8_t n_count, bool n_repeat, float n_rest) { +void play_note(float freq, int vol) { -if (audio_config.enable) { + if (!inited) { + audio_init(); + } + +if (audio_config.enable && voices < 8) { TIMSK3 &= ~_BV(OCIE3A); + // Cancel notes if notes are playing + if (notes) + stop_all_notes(); + note = true; + #ifdef PWM_AUDIO + freq = freq / SAMPLE_RATE; + #endif + if (freq > 0) { + frequencies[voices] = freq; + volumes[voices] = vol; + voices++; + } + + #ifdef PWM_AUDIO + TIMSK3 |= _BV(OCIE3A); + #else + TIMSK3 |= _BV(OCIE3A); + TCCR3A |= _BV(COM3A1); + #endif +} + +} + +void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat, float n_rest) { + if (!inited) { audio_init(); } + +if (audio_config.enable) { + TIMSK3 &= ~_BV(OCIE3A); // Cancel note if a note is playing if (note) stop_all_notes(); @@ -500,57 +555,24 @@ if (audio_config.enable) { } +#ifdef PWM_AUDIO void play_sample(uint8_t * s, uint16_t l, bool r) { - -if (audio_config.enable) { - TIMSK3 &= ~_BV(OCIE3A); if (!inited) { audio_init(); } - stop_all_notes(); - place_int = 0; - sample = s; - sample_length = l; - repeat = r; - #ifdef PWM_AUDIO - TIMSK3 |= _BV(OCIE3A); - #else - #endif - -} - -} - -void play_note(double freq, int vol) { - -if (audio_config.enable && voices < 8) { - TIMSK3 &= ~_BV(OCIE3A); - if (!inited) { - audio_init(); - } - // Cancel notes if notes are playing - if (notes) + if (audio_config.enable) { + TIMSK3 &= ~_BV(OCIE3A); stop_all_notes(); - note = true; - #ifdef PWM_AUDIO - freq = freq / SAMPLE_RATE; - #endif - if (freq > 0) { - frequencies[voices] = freq; - volumes[voices] = vol; - voices++; - } + place_int = 0; + sample = s; + sample_length = l; + repeat = r; - #ifdef PWM_AUDIO TIMSK3 |= _BV(OCIE3A); - #else - TIMSK3 |= _BV(OCIE3A); - TCCR3A |= _BV(COM3A1); - #endif -} - + } } +#endif //------------------------------------------------------------------------------ // Override these functions in your keymap file to play different tunes on diff --git a/quantum/audio.h b/quantum/audio.h index 0fe3eac9a..2d4d303ce 100644 --- a/quantum/audio.h +++ b/quantum/audio.h @@ -8,6 +8,11 @@ #ifndef AUDIO_H #define AUDIO_H +// Largely untested PWM audio mode (doesn't sound as good) +// #define PWM_AUDIO + +// #define VIBRATO_ENABLE + // Enable vibrato strength/amplitude - slows down ISR too much // #define VIBRATO_STRENGTH_ENABLE @@ -25,6 +30,8 @@ void audio_off(void); // Vibrato rate functions +#ifdef VIBRATO_ENABLE + void set_vibrato_rate(float rate); void increase_vibrato_rate(float change); void decrease_vibrato_rate(float change); @@ -37,6 +44,8 @@ void decrease_vibrato_strength(float change); #endif +#endif + // Polyphony functions void set_polyphony_rate(float rate); @@ -51,11 +60,15 @@ void set_tempo(float tempo); void increase_tempo(uint8_t tempo_change); void decrease_tempo(uint8_t tempo_change); +void audio_init(); + +#ifdef PWM_AUDIO void play_sample(uint8_t * s, uint16_t l, bool r); -void play_note(double freq, int vol); -void stop_note(double freq); +#endif +void play_note(float freq, int vol); +void stop_note(float freq); void stop_all_notes(void); -void play_notes(float (*np)[][2], uint8_t n_count, bool n_repeat, float n_rest); +void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat, float n_rest); #define SCALE (int []){ 0 + (12*0), 2 + (12*0), 4 + (12*0), 5 + (12*0), 7 + (12*0), 9 + (12*0), 11 + (12*0), \ 0 + (12*1), 2 + (12*1), 4 + (12*1), 5 + (12*1), 7 + (12*1), 9 + (12*1), 11 + (12*1), \ @@ -66,7 +79,7 @@ void play_notes(float (*np)[][2], uint8_t n_count, bool n_repeat, float n_rest); // These macros are used to allow play_notes to play an array of indeterminate // length. This works around the limitation of C's sizeof operation on pointers. // The global float array for the song must be used here. -#define NOTE_ARRAY_SIZE(x) ((int)(sizeof(x) / (sizeof(x[0])))) +#define NOTE_ARRAY_SIZE(x) ((int16_t)(sizeof(x) / (sizeof(x[0])))) #define PLAY_NOTE_ARRAY(note_array, note_repeat, note_rest_style) play_notes(¬e_array, NOTE_ARRAY_SIZE((note_array)), (note_repeat), (note_rest_style)); void play_goodbye_tone(void); diff --git a/quantum/vibrato_lut.h b/quantum/vibrato_lut.h index 4c267a626..a2b1f3e5c 100644 --- a/quantum/vibrato_lut.h +++ b/quantum/vibrato_lut.h @@ -2,107 +2,27 @@ #include #include -#define VIBRATO_LUT_LENGTH 100 +#define VIBRATO_LUT_LENGTH 20 const float VIBRATO_LUT[VIBRATO_LUT_LENGTH] = { \ -1.00045346811453, -1.00090535101508, -1.00135386178926, -1.00179722447259, 1.00223368114872, -1.0026614990145, -1.00307897737994, -1.00348445457284, -1.00387631471807, 1.00425299436105, -1.00461298890553, -1.00495485883603, -1.00527723569589, -1.00557882779254, 1.00585842560279, -1.00611490685176, -1.00634724124066, -1.00655449479987, -1.00673583384565, 1.00689052852052, -1.00701795589922, -1.00711760264454, -1.0071890671992, -1.00723206150266, 1.0072464122237, -1.00723206150266, -1.0071890671992, -1.00711760264454, -1.00701795589922, 1.00689052852052, -1.00673583384565, -1.00655449479987, -1.00634724124066, -1.00611490685176, 1.00585842560279, -1.00557882779254, -1.00527723569589, -1.00495485883603, -1.00461298890553, 1.00425299436105, -1.00387631471807, -1.00348445457284, -1.00307897737994, -1.0026614990145, 1.00223368114872, -1.00179722447259, -1.00135386178926, -1.00090535101508, -1.00045346811453, 1, -0.999546737425598, -0.999095467903976, -0.998647968674285, -0.998205999748565, 0.99777129706302, -0.997345565759612, -0.996930473622346, -0.996527644691494, -0.996138653077835, 0.99576501699778, -0.995408193048995, -0.995069570744927, -0.994750467325326, -0.994452122858643, 0.994175695650927, -0.993922257974591, -0.99369279212925, -0.993488186845591, -0.993309234042139, 0.993156625943589, -0.993030952568311, -0.99293269959154, -0.992862246589715, -0.992819865670409, 0.992805720491269, -0.992819865670409, -0.992862246589715, -0.99293269959154, -0.993030952568311, 0.993156625943589, -0.993309234042139, -0.993488186845591, -0.99369279212925, -0.993922257974591, 0.994175695650927, -0.994452122858643, -0.994750467325326, -0.995069570744927, -0.995408193048995, 0.99576501699778, -0.996138653077835, -0.996527644691494, -0.996930473622346, -0.997345565759612, 0.99777129706302, -0.998205999748565, -0.998647968674285, -0.999095467903976, -0.999546737425598, 1 }; \ No newline at end of file -- cgit v1.2.3-24-g4f1b From b0635e58eb33b0ed4f6b4a3846660feae15681ad Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Wed, 20 Apr 2016 18:39:36 -0400 Subject: delay isn't the problem here --- quantum/audio.c | 1 - 1 file changed, 1 deletion(-) (limited to 'quantum') diff --git a/quantum/audio.c b/quantum/audio.c index ab3444bc9..e4f0bf30e 100644 --- a/quantum/audio.c +++ b/quantum/audio.c @@ -213,7 +213,6 @@ void audio_init() { #endif inited = true; - _delay_ms(500); } void stop_all_notes() { -- cgit v1.2.3-24-g4f1b From 7d1a683607a95aa9715b5decb1013f3e644b96c9 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Wed, 20 Apr 2016 22:28:47 -0400 Subject: sounds for plover layout --- quantum/song_list.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'quantum') diff --git a/quantum/song_list.h b/quantum/song_list.h index e992bd18a..fc6fcdeef 100644 --- a/quantum/song_list.h +++ b/quantum/song_list.h @@ -64,6 +64,22 @@ S__NOTE(_REST), \ E__NOTE(_E7 ), +#define PLOVER_SOUND \ + E__NOTE(_GS6 ), \ + E__NOTE(_A6 ), \ + S__NOTE(_REST), \ + ED_NOTE(_E7 ), \ + S__NOTE(_REST), \ + ED_NOTE(_A7 ), + +#define PLOVER_GOODBYE_SOUND \ + E__NOTE(_GS6 ), \ + E__NOTE(_A6 ), \ + S__NOTE(_REST), \ + ED_NOTE(_A7 ), \ + S__NOTE(_REST), \ + ED_NOTE(_E7 ), + #define MUSIC_SCALE_SOUND \ E__NOTE(_A5 ), \ E__NOTE(_B5 ), \ -- cgit v1.2.3-24-g4f1b From 2e303b40aed372ea69b79850dae41e4f8ea457f4 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Wed, 20 Apr 2016 22:29:01 -0400 Subject: start of envelope function --- quantum/audio.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'quantum') diff --git a/quantum/audio.c b/quantum/audio.c index e4f0bf30e..1327887d9 100644 --- a/quantum/audio.c +++ b/quantum/audio.c @@ -81,6 +81,7 @@ bool inited = false; audio_config_t audio_config; +uint16_t envelope_index = 0; void audio_toggle(void) { audio_config.enable ^= 1; @@ -298,6 +299,26 @@ float vibrato(float average_freq) { #endif +float envelope(float f) { + uint16_t compensated_index = (uint16_t)((float)envelope_index * (880.0 / f)); + switch (compensated_index) { + case 0: + note_timbre = TIMBRE_50; + break; + case 20: + note_timbre = TIMBRE_25; + break; + case 32: + note_timbre = TIMBRE_12; + break; + case 40 ... 60: + f = f / 2; + note_timbre = TIMBRE_50; + break; + } + return f; +} + ISR(TIMER3_COMPA_vect) { if (note) { #ifdef PWM_AUDIO @@ -387,6 +408,12 @@ ISR(TIMER3_COMPA_vect) { freq = frequency; } } + + if (envelope_index < 65535) { + envelope_index++; + } + freq = envelope(freq); + ICR3 = (int)(((double)F_CPU) / (freq * CPU_PRESCALER)); // Set max to the period OCR3A = (int)((((double)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); // Set compare to half the period } @@ -495,6 +522,7 @@ if (audio_config.enable && voices < 8) { if (notes) stop_all_notes(); note = true; + envelope_index = 0; #ifdef PWM_AUDIO freq = freq / SAMPLE_RATE; #endif -- cgit v1.2.3-24-g4f1b From 2e60054951ce08e973c735991bd95390c6aa3842 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Wed, 20 Apr 2016 23:16:39 -0400 Subject: fade envelope --- quantum/audio.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'quantum') diff --git a/quantum/audio.c b/quantum/audio.c index 1327887d9..df421ef99 100644 --- a/quantum/audio.c +++ b/quantum/audio.c @@ -302,18 +302,19 @@ float vibrato(float average_freq) { float envelope(float f) { uint16_t compensated_index = (uint16_t)((float)envelope_index * (880.0 / f)); switch (compensated_index) { - case 0: - note_timbre = TIMBRE_50; - break; - case 20: - note_timbre = TIMBRE_25; - break; - case 32: + case 0 ... 9: + f = f / 4; note_timbre = TIMBRE_12; break; - case 40 ... 60: + case 10 ... 19: f = f / 2; - note_timbre = TIMBRE_50; + note_timbre = TIMBRE_12; + break; + case 20 ... 200: + note_timbre = .125 - pow(((float)compensated_index - 20) / (200 - 20), 2)*.125; + break; + default: + note_timbre = 0; break; } return f; @@ -414,6 +415,8 @@ ISR(TIMER3_COMPA_vect) { } freq = envelope(freq); + if (freq < 30.517578125) + freq = 30.52; ICR3 = (int)(((double)F_CPU) / (freq * CPU_PRESCALER)); // Set max to the period OCR3A = (int)((((double)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); // Set compare to half the period } -- cgit v1.2.3-24-g4f1b From 73228f5e5d1d4cd31a46e5e93aa893a8f727e3b9 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Thu, 21 Apr 2016 00:37:45 -0400 Subject: restructures audio, begins voicing --- quantum/audio.c | 622 ------------------------------------------ quantum/audio.h | 88 ------ quantum/audio/audio.c | 607 +++++++++++++++++++++++++++++++++++++++++ quantum/audio/audio.h | 89 ++++++ quantum/audio/musical_notes.h | 217 +++++++++++++++ quantum/audio/song_list.h | 117 ++++++++ quantum/audio/vibrato_lut.h | 28 ++ quantum/audio/voices.c | 60 ++++ quantum/audio/voices.h | 21 ++ quantum/audio/wave.h | 265 ++++++++++++++++++ quantum/musical_notes.h | 217 --------------- quantum/quantum.mk | 3 +- quantum/song_list.h | 117 -------- quantum/vibrato_lut.h | 28 -- quantum/wave.h | 265 ------------------ 15 files changed, 1406 insertions(+), 1338 deletions(-) delete mode 100644 quantum/audio.c delete mode 100644 quantum/audio.h create mode 100644 quantum/audio/audio.c create mode 100644 quantum/audio/audio.h create mode 100644 quantum/audio/musical_notes.h create mode 100644 quantum/audio/song_list.h create mode 100644 quantum/audio/vibrato_lut.h create mode 100644 quantum/audio/voices.c create mode 100644 quantum/audio/voices.h create mode 100644 quantum/audio/wave.h delete mode 100644 quantum/musical_notes.h delete mode 100644 quantum/song_list.h delete mode 100644 quantum/vibrato_lut.h delete mode 100644 quantum/wave.h (limited to 'quantum') diff --git a/quantum/audio.c b/quantum/audio.c deleted file mode 100644 index df421ef99..000000000 --- a/quantum/audio.c +++ /dev/null @@ -1,622 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "print.h" -#include "audio.h" -#include "keymap_common.h" - -#include "eeconfig.h" - -#ifdef VIBRATO_ENABLE - #include "vibrato_lut.h" -#endif - -#define PI 3.14159265 - -#define CPU_PRESCALER 8 - -#ifdef PWM_AUDIO - #include "wave.h" - #define SAMPLE_DIVIDER 39 - #define SAMPLE_RATE (2000000.0/SAMPLE_DIVIDER/2048) - // Resistor value of 1/ (2 * PI * 10nF * (2000000 hertz / SAMPLE_DIVIDER / 10)) for 10nF cap - - float places[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - uint16_t place_int = 0; - bool repeat = true; -#endif - -void delay_us(int count) { - while(count--) { - _delay_us(1); - } -} - -int voices = 0; -int voice_place = 0; -float frequency = 0; -int volume = 0; -long position = 0; - -float frequencies[8] = {0, 0, 0, 0, 0, 0, 0, 0}; -int volumes[8] = {0, 0, 0, 0, 0, 0, 0, 0}; -bool sliding = false; - -int max = 0xFF; -float sum = 0; -float place = 0; - -uint8_t * sample; -uint16_t sample_length = 0; -// float freq = 0; - -bool notes = false; -bool note = false; -float note_frequency = 0; -float note_length = 0; -float note_tempo = TEMPO_DEFAULT; -float note_timbre = TIMBRE_DEFAULT; -uint16_t note_position = 0; -float (* notes_pointer)[][2]; -uint16_t notes_count; -bool notes_repeat; -float notes_rest; -bool note_resting = false; - -uint8_t current_note = 0; -uint8_t rest_counter = 0; - -#ifdef VIBRATO_ENABLE -float vibrato_counter = 0; -float vibrato_strength = .5; -float vibrato_rate = 0.125; -#endif - -float polyphony_rate = 0; - -bool inited = false; - -audio_config_t audio_config; - -uint16_t envelope_index = 0; - -void audio_toggle(void) { - audio_config.enable ^= 1; - eeconfig_write_audio(audio_config.raw); -} - -void audio_on(void) { - audio_config.enable = 1; - eeconfig_write_audio(audio_config.raw); -} - -void audio_off(void) { - audio_config.enable = 0; - eeconfig_write_audio(audio_config.raw); -} - -#ifdef VIBRATO_ENABLE -// Vibrato rate functions - -void set_vibrato_rate(float rate) { - vibrato_rate = rate; -} - -void increase_vibrato_rate(float change) { - vibrato_rate *= change; -} - -void decrease_vibrato_rate(float change) { - vibrato_rate /= change; -} - -#ifdef VIBRATO_STRENGTH_ENABLE - -void set_vibrato_strength(float strength) { - vibrato_strength = strength; -} - -void increase_vibrato_strength(float change) { - vibrato_strength *= change; -} - -void decrease_vibrato_strength(float change) { - vibrato_strength /= change; -} - -#endif - -#endif - -// Polyphony functions - -void set_polyphony_rate(float rate) { - polyphony_rate = rate; -} - -void enable_polyphony() { - polyphony_rate = 5; -} - -void disable_polyphony() { - polyphony_rate = 0; -} - -void increase_polyphony_rate(float change) { - polyphony_rate *= change; -} - -void decrease_polyphony_rate(float change) { - polyphony_rate /= change; -} - -// Timbre function - -void set_timbre(float timbre) { - note_timbre = timbre; -} - -// Tempo functions - -void set_tempo(float tempo) { - note_tempo = tempo; -} - -void decrease_tempo(uint8_t tempo_change) { - note_tempo += (float) tempo_change; -} - -void increase_tempo(uint8_t tempo_change) { - if (note_tempo - (float) tempo_change < 10) { - note_tempo = 10; - } else { - note_tempo -= (float) tempo_change; - } -} - -void audio_init() { - - /* check signature */ - if (!eeconfig_is_enabled()) { - eeconfig_init(); - } - audio_config.raw = eeconfig_read_audio(); - - #ifdef PWM_AUDIO - PLLFRQ = _BV(PDIV2); - PLLCSR = _BV(PLLE); - while(!(PLLCSR & _BV(PLOCK))); - PLLFRQ |= _BV(PLLTM0); /* PCK 48MHz */ - - /* Init a fast PWM on Timer4 */ - TCCR4A = _BV(COM4A0) | _BV(PWM4A); /* Clear OC4A on Compare Match */ - TCCR4B = _BV(CS40); /* No prescaling => f = PCK/256 = 187500Hz */ - OCR4A = 0; - - /* Enable the OC4A output */ - DDRC |= _BV(PORTC6); - - TIMSK3 &= ~_BV(OCIE3A); // Turn off 3A interputs - - TCCR3A = 0x0; // Options not needed - TCCR3B = _BV(CS31) | _BV(CS30) | _BV(WGM32); // 64th prescaling and CTC - OCR3A = SAMPLE_DIVIDER - 1; // Correct count/compare, related to sample playback - #else - DDRC |= _BV(PORTC6); - - TIMSK3 &= ~_BV(OCIE3A); // Turn off 3A interputs - - TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30); - TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30); - #endif - - inited = true; -} - -void stop_all_notes() { - if (!inited) { - audio_init(); - } - voices = 0; - #ifdef PWM_AUDIO - TIMSK3 &= ~_BV(OCIE3A); - #else - TIMSK3 &= ~_BV(OCIE3A); - TCCR3A &= ~_BV(COM3A1); - #endif - notes = false; - note = false; - frequency = 0; - volume = 0; - - for (int i = 0; i < 8; i++) { - frequencies[i] = 0; - volumes[i] = 0; - } -} - -void stop_note(float freq) { - if (note) { - if (!inited) { - audio_init(); - } - #ifdef PWM_AUDIO - freq = freq / SAMPLE_RATE; - #endif - for (int i = 7; i >= 0; i--) { - if (frequencies[i] == freq) { - frequencies[i] = 0; - volumes[i] = 0; - for (int j = i; (j < 7); j++) { - frequencies[j] = frequencies[j+1]; - frequencies[j+1] = 0; - volumes[j] = volumes[j+1]; - volumes[j+1] = 0; - } - break; - } - } - voices--; - if (voices < 0) - voices = 0; - if (voice_place >= voices) { - voice_place = 0; - } - if (voices == 0) { - #ifdef PWM_AUDIO - TIMSK3 &= ~_BV(OCIE3A); - #else - TIMSK3 &= ~_BV(OCIE3A); - TCCR3A &= ~_BV(COM3A1); - #endif - frequency = 0; - volume = 0; - note = false; - } - } -} - -#ifdef VIBRATO_ENABLE - -float mod(float a, int b) -{ - float r = fmod(a, b); - return r < 0 ? r + b : r; -} - -float vibrato(float average_freq) { - #ifdef VIBRATO_STRENGTH_ENABLE - float vibrated_freq = average_freq * pow(VIBRATO_LUT[(int)vibrato_counter], vibrato_strength); - #else - float vibrated_freq = average_freq * VIBRATO_LUT[(int)vibrato_counter]; - #endif - vibrato_counter = mod((vibrato_counter + vibrato_rate * (1.0 + 440.0/average_freq)), VIBRATO_LUT_LENGTH); - return vibrated_freq; -} - -#endif - -float envelope(float f) { - uint16_t compensated_index = (uint16_t)((float)envelope_index * (880.0 / f)); - switch (compensated_index) { - case 0 ... 9: - f = f / 4; - note_timbre = TIMBRE_12; - break; - case 10 ... 19: - f = f / 2; - note_timbre = TIMBRE_12; - break; - case 20 ... 200: - note_timbre = .125 - pow(((float)compensated_index - 20) / (200 - 20), 2)*.125; - break; - default: - note_timbre = 0; - break; - } - return f; -} - -ISR(TIMER3_COMPA_vect) { - if (note) { - #ifdef PWM_AUDIO - if (voices == 1) { - // SINE - OCR4A = pgm_read_byte(&sinewave[(uint16_t)place]) >> 2; - - // SQUARE - // if (((int)place) >= 1024){ - // OCR4A = 0xFF >> 2; - // } else { - // OCR4A = 0x00; - // } - - // SAWTOOTH - // OCR4A = (int)place / 4; - - // TRIANGLE - // if (((int)place) >= 1024) { - // OCR4A = (int)place / 2; - // } else { - // OCR4A = 2048 - (int)place / 2; - // } - - place += frequency; - - if (place >= SINE_LENGTH) - place -= SINE_LENGTH; - - } else { - int sum = 0; - for (int i = 0; i < voices; i++) { - // SINE - sum += pgm_read_byte(&sinewave[(uint16_t)places[i]]) >> 2; - - // SQUARE - // if (((int)places[i]) >= 1024){ - // sum += 0xFF >> 2; - // } else { - // sum += 0x00; - // } - - places[i] += frequencies[i]; - - if (places[i] >= SINE_LENGTH) - places[i] -= SINE_LENGTH; - } - OCR4A = sum; - } - #else - if (voices > 0) { - float freq; - if (polyphony_rate > 0) { - if (voices > 1) { - voice_place %= voices; - if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER)) { - voice_place = (voice_place + 1) % voices; - place = 0.0; - } - } - #ifdef VIBRATO_ENABLE - if (vibrato_strength > 0) { - freq = vibrato(frequencies[voice_place]); - } else { - #else - { - #endif - freq = frequencies[voice_place]; - } - } else { - if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440/frequencies[voices - 1]/12/2)) { - frequency = frequency * pow(2, 440/frequency/12/2); - } else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440/frequencies[voices - 1]/12/2)) { - frequency = frequency * pow(2, -440/frequency/12/2); - } else { - frequency = frequencies[voices - 1]; - } - - - #ifdef VIBRATO_ENABLE - if (vibrato_strength > 0) { - freq = vibrato(frequency); - } else { - #else - { - #endif - freq = frequency; - } - } - - if (envelope_index < 65535) { - envelope_index++; - } - freq = envelope(freq); - - if (freq < 30.517578125) - freq = 30.52; - ICR3 = (int)(((double)F_CPU) / (freq * CPU_PRESCALER)); // Set max to the period - OCR3A = (int)((((double)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); // Set compare to half the period - } - #endif - } - - // SAMPLE - // OCR4A = pgm_read_byte(&sample[(uint16_t)place_int]); - - // place_int++; - - // if (place_int >= sample_length) - // if (repeat) - // place_int -= sample_length; - // else - // TIMSK3 &= ~_BV(OCIE3A); - - - if (notes) { - #ifdef PWM_AUDIO - OCR4A = pgm_read_byte(&sinewave[(uint16_t)place]) >> 0; - - place += note_frequency; - if (place >= SINE_LENGTH) - place -= SINE_LENGTH; - #else - if (note_frequency > 0) { - float freq; - - #ifdef VIBRATO_ENABLE - if (vibrato_strength > 0) { - freq = vibrato(note_frequency); - } else { - #else - { - #endif - freq = note_frequency; - } - - ICR3 = (int)(((double)F_CPU) / (freq * CPU_PRESCALER)); // Set max to the period - OCR3A = (int)((((double)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); // Set compare to half the period - } else { - ICR3 = 0; - OCR3A = 0; - } - #endif - - - note_position++; - bool end_of_note = false; - if (ICR3 > 0) - end_of_note = (note_position >= (note_length / ICR3 * 0xFFFF)); - else - end_of_note = (note_position >= (note_length * 0x7FF)); - if (end_of_note) { - current_note++; - if (current_note >= notes_count) { - if (notes_repeat) { - current_note = 0; - } else { - #ifdef PWM_AUDIO - TIMSK3 &= ~_BV(OCIE3A); - #else - TIMSK3 &= ~_BV(OCIE3A); - TCCR3A &= ~_BV(COM3A1); - #endif - notes = false; - return; - } - } - if (!note_resting && (notes_rest > 0)) { - note_resting = true; - note_frequency = 0; - note_length = notes_rest; - current_note--; - } else { - note_resting = false; - #ifdef PWM_AUDIO - note_frequency = (*notes_pointer)[current_note][0] / SAMPLE_RATE; - note_length = (*notes_pointer)[current_note][1] * (note_tempo / 100); - #else - note_frequency = (*notes_pointer)[current_note][0]; - note_length = ((*notes_pointer)[current_note][1] / 4) * (note_tempo / 100); - #endif - } - note_position = 0; - } - - } - - if (!audio_config.enable) { - notes = false; - note = false; - } -} - -void play_note(float freq, int vol) { - - if (!inited) { - audio_init(); - } - -if (audio_config.enable && voices < 8) { - TIMSK3 &= ~_BV(OCIE3A); - // Cancel notes if notes are playing - if (notes) - stop_all_notes(); - note = true; - envelope_index = 0; - #ifdef PWM_AUDIO - freq = freq / SAMPLE_RATE; - #endif - if (freq > 0) { - frequencies[voices] = freq; - volumes[voices] = vol; - voices++; - } - - #ifdef PWM_AUDIO - TIMSK3 |= _BV(OCIE3A); - #else - TIMSK3 |= _BV(OCIE3A); - TCCR3A |= _BV(COM3A1); - #endif -} - -} - -void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat, float n_rest) { - - if (!inited) { - audio_init(); - } - -if (audio_config.enable) { - TIMSK3 &= ~_BV(OCIE3A); - // Cancel note if a note is playing - if (note) - stop_all_notes(); - notes = true; - - notes_pointer = np; - notes_count = n_count; - notes_repeat = n_repeat; - notes_rest = n_rest; - - place = 0; - current_note = 0; - #ifdef PWM_AUDIO - note_frequency = (*notes_pointer)[current_note][0] / SAMPLE_RATE; - note_length = (*notes_pointer)[current_note][1] * (note_tempo / 100); - #else - note_frequency = (*notes_pointer)[current_note][0]; - note_length = ((*notes_pointer)[current_note][1] / 4) * (note_tempo / 100); - #endif - note_position = 0; - - - #ifdef PWM_AUDIO - TIMSK3 |= _BV(OCIE3A); - #else - TIMSK3 |= _BV(OCIE3A); - TCCR3A |= _BV(COM3A1); - #endif -} - -} - -#ifdef PWM_AUDIO -void play_sample(uint8_t * s, uint16_t l, bool r) { - if (!inited) { - audio_init(); - } - - if (audio_config.enable) { - TIMSK3 &= ~_BV(OCIE3A); - stop_all_notes(); - place_int = 0; - sample = s; - sample_length = l; - repeat = r; - - TIMSK3 |= _BV(OCIE3A); - } -} -#endif - -//------------------------------------------------------------------------------ -// Override these functions in your keymap file to play different tunes on -// startup and bootloader jump -__attribute__ ((weak)) -void play_startup_tone() -{ -} - - - -__attribute__ ((weak)) -void play_goodbye_tone() -{ - -} -//------------------------------------------------------------------------------ diff --git a/quantum/audio.h b/quantum/audio.h deleted file mode 100644 index 2d4d303ce..000000000 --- a/quantum/audio.h +++ /dev/null @@ -1,88 +0,0 @@ -#include -#include -#include -#include -#include "musical_notes.h" -#include "song_list.h" - -#ifndef AUDIO_H -#define AUDIO_H - -// Largely untested PWM audio mode (doesn't sound as good) -// #define PWM_AUDIO - -// #define VIBRATO_ENABLE - -// Enable vibrato strength/amplitude - slows down ISR too much -// #define VIBRATO_STRENGTH_ENABLE - -typedef union { - uint8_t raw; - struct { - bool enable :1; - uint8_t level :7; - }; -} audio_config_t; - -void audio_toggle(void); -void audio_on(void); -void audio_off(void); - -// Vibrato rate functions - -#ifdef VIBRATO_ENABLE - -void set_vibrato_rate(float rate); -void increase_vibrato_rate(float change); -void decrease_vibrato_rate(float change); - -#ifdef VIBRATO_STRENGTH_ENABLE - -void set_vibrato_strength(float strength); -void increase_vibrato_strength(float change); -void decrease_vibrato_strength(float change); - -#endif - -#endif - -// Polyphony functions - -void set_polyphony_rate(float rate); -void enable_polyphony(); -void disable_polyphony(); -void increase_polyphony_rate(float change); -void decrease_polyphony_rate(float change); - -void set_timbre(float timbre); -void set_tempo(float tempo); - -void increase_tempo(uint8_t tempo_change); -void decrease_tempo(uint8_t tempo_change); - -void audio_init(); - -#ifdef PWM_AUDIO -void play_sample(uint8_t * s, uint16_t l, bool r); -#endif -void play_note(float freq, int vol); -void stop_note(float freq); -void stop_all_notes(void); -void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat, float n_rest); - -#define SCALE (int []){ 0 + (12*0), 2 + (12*0), 4 + (12*0), 5 + (12*0), 7 + (12*0), 9 + (12*0), 11 + (12*0), \ - 0 + (12*1), 2 + (12*1), 4 + (12*1), 5 + (12*1), 7 + (12*1), 9 + (12*1), 11 + (12*1), \ - 0 + (12*2), 2 + (12*2), 4 + (12*2), 5 + (12*2), 7 + (12*2), 9 + (12*2), 11 + (12*2), \ - 0 + (12*3), 2 + (12*3), 4 + (12*3), 5 + (12*3), 7 + (12*3), 9 + (12*3), 11 + (12*3), \ - 0 + (12*4), 2 + (12*4), 4 + (12*4), 5 + (12*4), 7 + (12*4), 9 + (12*4), 11 + (12*4), } - -// These macros are used to allow play_notes to play an array of indeterminate -// length. This works around the limitation of C's sizeof operation on pointers. -// The global float array for the song must be used here. -#define NOTE_ARRAY_SIZE(x) ((int16_t)(sizeof(x) / (sizeof(x[0])))) -#define PLAY_NOTE_ARRAY(note_array, note_repeat, note_rest_style) play_notes(¬e_array, NOTE_ARRAY_SIZE((note_array)), (note_repeat), (note_rest_style)); - -void play_goodbye_tone(void); -void play_startup_tone(void); - -#endif \ No newline at end of file diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c new file mode 100644 index 000000000..3225557ba --- /dev/null +++ b/quantum/audio/audio.c @@ -0,0 +1,607 @@ +#include +#include +#include +#include +#include +#include +#include "print.h" +#include "audio.h" +#include "keymap_common.h" + +#include "eeconfig.h" + +#ifdef VIBRATO_ENABLE + #include "vibrato_lut.h" +#endif + +#define PI 3.14159265 + +#define CPU_PRESCALER 8 + +#ifdef PWM_AUDIO + #include "wave.h" + #define SAMPLE_DIVIDER 39 + #define SAMPLE_RATE (2000000.0/SAMPLE_DIVIDER/2048) + // Resistor value of 1/ (2 * PI * 10nF * (2000000 hertz / SAMPLE_DIVIDER / 10)) for 10nF cap + + float places[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + uint16_t place_int = 0; + bool repeat = true; +#endif + +void delay_us(int count) { + while(count--) { + _delay_us(1); + } +} + +int voices = 0; +int voice_place = 0; +float frequency = 0; +int volume = 0; +long position = 0; + +float frequencies[8] = {0, 0, 0, 0, 0, 0, 0, 0}; +int volumes[8] = {0, 0, 0, 0, 0, 0, 0, 0}; +bool sliding = false; + +int max = 0xFF; +float sum = 0; +float place = 0; + +uint8_t * sample; +uint16_t sample_length = 0; +// float freq = 0; + +bool notes = false; +bool note = false; +float note_frequency = 0; +float note_length = 0; +float note_tempo = TEMPO_DEFAULT; +float note_timbre = TIMBRE_DEFAULT; +uint16_t note_position = 0; +float (* notes_pointer)[][2]; +uint16_t notes_count; +bool notes_repeat; +float notes_rest; +bool note_resting = false; + +uint8_t current_note = 0; +uint8_t rest_counter = 0; + +#ifdef VIBRATO_ENABLE +float vibrato_counter = 0; +float vibrato_strength = .5; +float vibrato_rate = 0.125; +#endif + +float polyphony_rate = 0; + +bool inited = false; + +audio_config_t audio_config; + +uint16_t envelope_index = 0; + +void audio_toggle(void) { + audio_config.enable ^= 1; + eeconfig_write_audio(audio_config.raw); +} + +void audio_on(void) { + audio_config.enable = 1; + eeconfig_write_audio(audio_config.raw); +} + +void audio_off(void) { + audio_config.enable = 0; + eeconfig_write_audio(audio_config.raw); +} + +#ifdef VIBRATO_ENABLE +// Vibrato rate functions + +void set_vibrato_rate(float rate) { + vibrato_rate = rate; +} + +void increase_vibrato_rate(float change) { + vibrato_rate *= change; +} + +void decrease_vibrato_rate(float change) { + vibrato_rate /= change; +} + +#ifdef VIBRATO_STRENGTH_ENABLE + +void set_vibrato_strength(float strength) { + vibrato_strength = strength; +} + +void increase_vibrato_strength(float change) { + vibrato_strength *= change; +} + +void decrease_vibrato_strength(float change) { + vibrato_strength /= change; +} + +#endif + +#endif + +// Polyphony functions + +void set_polyphony_rate(float rate) { + polyphony_rate = rate; +} + +void enable_polyphony() { + polyphony_rate = 5; +} + +void disable_polyphony() { + polyphony_rate = 0; +} + +void increase_polyphony_rate(float change) { + polyphony_rate *= change; +} + +void decrease_polyphony_rate(float change) { + polyphony_rate /= change; +} + +// Timbre function + +void set_timbre(float timbre) { + note_timbre = timbre; +} + +// Tempo functions + +void set_tempo(float tempo) { + note_tempo = tempo; +} + +void decrease_tempo(uint8_t tempo_change) { + note_tempo += (float) tempo_change; +} + +void increase_tempo(uint8_t tempo_change) { + if (note_tempo - (float) tempo_change < 10) { + note_tempo = 10; + } else { + note_tempo -= (float) tempo_change; + } +} + +void audio_init() { + + /* check signature */ + if (!eeconfig_is_enabled()) { + eeconfig_init(); + } + audio_config.raw = eeconfig_read_audio(); + + #ifdef PWM_AUDIO + PLLFRQ = _BV(PDIV2); + PLLCSR = _BV(PLLE); + while(!(PLLCSR & _BV(PLOCK))); + PLLFRQ |= _BV(PLLTM0); /* PCK 48MHz */ + + /* Init a fast PWM on Timer4 */ + TCCR4A = _BV(COM4A0) | _BV(PWM4A); /* Clear OC4A on Compare Match */ + TCCR4B = _BV(CS40); /* No prescaling => f = PCK/256 = 187500Hz */ + OCR4A = 0; + + /* Enable the OC4A output */ + DDRC |= _BV(PORTC6); + + TIMSK3 &= ~_BV(OCIE3A); // Turn off 3A interputs + + TCCR3A = 0x0; // Options not needed + TCCR3B = _BV(CS31) | _BV(CS30) | _BV(WGM32); // 64th prescaling and CTC + OCR3A = SAMPLE_DIVIDER - 1; // Correct count/compare, related to sample playback + #else + DDRC |= _BV(PORTC6); + + TIMSK3 &= ~_BV(OCIE3A); // Turn off 3A interputs + + TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30); + TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30); + #endif + + inited = true; +} + +void stop_all_notes() { + if (!inited) { + audio_init(); + } + voices = 0; + #ifdef PWM_AUDIO + TIMSK3 &= ~_BV(OCIE3A); + #else + TIMSK3 &= ~_BV(OCIE3A); + TCCR3A &= ~_BV(COM3A1); + #endif + notes = false; + note = false; + frequency = 0; + volume = 0; + + for (int i = 0; i < 8; i++) { + frequencies[i] = 0; + volumes[i] = 0; + } +} + +void stop_note(float freq) { + if (note) { + if (!inited) { + audio_init(); + } + #ifdef PWM_AUDIO + freq = freq / SAMPLE_RATE; + #endif + for (int i = 7; i >= 0; i--) { + if (frequencies[i] == freq) { + frequencies[i] = 0; + volumes[i] = 0; + for (int j = i; (j < 7); j++) { + frequencies[j] = frequencies[j+1]; + frequencies[j+1] = 0; + volumes[j] = volumes[j+1]; + volumes[j+1] = 0; + } + break; + } + } + voices--; + if (voices < 0) + voices = 0; + if (voice_place >= voices) { + voice_place = 0; + } + if (voices == 0) { + #ifdef PWM_AUDIO + TIMSK3 &= ~_BV(OCIE3A); + #else + TIMSK3 &= ~_BV(OCIE3A); + TCCR3A &= ~_BV(COM3A1); + #endif + frequency = 0; + volume = 0; + note = false; + } + } +} + +#ifdef VIBRATO_ENABLE + +float mod(float a, int b) +{ + float r = fmod(a, b); + return r < 0 ? r + b : r; +} + +float vibrato(float average_freq) { + #ifdef VIBRATO_STRENGTH_ENABLE + float vibrated_freq = average_freq * pow(VIBRATO_LUT[(int)vibrato_counter], vibrato_strength); + #else + float vibrated_freq = average_freq * VIBRATO_LUT[(int)vibrato_counter]; + #endif + vibrato_counter = mod((vibrato_counter + vibrato_rate * (1.0 + 440.0/average_freq)), VIBRATO_LUT_LENGTH); + return vibrated_freq; +} + +#endif + +ISR(TIMER3_COMPA_vect) { + if (note) { + #ifdef PWM_AUDIO + if (voices == 1) { + // SINE + OCR4A = pgm_read_byte(&sinewave[(uint16_t)place]) >> 2; + + // SQUARE + // if (((int)place) >= 1024){ + // OCR4A = 0xFF >> 2; + // } else { + // OCR4A = 0x00; + // } + + // SAWTOOTH + // OCR4A = (int)place / 4; + + // TRIANGLE + // if (((int)place) >= 1024) { + // OCR4A = (int)place / 2; + // } else { + // OCR4A = 2048 - (int)place / 2; + // } + + place += frequency; + + if (place >= SINE_LENGTH) + place -= SINE_LENGTH; + + } else { + int sum = 0; + for (int i = 0; i < voices; i++) { + // SINE + sum += pgm_read_byte(&sinewave[(uint16_t)places[i]]) >> 2; + + // SQUARE + // if (((int)places[i]) >= 1024){ + // sum += 0xFF >> 2; + // } else { + // sum += 0x00; + // } + + places[i] += frequencies[i]; + + if (places[i] >= SINE_LENGTH) + places[i] -= SINE_LENGTH; + } + OCR4A = sum; + } + #else + if (voices > 0) { + float freq; + if (polyphony_rate > 0) { + if (voices > 1) { + voice_place %= voices; + if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER)) { + voice_place = (voice_place + 1) % voices; + place = 0.0; + } + } + #ifdef VIBRATO_ENABLE + if (vibrato_strength > 0) { + freq = vibrato(frequencies[voice_place]); + } else { + #else + { + #endif + freq = frequencies[voice_place]; + } + } else { + if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440/frequencies[voices - 1]/12/2)) { + frequency = frequency * pow(2, 440/frequency/12/2); + } else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440/frequencies[voices - 1]/12/2)) { + frequency = frequency * pow(2, -440/frequency/12/2); + } else { + frequency = frequencies[voices - 1]; + } + + + #ifdef VIBRATO_ENABLE + if (vibrato_strength > 0) { + freq = vibrato(frequency); + } else { + #else + { + #endif + freq = frequency; + } + } + + if (envelope_index < 65535) { + envelope_index++; + } + freq = voice_envelope(freq); + + if (freq < 30.517578125) + freq = 30.52; + ICR3 = (int)(((double)F_CPU) / (freq * CPU_PRESCALER)); // Set max to the period + OCR3A = (int)((((double)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); // Set compare to half the period + } + #endif + } + + // SAMPLE + // OCR4A = pgm_read_byte(&sample[(uint16_t)place_int]); + + // place_int++; + + // if (place_int >= sample_length) + // if (repeat) + // place_int -= sample_length; + // else + // TIMSK3 &= ~_BV(OCIE3A); + + + if (notes) { + #ifdef PWM_AUDIO + OCR4A = pgm_read_byte(&sinewave[(uint16_t)place]) >> 0; + + place += note_frequency; + if (place >= SINE_LENGTH) + place -= SINE_LENGTH; + #else + if (note_frequency > 0) { + float freq; + + #ifdef VIBRATO_ENABLE + if (vibrato_strength > 0) { + freq = vibrato(note_frequency); + } else { + #else + { + #endif + freq = note_frequency; + } + + if (envelope_index < 65535) { + envelope_index++; + } + freq = voice_envelope(freq); + + ICR3 = (int)(((double)F_CPU) / (freq * CPU_PRESCALER)); // Set max to the period + OCR3A = (int)((((double)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); // Set compare to half the period + } else { + ICR3 = 0; + OCR3A = 0; + } + #endif + + + note_position++; + bool end_of_note = false; + if (ICR3 > 0) + end_of_note = (note_position >= (note_length / ICR3 * 0xFFFF)); + else + end_of_note = (note_position >= (note_length * 0x7FF)); + if (end_of_note) { + current_note++; + if (current_note >= notes_count) { + if (notes_repeat) { + current_note = 0; + } else { + #ifdef PWM_AUDIO + TIMSK3 &= ~_BV(OCIE3A); + #else + TIMSK3 &= ~_BV(OCIE3A); + TCCR3A &= ~_BV(COM3A1); + #endif + notes = false; + return; + } + } + if (!note_resting && (notes_rest > 0)) { + note_resting = true; + note_frequency = 0; + note_length = notes_rest; + current_note--; + } else { + note_resting = false; + #ifdef PWM_AUDIO + note_frequency = (*notes_pointer)[current_note][0] / SAMPLE_RATE; + note_length = (*notes_pointer)[current_note][1] * (note_tempo / 100); + #else + envelope_index = 0; + note_frequency = (*notes_pointer)[current_note][0]; + note_length = ((*notes_pointer)[current_note][1] / 4) * (note_tempo / 100); + #endif + } + note_position = 0; + } + + } + + if (!audio_config.enable) { + notes = false; + note = false; + } +} + +void play_note(float freq, int vol) { + + if (!inited) { + audio_init(); + } + +if (audio_config.enable && voices < 8) { + TIMSK3 &= ~_BV(OCIE3A); + // Cancel notes if notes are playing + if (notes) + stop_all_notes(); + note = true; + envelope_index = 0; + #ifdef PWM_AUDIO + freq = freq / SAMPLE_RATE; + #endif + if (freq > 0) { + frequencies[voices] = freq; + volumes[voices] = vol; + voices++; + } + + #ifdef PWM_AUDIO + TIMSK3 |= _BV(OCIE3A); + #else + TIMSK3 |= _BV(OCIE3A); + TCCR3A |= _BV(COM3A1); + #endif +} + +} + +void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat, float n_rest) { + + if (!inited) { + audio_init(); + } + +if (audio_config.enable) { + TIMSK3 &= ~_BV(OCIE3A); + // Cancel note if a note is playing + if (note) + stop_all_notes(); + notes = true; + + notes_pointer = np; + notes_count = n_count; + notes_repeat = n_repeat; + notes_rest = n_rest; + + place = 0; + current_note = 0; + #ifdef PWM_AUDIO + note_frequency = (*notes_pointer)[current_note][0] / SAMPLE_RATE; + note_length = (*notes_pointer)[current_note][1] * (note_tempo / 100); + #else + note_frequency = (*notes_pointer)[current_note][0]; + note_length = ((*notes_pointer)[current_note][1] / 4) * (note_tempo / 100); + #endif + note_position = 0; + + + #ifdef PWM_AUDIO + TIMSK3 |= _BV(OCIE3A); + #else + TIMSK3 |= _BV(OCIE3A); + TCCR3A |= _BV(COM3A1); + #endif +} + +} + +#ifdef PWM_AUDIO +void play_sample(uint8_t * s, uint16_t l, bool r) { + if (!inited) { + audio_init(); + } + + if (audio_config.enable) { + TIMSK3 &= ~_BV(OCIE3A); + stop_all_notes(); + place_int = 0; + sample = s; + sample_length = l; + repeat = r; + + TIMSK3 |= _BV(OCIE3A); + } +} +#endif + +//------------------------------------------------------------------------------ +// Override these functions in your keymap file to play different tunes on +// startup and bootloader jump +__attribute__ ((weak)) +void play_startup_tone() +{ +} + + + +__attribute__ ((weak)) +void play_goodbye_tone() +{ + +} +//------------------------------------------------------------------------------ diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h new file mode 100644 index 000000000..d1ccfdb82 --- /dev/null +++ b/quantum/audio/audio.h @@ -0,0 +1,89 @@ +#include +#include +#include +#include +#include "musical_notes.h" +#include "song_list.h" +#include "voices.h" + +#ifndef AUDIO_H +#define AUDIO_H + +// Largely untested PWM audio mode (doesn't sound as good) +// #define PWM_AUDIO + +// #define VIBRATO_ENABLE + +// Enable vibrato strength/amplitude - slows down ISR too much +// #define VIBRATO_STRENGTH_ENABLE + +typedef union { + uint8_t raw; + struct { + bool enable :1; + uint8_t level :7; + }; +} audio_config_t; + +void audio_toggle(void); +void audio_on(void); +void audio_off(void); + +// Vibrato rate functions + +#ifdef VIBRATO_ENABLE + +void set_vibrato_rate(float rate); +void increase_vibrato_rate(float change); +void decrease_vibrato_rate(float change); + +#ifdef VIBRATO_STRENGTH_ENABLE + +void set_vibrato_strength(float strength); +void increase_vibrato_strength(float change); +void decrease_vibrato_strength(float change); + +#endif + +#endif + +// Polyphony functions + +void set_polyphony_rate(float rate); +void enable_polyphony(); +void disable_polyphony(); +void increase_polyphony_rate(float change); +void decrease_polyphony_rate(float change); + +void set_timbre(float timbre); +void set_tempo(float tempo); + +void increase_tempo(uint8_t tempo_change); +void decrease_tempo(uint8_t tempo_change); + +void audio_init(); + +#ifdef PWM_AUDIO +void play_sample(uint8_t * s, uint16_t l, bool r); +#endif +void play_note(float freq, int vol); +void stop_note(float freq); +void stop_all_notes(void); +void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat, float n_rest); + +#define SCALE (int []){ 0 + (12*0), 2 + (12*0), 4 + (12*0), 5 + (12*0), 7 + (12*0), 9 + (12*0), 11 + (12*0), \ + 0 + (12*1), 2 + (12*1), 4 + (12*1), 5 + (12*1), 7 + (12*1), 9 + (12*1), 11 + (12*1), \ + 0 + (12*2), 2 + (12*2), 4 + (12*2), 5 + (12*2), 7 + (12*2), 9 + (12*2), 11 + (12*2), \ + 0 + (12*3), 2 + (12*3), 4 + (12*3), 5 + (12*3), 7 + (12*3), 9 + (12*3), 11 + (12*3), \ + 0 + (12*4), 2 + (12*4), 4 + (12*4), 5 + (12*4), 7 + (12*4), 9 + (12*4), 11 + (12*4), } + +// These macros are used to allow play_notes to play an array of indeterminate +// length. This works around the limitation of C's sizeof operation on pointers. +// The global float array for the song must be used here. +#define NOTE_ARRAY_SIZE(x) ((int16_t)(sizeof(x) / (sizeof(x[0])))) +#define PLAY_NOTE_ARRAY(note_array, note_repeat, note_rest_style) play_notes(¬e_array, NOTE_ARRAY_SIZE((note_array)), (note_repeat), (note_rest_style)); + +void play_goodbye_tone(void); +void play_startup_tone(void); + +#endif \ No newline at end of file diff --git a/quantum/audio/musical_notes.h b/quantum/audio/musical_notes.h new file mode 100644 index 000000000..b08d16a6f --- /dev/null +++ b/quantum/audio/musical_notes.h @@ -0,0 +1,217 @@ +#ifndef MUSICAL_NOTES_H +#define MUSICAL_NOTES_H + +// Tempo Placeholder +#define TEMPO_DEFAULT 100 + + +#define SONG(notes...) { notes } + + +// Note Types +#define MUSICAL_NOTE(note, duration) {(NOTE##note), duration} +#define WHOLE_NOTE(note) MUSICAL_NOTE(note, 64) +#define HALF_NOTE(note) MUSICAL_NOTE(note, 32) +#define QUARTER_NOTE(note) MUSICAL_NOTE(note, 16) +#define EIGHTH_NOTE(note) MUSICAL_NOTE(note, 8) +#define SIXTEENTH_NOTE(note) MUSICAL_NOTE(note, 4) + +#define WHOLE_DOT_NOTE(note) MUSICAL_NOTE(note, 64+32) +#define HALF_DOT_NOTE(note) MUSICAL_NOTE(note, 32+16) +#define QUARTER_DOT_NOTE(note) MUSICAL_NOTE(note, 16+8) +#define EIGHTH_DOT_NOTE(note) MUSICAL_NOTE(note, 8+4) +#define SIXTEENTH_DOT_NOTE(note) MUSICAL_NOTE(note, 4+2) + +// Note Type Shortcuts +#define M__NOTE(note, duration) MUSICAL_NOTE(note, duration) +#define W__NOTE(n) WHOLE_NOTE(n) +#define H__NOTE(n) HALF_NOTE(n) +#define Q__NOTE(n) QUARTER_NOTE(n) +#define E__NOTE(n) EIGHTH_NOTE(n) +#define S__NOTE(n) SIXTEENTH_NOTE(n) +#define WD_NOTE(n) WHOLE_DOT_NOTE(n) +#define HD_NOTE(n) HALF_DOT_NOTE(n) +#define QD_NOTE(n) QUARTER_DOT_NOTE(n) +#define ED_NOTE(n) EIGHTH_DOT_NOTE(n) +#define SD_NOTE(n) SIXTEENTH_DOT_NOTE(n) + +// Note Styles +// Staccato makes sure there is a rest between each note. Think: TA TA TA +// Legato makes notes flow together. Think: TAAA +#define STACCATO 0.01 +#define LEGATO 0 + +// Note Timbre +// Changes how the notes sound +#define TIMBRE_12 0.125 +#define TIMBRE_25 0.250 +#define TIMBRE_50 0.500 +#define TIMBRE_75 0.750 +#define TIMBRE_DEFAULT TIMBRE_50 + + +// Notes - # = Octave + +#define NOTE_REST 0.00 + +/* These notes are currently bugged +#define NOTE_C0 16.35 +#define NOTE_CS0 17.32 +#define NOTE_D0 18.35 +#define NOTE_DS0 19.45 +#define NOTE_E0 20.60 +#define NOTE_F0 21.83 +#define NOTE_FS0 23.12 +#define NOTE_G0 24.50 +#define NOTE_GS0 25.96 +#define NOTE_A0 27.50 +#define NOTE_AS0 29.14 +#define NOTE_B0 30.87 +#define NOTE_C1 32.70 +#define NOTE_CS1 34.65 +#define NOTE_D1 36.71 +#define NOTE_DS1 38.89 +#define NOTE_E1 41.20 +#define NOTE_F1 43.65 +#define NOTE_FS1 46.25 +#define NOTE_G1 49.00 +#define NOTE_GS1 51.91 +#define NOTE_A1 55.00 +#define NOTE_AS1 58.27 +*/ + +#define NOTE_B1 61.74 +#define NOTE_C2 65.41 +#define NOTE_CS2 69.30 +#define NOTE_D2 73.42 +#define NOTE_DS2 77.78 +#define NOTE_E2 82.41 +#define NOTE_F2 87.31 +#define NOTE_FS2 92.50 +#define NOTE_G2 98.00 +#define NOTE_GS2 103.83 +#define NOTE_A2 110.00 +#define NOTE_AS2 116.54 +#define NOTE_B2 123.47 +#define NOTE_C3 130.81 +#define NOTE_CS3 138.59 +#define NOTE_D3 146.83 +#define NOTE_DS3 155.56 +#define NOTE_E3 164.81 +#define NOTE_F3 174.61 +#define NOTE_FS3 185.00 +#define NOTE_G3 196.00 +#define NOTE_GS3 207.65 +#define NOTE_A3 220.00 +#define NOTE_AS3 233.08 +#define NOTE_B3 246.94 +#define NOTE_C4 261.63 +#define NOTE_CS4 277.18 +#define NOTE_D4 293.66 +#define NOTE_DS4 311.13 +#define NOTE_E4 329.63 +#define NOTE_F4 349.23 +#define NOTE_FS4 369.99 +#define NOTE_G4 392.00 +#define NOTE_GS4 415.30 +#define NOTE_A4 440.00 +#define NOTE_AS4 466.16 +#define NOTE_B4 493.88 +#define NOTE_C5 523.25 +#define NOTE_CS5 554.37 +#define NOTE_D5 587.33 +#define NOTE_DS5 622.25 +#define NOTE_E5 659.26 +#define NOTE_F5 698.46 +#define NOTE_FS5 739.99 +#define NOTE_G5 783.99 +#define NOTE_GS5 830.61 +#define NOTE_A5 880.00 +#define NOTE_AS5 932.33 +#define NOTE_B5 987.77 +#define NOTE_C6 1046.50 +#define NOTE_CS6 1108.73 +#define NOTE_D6 1174.66 +#define NOTE_DS6 1244.51 +#define NOTE_E6 1318.51 +#define NOTE_F6 1396.91 +#define NOTE_FS6 1479.98 +#define NOTE_G6 1567.98 +#define NOTE_GS6 1661.22 +#define NOTE_A6 1760.00 +#define NOTE_AS6 1864.66 +#define NOTE_B6 1975.53 +#define NOTE_C7 2093.00 +#define NOTE_CS7 2217.46 +#define NOTE_D7 2349.32 +#define NOTE_DS7 2489.02 +#define NOTE_E7 2637.02 +#define NOTE_F7 2793.83 +#define NOTE_FS7 2959.96 +#define NOTE_G7 3135.96 +#define NOTE_GS7 3322.44 +#define NOTE_A7 3520.00 +#define NOTE_AS7 3729.31 +#define NOTE_B7 3951.07 +#define NOTE_C8 4186.01 +#define NOTE_CS8 4434.92 +#define NOTE_D8 4698.64 +#define NOTE_DS8 4978.03 +#define NOTE_E8 5274.04 +#define NOTE_F8 5587.65 +#define NOTE_FS8 5919.91 +#define NOTE_G8 6271.93 +#define NOTE_GS8 6644.88 +#define NOTE_A8 7040.00 +#define NOTE_AS8 7458.62 +#define NOTE_B8 7902.13 + +// Flat Aliases +#define NOTE_DF0 NOTE_CS0 +#define NOTE_EF0 NOTE_DS0 +#define NOTE_GF0 NOTE_FS0 +#define NOTE_AF0 NOTE_GS0 +#define NOTE_BF0 NOTE_AS0 +#define NOTE_DF1 NOTE_CS1 +#define NOTE_EF1 NOTE_DS1 +#define NOTE_GF1 NOTE_FS1 +#define NOTE_AF1 NOTE_GS1 +#define NOTE_BF1 NOTE_AS1 +#define NOTE_DF2 NOTE_CS2 +#define NOTE_EF2 NOTE_DS2 +#define NOTE_GF2 NOTE_FS2 +#define NOTE_AF2 NOTE_GS2 +#define NOTE_BF2 NOTE_AS2 +#define NOTE_DF3 NOTE_CS3 +#define NOTE_EF3 NOTE_DS3 +#define NOTE_GF3 NOTE_FS3 +#define NOTE_AF3 NOTE_GS3 +#define NOTE_BF3 NOTE_AS3 +#define NOTE_DF4 NOTE_CS4 +#define NOTE_EF4 NOTE_DS4 +#define NOTE_GF4 NOTE_FS4 +#define NOTE_AF4 NOTE_GS4 +#define NOTE_BF4 NOTE_AS4 +#define NOTE_DF5 NOTE_CS5 +#define NOTE_EF5 NOTE_DS5 +#define NOTE_GF5 NOTE_FS5 +#define NOTE_AF5 NOTE_GS5 +#define NOTE_BF5 NOTE_AS5 +#define NOTE_DF6 NOTE_CS6 +#define NOTE_EF6 NOTE_DS6 +#define NOTE_GF6 NOTE_FS6 +#define NOTE_AF6 NOTE_GS6 +#define NOTE_BF6 NOTE_AS6 +#define NOTE_DF7 NOTE_CS7 +#define NOTE_EF7 NOTE_DS7 +#define NOTE_GF7 NOTE_FS7 +#define NOTE_AF7 NOTE_GS7 +#define NOTE_BF7 NOTE_AS7 +#define NOTE_DF8 NOTE_CS8 +#define NOTE_EF8 NOTE_DS8 +#define NOTE_GF8 NOTE_FS8 +#define NOTE_AF8 NOTE_GS8 +#define NOTE_BF8 NOTE_AS8 + + +#endif \ No newline at end of file diff --git a/quantum/audio/song_list.h b/quantum/audio/song_list.h new file mode 100644 index 000000000..fc6fcdeef --- /dev/null +++ b/quantum/audio/song_list.h @@ -0,0 +1,117 @@ +#include "musical_notes.h" + +#ifndef SONG_LIST_H +#define SONG_LIST_H + +#define ODE_TO_JOY \ + Q__NOTE(_E4), Q__NOTE(_E4), Q__NOTE(_F4), Q__NOTE(_G4), \ + Q__NOTE(_G4), Q__NOTE(_F4), Q__NOTE(_E4), Q__NOTE(_D4), \ + Q__NOTE(_C4), Q__NOTE(_C4), Q__NOTE(_D4), Q__NOTE(_E4), \ + QD_NOTE(_E4), E__NOTE(_D4), H__NOTE(_D4), + +#define ROCK_A_BYE_BABY \ + QD_NOTE(_B4), E__NOTE(_D4), Q__NOTE(_B5), \ + H__NOTE(_A5), Q__NOTE(_G5), \ + QD_NOTE(_B4), E__NOTE(_D5), Q__NOTE(_G5), \ + H__NOTE(_FS5), + +#define CLOSE_ENCOUNTERS_5_NOTE \ + Q__NOTE(_D5), \ + Q__NOTE(_E5), \ + Q__NOTE(_C5), \ + Q__NOTE(_C4), \ + Q__NOTE(_G4), + +#define DOE_A_DEER \ + QD_NOTE(_C4), E__NOTE(_D4), \ + QD_NOTE(_E4), E__NOTE(_C4), \ + Q__NOTE(_E4), Q__NOTE(_C4), \ + Q__NOTE(_E4), + +#define GOODBYE_SOUND \ + E__NOTE(_E7), \ + E__NOTE(_A6), \ + ED_NOTE(_E6), + +#define STARTUP_SOUND \ + ED_NOTE(_E7 ), \ + E__NOTE(_CS7), \ + E__NOTE(_E6 ), \ + E__NOTE(_A6 ), \ + M__NOTE(_CS7, 20), + +#define QWERTY_SOUND \ + E__NOTE(_GS6 ), \ + E__NOTE(_A6 ), \ + S__NOTE(_REST), \ + Q__NOTE(_E7 ), + +#define COLEMAK_SOUND \ + E__NOTE(_GS6 ), \ + E__NOTE(_A6 ), \ + S__NOTE(_REST), \ + ED_NOTE(_E7 ), \ + S__NOTE(_REST), \ + ED_NOTE(_GS7 ), + +#define DVORAK_SOUND \ + E__NOTE(_GS6 ), \ + E__NOTE(_A6 ), \ + S__NOTE(_REST), \ + E__NOTE(_E7 ), \ + S__NOTE(_REST), \ + E__NOTE(_FS7 ), \ + S__NOTE(_REST), \ + E__NOTE(_E7 ), + +#define PLOVER_SOUND \ + E__NOTE(_GS6 ), \ + E__NOTE(_A6 ), \ + S__NOTE(_REST), \ + ED_NOTE(_E7 ), \ + S__NOTE(_REST), \ + ED_NOTE(_A7 ), + +#define PLOVER_GOODBYE_SOUND \ + E__NOTE(_GS6 ), \ + E__NOTE(_A6 ), \ + S__NOTE(_REST), \ + ED_NOTE(_A7 ), \ + S__NOTE(_REST), \ + ED_NOTE(_E7 ), + +#define MUSIC_SCALE_SOUND \ + E__NOTE(_A5 ), \ + E__NOTE(_B5 ), \ + E__NOTE(_CS6), \ + E__NOTE(_D6 ), \ + E__NOTE(_E6 ), \ + E__NOTE(_FS6), \ + E__NOTE(_GS6), \ + E__NOTE(_A6 ), + +#define CAPS_LOCK_ON_SOUND \ + E__NOTE(_A3), \ + E__NOTE(_B3), + +#define CAPS_LOCK_OFF_SOUND \ + E__NOTE(_B3), \ + E__NOTE(_A3), + +#define SCROLL_LOCK_ON_SOUND \ + E__NOTE(_D4), \ + E__NOTE(_E4), + +#define SCROLL_LOCK_OFF_SOUND \ + E__NOTE(_E4), \ + E__NOTE(_D4), + +#define NUM_LOCK_ON_SOUND \ + E__NOTE(_D5), \ + E__NOTE(_E5), + +#define NUM_LOCK_OFF_SOUND \ + E__NOTE(_E5), \ + E__NOTE(_D5), + +#endif diff --git a/quantum/audio/vibrato_lut.h b/quantum/audio/vibrato_lut.h new file mode 100644 index 000000000..a2b1f3e5c --- /dev/null +++ b/quantum/audio/vibrato_lut.h @@ -0,0 +1,28 @@ +#include +#include +#include + +#define VIBRATO_LUT_LENGTH 20 + +const float VIBRATO_LUT[VIBRATO_LUT_LENGTH] = { \ +1.00223368114872, +1.00425299436105, +1.00585842560279, +1.00689052852052, +1.0072464122237, +1.00689052852052, +1.00585842560279, +1.00425299436105, +1.00223368114872, +1, +0.99777129706302, +0.99576501699778, +0.994175695650927, +0.993156625943589, +0.992805720491269, +0.993156625943589, +0.994175695650927, +0.99576501699778, +0.99777129706302, +1 +}; \ No newline at end of file diff --git a/quantum/audio/voices.c b/quantum/audio/voices.c new file mode 100644 index 000000000..30e8be641 --- /dev/null +++ b/quantum/audio/voices.c @@ -0,0 +1,60 @@ +#include "voices.h" + +extern uint16_t envelope_index; +extern float note_timbre; + +voice_type voice = default_voice; + +void set_voice(voice_type v) { + voice = v; +} + +float voice_envelope(float frequency) { + // envelope_index ranges from 0 to 0xFFFF, which is preserved at 880.0 Hz + uint16_t compensated_index = (uint16_t)((float)envelope_index * (880.0 / frequency)); + + switch (voice) { + case default_voice: + // nothing here on purpose + break; + case butts_fader: + switch (compensated_index) { + case 0 ... 9: + frequency = frequency / 4; + note_timbre = TIMBRE_12; + break; + case 10 ... 19: + frequency = frequency / 2; + note_timbre = TIMBRE_12; + break; + case 20 ... 200: + note_timbre = .125 - pow(((float)compensated_index - 20) / (200 - 20), 2)*.125; + break; + default: + note_timbre = 0; + break; + } + break; + case octave_crunch: + switch (compensated_index) { + case 0 ... 9: + case 20 ... 24: + case 30 ... 32: + frequency = frequency / 2; + note_timbre = TIMBRE_12; + break; + case 10 ... 19: + case 25 ... 29: + case 33 ... 35: + frequency = frequency * 2; + note_timbre = TIMBRE_12; + break; + default: + note_timbre = TIMBRE_12; + break; + } + break; + } + + return frequency; +} \ No newline at end of file diff --git a/quantum/audio/voices.h b/quantum/audio/voices.h new file mode 100644 index 000000000..32135dac7 --- /dev/null +++ b/quantum/audio/voices.h @@ -0,0 +1,21 @@ +#include +#include +#include +#include +#include "musical_notes.h" +#include "song_list.h" + +#ifndef VOICES_H +#define VOICES_H + +float voice_envelope(float frequency); + +typedef enum { + default_voice, + butts_fader, + octave_crunch +} voice_type; + +void set_voice(voice_type v); + +#endif \ No newline at end of file diff --git a/quantum/audio/wave.h b/quantum/audio/wave.h new file mode 100644 index 000000000..6ebc34851 --- /dev/null +++ b/quantum/audio/wave.h @@ -0,0 +1,265 @@ +#include +#include +#include + +#define SINE_LENGTH 2048 + +const uint8_t sinewave[] PROGMEM= //2048 values +{ +0x80,0x80,0x80,0x81,0x81,0x81,0x82,0x82, +0x83,0x83,0x83,0x84,0x84,0x85,0x85,0x85, +0x86,0x86,0x87,0x87,0x87,0x88,0x88,0x88, +0x89,0x89,0x8a,0x8a,0x8a,0x8b,0x8b,0x8c, +0x8c,0x8c,0x8d,0x8d,0x8e,0x8e,0x8e,0x8f, +0x8f,0x8f,0x90,0x90,0x91,0x91,0x91,0x92, +0x92,0x93,0x93,0x93,0x94,0x94,0x95,0x95, +0x95,0x96,0x96,0x96,0x97,0x97,0x98,0x98, +0x98,0x99,0x99,0x9a,0x9a,0x9a,0x9b,0x9b, +0x9b,0x9c,0x9c,0x9d,0x9d,0x9d,0x9e,0x9e, +0x9e,0x9f,0x9f,0xa0,0xa0,0xa0,0xa1,0xa1, +0xa2,0xa2,0xa2,0xa3,0xa3,0xa3,0xa4,0xa4, +0xa5,0xa5,0xa5,0xa6,0xa6,0xa6,0xa7,0xa7, +0xa7,0xa8,0xa8,0xa9,0xa9,0xa9,0xaa,0xaa, +0xaa,0xab,0xab,0xac,0xac,0xac,0xad,0xad, +0xad,0xae,0xae,0xae,0xaf,0xaf,0xb0,0xb0, +0xb0,0xb1,0xb1,0xb1,0xb2,0xb2,0xb2,0xb3, +0xb3,0xb4,0xb4,0xb4,0xb5,0xb5,0xb5,0xb6, +0xb6,0xb6,0xb7,0xb7,0xb7,0xb8,0xb8,0xb8, +0xb9,0xb9,0xba,0xba,0xba,0xbb,0xbb,0xbb, +0xbc,0xbc,0xbc,0xbd,0xbd,0xbd,0xbe,0xbe, +0xbe,0xbf,0xbf,0xbf,0xc0,0xc0,0xc0,0xc1, +0xc1,0xc1,0xc2,0xc2,0xc2,0xc3,0xc3,0xc3, +0xc4,0xc4,0xc4,0xc5,0xc5,0xc5,0xc6,0xc6, +0xc6,0xc7,0xc7,0xc7,0xc8,0xc8,0xc8,0xc9, +0xc9,0xc9,0xca,0xca,0xca,0xcb,0xcb,0xcb, +0xcb,0xcc,0xcc,0xcc,0xcd,0xcd,0xcd,0xce, +0xce,0xce,0xcf,0xcf,0xcf,0xcf,0xd0,0xd0, +0xd0,0xd1,0xd1,0xd1,0xd2,0xd2,0xd2,0xd2, +0xd3,0xd3,0xd3,0xd4,0xd4,0xd4,0xd5,0xd5, +0xd5,0xd5,0xd6,0xd6,0xd6,0xd7,0xd7,0xd7, +0xd7,0xd8,0xd8,0xd8,0xd9,0xd9,0xd9,0xd9, +0xda,0xda,0xda,0xda,0xdb,0xdb,0xdb,0xdc, +0xdc,0xdc,0xdc,0xdd,0xdd,0xdd,0xdd,0xde, +0xde,0xde,0xde,0xdf,0xdf,0xdf,0xe0,0xe0, +0xe0,0xe0,0xe1,0xe1,0xe1,0xe1,0xe2,0xe2, +0xe2,0xe2,0xe3,0xe3,0xe3,0xe3,0xe4,0xe4, +0xe4,0xe4,0xe4,0xe5,0xe5,0xe5,0xe5,0xe6, +0xe6,0xe6,0xe6,0xe7,0xe7,0xe7,0xe7,0xe8, +0xe8,0xe8,0xe8,0xe8,0xe9,0xe9,0xe9,0xe9, +0xea,0xea,0xea,0xea,0xea,0xeb,0xeb,0xeb, +0xeb,0xeb,0xec,0xec,0xec,0xec,0xec,0xed, +0xed,0xed,0xed,0xed,0xee,0xee,0xee,0xee, +0xee,0xef,0xef,0xef,0xef,0xef,0xf0,0xf0, +0xf0,0xf0,0xf0,0xf0,0xf1,0xf1,0xf1,0xf1, +0xf1,0xf2,0xf2,0xf2,0xf2,0xf2,0xf2,0xf3, +0xf3,0xf3,0xf3,0xf3,0xf3,0xf4,0xf4,0xf4, +0xf4,0xf4,0xf4,0xf5,0xf5,0xf5,0xf5,0xf5, +0xf5,0xf5,0xf6,0xf6,0xf6,0xf6,0xf6,0xf6, +0xf6,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7, +0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8, +0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9, +0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa, +0xfa,0xfa,0xfb,0xfb,0xfb,0xfb,0xfb,0xfb, +0xfb,0xfb,0xfb,0xfb,0xfc,0xfc,0xfc,0xfc, +0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc, +0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd, +0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfe,0xfe, +0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe, +0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe, +0xfe,0xfe,0xfe,0xfe,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfe, +0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe, +0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe, +0xfe,0xfe,0xfe,0xfd,0xfd,0xfd,0xfd,0xfd, +0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd, +0xfd,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc, +0xfc,0xfc,0xfc,0xfc,0xfc,0xfb,0xfb,0xfb, +0xfb,0xfb,0xfb,0xfb,0xfb,0xfb,0xfb,0xfa, +0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa, +0xfa,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9, +0xf9,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8, +0xf8,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7, +0xf6,0xf6,0xf6,0xf6,0xf6,0xf6,0xf6,0xf5, +0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf4,0xf4, +0xf4,0xf4,0xf4,0xf4,0xf3,0xf3,0xf3,0xf3, +0xf3,0xf3,0xf2,0xf2,0xf2,0xf2,0xf2,0xf2, +0xf1,0xf1,0xf1,0xf1,0xf1,0xf0,0xf0,0xf0, +0xf0,0xf0,0xf0,0xef,0xef,0xef,0xef,0xef, +0xee,0xee,0xee,0xee,0xee,0xed,0xed,0xed, +0xed,0xed,0xec,0xec,0xec,0xec,0xec,0xeb, +0xeb,0xeb,0xeb,0xeb,0xea,0xea,0xea,0xea, +0xea,0xe9,0xe9,0xe9,0xe9,0xe8,0xe8,0xe8, +0xe8,0xe8,0xe7,0xe7,0xe7,0xe7,0xe6,0xe6, +0xe6,0xe6,0xe5,0xe5,0xe5,0xe5,0xe4,0xe4, +0xe4,0xe4,0xe4,0xe3,0xe3,0xe3,0xe3,0xe2, +0xe2,0xe2,0xe2,0xe1,0xe1,0xe1,0xe1,0xe0, +0xe0,0xe0,0xe0,0xdf,0xdf,0xdf,0xde,0xde, +0xde,0xde,0xdd,0xdd,0xdd,0xdd,0xdc,0xdc, +0xdc,0xdc,0xdb,0xdb,0xdb,0xda,0xda,0xda, +0xda,0xd9,0xd9,0xd9,0xd9,0xd8,0xd8,0xd8, +0xd7,0xd7,0xd7,0xd7,0xd6,0xd6,0xd6,0xd5, +0xd5,0xd5,0xd5,0xd4,0xd4,0xd4,0xd3,0xd3, +0xd3,0xd2,0xd2,0xd2,0xd2,0xd1,0xd1,0xd1, +0xd0,0xd0,0xd0,0xcf,0xcf,0xcf,0xcf,0xce, +0xce,0xce,0xcd,0xcd,0xcd,0xcc,0xcc,0xcc, +0xcb,0xcb,0xcb,0xcb,0xca,0xca,0xca,0xc9, +0xc9,0xc9,0xc8,0xc8,0xc8,0xc7,0xc7,0xc7, +0xc6,0xc6,0xc6,0xc5,0xc5,0xc5,0xc4,0xc4, +0xc4,0xc3,0xc3,0xc3,0xc2,0xc2,0xc2,0xc1, +0xc1,0xc1,0xc0,0xc0,0xc0,0xbf,0xbf,0xbf, +0xbe,0xbe,0xbe,0xbd,0xbd,0xbd,0xbc,0xbc, +0xbc,0xbb,0xbb,0xbb,0xba,0xba,0xba,0xb9, +0xb9,0xb8,0xb8,0xb8,0xb7,0xb7,0xb7,0xb6, +0xb6,0xb6,0xb5,0xb5,0xb5,0xb4,0xb4,0xb4, +0xb3,0xb3,0xb2,0xb2,0xb2,0xb1,0xb1,0xb1, +0xb0,0xb0,0xb0,0xaf,0xaf,0xae,0xae,0xae, +0xad,0xad,0xad,0xac,0xac,0xac,0xab,0xab, +0xaa,0xaa,0xaa,0xa9,0xa9,0xa9,0xa8,0xa8, +0xa7,0xa7,0xa7,0xa6,0xa6,0xa6,0xa5,0xa5, +0xa5,0xa4,0xa4,0xa3,0xa3,0xa3,0xa2,0xa2, +0xa2,0xa1,0xa1,0xa0,0xa0,0xa0,0x9f,0x9f, +0x9e,0x9e,0x9e,0x9d,0x9d,0x9d,0x9c,0x9c, +0x9b,0x9b,0x9b,0x9a,0x9a,0x9a,0x99,0x99, +0x98,0x98,0x98,0x97,0x97,0x96,0x96,0x96, +0x95,0x95,0x95,0x94,0x94,0x93,0x93,0x93, +0x92,0x92,0x91,0x91,0x91,0x90,0x90,0x8f, +0x8f,0x8f,0x8e,0x8e,0x8e,0x8d,0x8d,0x8c, +0x8c,0x8c,0x8b,0x8b,0x8a,0x8a,0x8a,0x89, +0x89,0x88,0x88,0x88,0x87,0x87,0x87,0x86, +0x86,0x85,0x85,0x85,0x84,0x84,0x83,0x83, +0x83,0x82,0x82,0x81,0x81,0x81,0x80,0x80, +0x80,0x7f,0x7f,0x7e,0x7e,0x7e,0x7d,0x7d, +0x7c,0x7c,0x7c,0x7b,0x7b,0x7a,0x7a,0x7a, +0x79,0x79,0x78,0x78,0x78,0x77,0x77,0x77, +0x76,0x76,0x75,0x75,0x75,0x74,0x74,0x73, +0x73,0x73,0x72,0x72,0x71,0x71,0x71,0x70, +0x70,0x70,0x6f,0x6f,0x6e,0x6e,0x6e,0x6d, +0x6d,0x6c,0x6c,0x6c,0x6b,0x6b,0x6a,0x6a, +0x6a,0x69,0x69,0x69,0x68,0x68,0x67,0x67, +0x67,0x66,0x66,0x65,0x65,0x65,0x64,0x64, +0x64,0x63,0x63,0x62,0x62,0x62,0x61,0x61, +0x61,0x60,0x60,0x5f,0x5f,0x5f,0x5e,0x5e, +0x5d,0x5d,0x5d,0x5c,0x5c,0x5c,0x5b,0x5b, +0x5a,0x5a,0x5a,0x59,0x59,0x59,0x58,0x58, +0x58,0x57,0x57,0x56,0x56,0x56,0x55,0x55, +0x55,0x54,0x54,0x53,0x53,0x53,0x52,0x52, +0x52,0x51,0x51,0x51,0x50,0x50,0x4f,0x4f, +0x4f,0x4e,0x4e,0x4e,0x4d,0x4d,0x4d,0x4c, +0x4c,0x4b,0x4b,0x4b,0x4a,0x4a,0x4a,0x49, +0x49,0x49,0x48,0x48,0x48,0x47,0x47,0x47, +0x46,0x46,0x45,0x45,0x45,0x44,0x44,0x44, +0x43,0x43,0x43,0x42,0x42,0x42,0x41,0x41, +0x41,0x40,0x40,0x40,0x3f,0x3f,0x3f,0x3e, +0x3e,0x3e,0x3d,0x3d,0x3d,0x3c,0x3c,0x3c, +0x3b,0x3b,0x3b,0x3a,0x3a,0x3a,0x39,0x39, +0x39,0x38,0x38,0x38,0x37,0x37,0x37,0x36, +0x36,0x36,0x35,0x35,0x35,0x34,0x34,0x34, +0x34,0x33,0x33,0x33,0x32,0x32,0x32,0x31, +0x31,0x31,0x30,0x30,0x30,0x30,0x2f,0x2f, +0x2f,0x2e,0x2e,0x2e,0x2d,0x2d,0x2d,0x2d, +0x2c,0x2c,0x2c,0x2b,0x2b,0x2b,0x2a,0x2a, +0x2a,0x2a,0x29,0x29,0x29,0x28,0x28,0x28, +0x28,0x27,0x27,0x27,0x26,0x26,0x26,0x26, +0x25,0x25,0x25,0x25,0x24,0x24,0x24,0x23, +0x23,0x23,0x23,0x22,0x22,0x22,0x22,0x21, +0x21,0x21,0x21,0x20,0x20,0x20,0x1f,0x1f, +0x1f,0x1f,0x1e,0x1e,0x1e,0x1e,0x1d,0x1d, +0x1d,0x1d,0x1c,0x1c,0x1c,0x1c,0x1b,0x1b, +0x1b,0x1b,0x1b,0x1a,0x1a,0x1a,0x1a,0x19, +0x19,0x19,0x19,0x18,0x18,0x18,0x18,0x17, +0x17,0x17,0x17,0x17,0x16,0x16,0x16,0x16, +0x15,0x15,0x15,0x15,0x15,0x14,0x14,0x14, +0x14,0x14,0x13,0x13,0x13,0x13,0x13,0x12, +0x12,0x12,0x12,0x12,0x11,0x11,0x11,0x11, +0x11,0x10,0x10,0x10,0x10,0x10,0xf,0xf, +0xf,0xf,0xf,0xf,0xe,0xe,0xe,0xe, +0xe,0xd,0xd,0xd,0xd,0xd,0xd,0xc, +0xc,0xc,0xc,0xc,0xc,0xb,0xb,0xb, +0xb,0xb,0xb,0xa,0xa,0xa,0xa,0xa, +0xa,0xa,0x9,0x9,0x9,0x9,0x9,0x9, +0x9,0x8,0x8,0x8,0x8,0x8,0x8,0x8, +0x7,0x7,0x7,0x7,0x7,0x7,0x7,0x7, +0x6,0x6,0x6,0x6,0x6,0x6,0x6,0x6, +0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5, +0x5,0x5,0x4,0x4,0x4,0x4,0x4,0x4, +0x4,0x4,0x4,0x4,0x3,0x3,0x3,0x3, +0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3, +0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2, +0x2,0x2,0x2,0x2,0x2,0x2,0x1,0x1, +0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1, +0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1, +0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0, +0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, +0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, +0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, +0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, +0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, +0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, +0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1, +0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1, +0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1, +0x1,0x1,0x1,0x2,0x2,0x2,0x2,0x2, +0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2, +0x2,0x3,0x3,0x3,0x3,0x3,0x3,0x3, +0x3,0x3,0x3,0x3,0x3,0x4,0x4,0x4, +0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x5, +0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5, +0x5,0x6,0x6,0x6,0x6,0x6,0x6,0x6, +0x6,0x7,0x7,0x7,0x7,0x7,0x7,0x7, +0x7,0x8,0x8,0x8,0x8,0x8,0x8,0x8, +0x9,0x9,0x9,0x9,0x9,0x9,0x9,0xa, +0xa,0xa,0xa,0xa,0xa,0xa,0xb,0xb, +0xb,0xb,0xb,0xb,0xc,0xc,0xc,0xc, +0xc,0xc,0xd,0xd,0xd,0xd,0xd,0xd, +0xe,0xe,0xe,0xe,0xe,0xf,0xf,0xf, +0xf,0xf,0xf,0x10,0x10,0x10,0x10,0x10, +0x11,0x11,0x11,0x11,0x11,0x12,0x12,0x12, +0x12,0x12,0x13,0x13,0x13,0x13,0x13,0x14, +0x14,0x14,0x14,0x14,0x15,0x15,0x15,0x15, +0x15,0x16,0x16,0x16,0x16,0x17,0x17,0x17, +0x17,0x17,0x18,0x18,0x18,0x18,0x19,0x19, +0x19,0x19,0x1a,0x1a,0x1a,0x1a,0x1b,0x1b, +0x1b,0x1b,0x1b,0x1c,0x1c,0x1c,0x1c,0x1d, +0x1d,0x1d,0x1d,0x1e,0x1e,0x1e,0x1e,0x1f, +0x1f,0x1f,0x1f,0x20,0x20,0x20,0x21,0x21, +0x21,0x21,0x22,0x22,0x22,0x22,0x23,0x23, +0x23,0x23,0x24,0x24,0x24,0x25,0x25,0x25, +0x25,0x26,0x26,0x26,0x26,0x27,0x27,0x27, +0x28,0x28,0x28,0x28,0x29,0x29,0x29,0x2a, +0x2a,0x2a,0x2a,0x2b,0x2b,0x2b,0x2c,0x2c, +0x2c,0x2d,0x2d,0x2d,0x2d,0x2e,0x2e,0x2e, +0x2f,0x2f,0x2f,0x30,0x30,0x30,0x30,0x31, +0x31,0x31,0x32,0x32,0x32,0x33,0x33,0x33, +0x34,0x34,0x34,0x34,0x35,0x35,0x35,0x36, +0x36,0x36,0x37,0x37,0x37,0x38,0x38,0x38, +0x39,0x39,0x39,0x3a,0x3a,0x3a,0x3b,0x3b, +0x3b,0x3c,0x3c,0x3c,0x3d,0x3d,0x3d,0x3e, +0x3e,0x3e,0x3f,0x3f,0x3f,0x40,0x40,0x40, +0x41,0x41,0x41,0x42,0x42,0x42,0x43,0x43, +0x43,0x44,0x44,0x44,0x45,0x45,0x45,0x46, +0x46,0x47,0x47,0x47,0x48,0x48,0x48,0x49, +0x49,0x49,0x4a,0x4a,0x4a,0x4b,0x4b,0x4b, +0x4c,0x4c,0x4d,0x4d,0x4d,0x4e,0x4e,0x4e, +0x4f,0x4f,0x4f,0x50,0x50,0x51,0x51,0x51, +0x52,0x52,0x52,0x53,0x53,0x53,0x54,0x54, +0x55,0x55,0x55,0x56,0x56,0x56,0x57,0x57, +0x58,0x58,0x58,0x59,0x59,0x59,0x5a,0x5a, +0x5a,0x5b,0x5b,0x5c,0x5c,0x5c,0x5d,0x5d, +0x5d,0x5e,0x5e,0x5f,0x5f,0x5f,0x60,0x60, +0x61,0x61,0x61,0x62,0x62,0x62,0x63,0x63, +0x64,0x64,0x64,0x65,0x65,0x65,0x66,0x66, +0x67,0x67,0x67,0x68,0x68,0x69,0x69,0x69, +0x6a,0x6a,0x6a,0x6b,0x6b,0x6c,0x6c,0x6c, +0x6d,0x6d,0x6e,0x6e,0x6e,0x6f,0x6f,0x70, +0x70,0x70,0x71,0x71,0x71,0x72,0x72,0x73, +0x73,0x73,0x74,0x74,0x75,0x75,0x75,0x76, +0x76,0x77,0x77,0x77,0x78,0x78,0x78,0x79, +0x79,0x7a,0x7a,0x7a,0x7b,0x7b,0x7c,0x7c, +0x7c,0x7d,0x7d,0x7e,0x7e,0x7e,0x7f,0x7f +}; \ No newline at end of file diff --git a/quantum/musical_notes.h b/quantum/musical_notes.h deleted file mode 100644 index b08d16a6f..000000000 --- a/quantum/musical_notes.h +++ /dev/null @@ -1,217 +0,0 @@ -#ifndef MUSICAL_NOTES_H -#define MUSICAL_NOTES_H - -// Tempo Placeholder -#define TEMPO_DEFAULT 100 - - -#define SONG(notes...) { notes } - - -// Note Types -#define MUSICAL_NOTE(note, duration) {(NOTE##note), duration} -#define WHOLE_NOTE(note) MUSICAL_NOTE(note, 64) -#define HALF_NOTE(note) MUSICAL_NOTE(note, 32) -#define QUARTER_NOTE(note) MUSICAL_NOTE(note, 16) -#define EIGHTH_NOTE(note) MUSICAL_NOTE(note, 8) -#define SIXTEENTH_NOTE(note) MUSICAL_NOTE(note, 4) - -#define WHOLE_DOT_NOTE(note) MUSICAL_NOTE(note, 64+32) -#define HALF_DOT_NOTE(note) MUSICAL_NOTE(note, 32+16) -#define QUARTER_DOT_NOTE(note) MUSICAL_NOTE(note, 16+8) -#define EIGHTH_DOT_NOTE(note) MUSICAL_NOTE(note, 8+4) -#define SIXTEENTH_DOT_NOTE(note) MUSICAL_NOTE(note, 4+2) - -// Note Type Shortcuts -#define M__NOTE(note, duration) MUSICAL_NOTE(note, duration) -#define W__NOTE(n) WHOLE_NOTE(n) -#define H__NOTE(n) HALF_NOTE(n) -#define Q__NOTE(n) QUARTER_NOTE(n) -#define E__NOTE(n) EIGHTH_NOTE(n) -#define S__NOTE(n) SIXTEENTH_NOTE(n) -#define WD_NOTE(n) WHOLE_DOT_NOTE(n) -#define HD_NOTE(n) HALF_DOT_NOTE(n) -#define QD_NOTE(n) QUARTER_DOT_NOTE(n) -#define ED_NOTE(n) EIGHTH_DOT_NOTE(n) -#define SD_NOTE(n) SIXTEENTH_DOT_NOTE(n) - -// Note Styles -// Staccato makes sure there is a rest between each note. Think: TA TA TA -// Legato makes notes flow together. Think: TAAA -#define STACCATO 0.01 -#define LEGATO 0 - -// Note Timbre -// Changes how the notes sound -#define TIMBRE_12 0.125 -#define TIMBRE_25 0.250 -#define TIMBRE_50 0.500 -#define TIMBRE_75 0.750 -#define TIMBRE_DEFAULT TIMBRE_50 - - -// Notes - # = Octave - -#define NOTE_REST 0.00 - -/* These notes are currently bugged -#define NOTE_C0 16.35 -#define NOTE_CS0 17.32 -#define NOTE_D0 18.35 -#define NOTE_DS0 19.45 -#define NOTE_E0 20.60 -#define NOTE_F0 21.83 -#define NOTE_FS0 23.12 -#define NOTE_G0 24.50 -#define NOTE_GS0 25.96 -#define NOTE_A0 27.50 -#define NOTE_AS0 29.14 -#define NOTE_B0 30.87 -#define NOTE_C1 32.70 -#define NOTE_CS1 34.65 -#define NOTE_D1 36.71 -#define NOTE_DS1 38.89 -#define NOTE_E1 41.20 -#define NOTE_F1 43.65 -#define NOTE_FS1 46.25 -#define NOTE_G1 49.00 -#define NOTE_GS1 51.91 -#define NOTE_A1 55.00 -#define NOTE_AS1 58.27 -*/ - -#define NOTE_B1 61.74 -#define NOTE_C2 65.41 -#define NOTE_CS2 69.30 -#define NOTE_D2 73.42 -#define NOTE_DS2 77.78 -#define NOTE_E2 82.41 -#define NOTE_F2 87.31 -#define NOTE_FS2 92.50 -#define NOTE_G2 98.00 -#define NOTE_GS2 103.83 -#define NOTE_A2 110.00 -#define NOTE_AS2 116.54 -#define NOTE_B2 123.47 -#define NOTE_C3 130.81 -#define NOTE_CS3 138.59 -#define NOTE_D3 146.83 -#define NOTE_DS3 155.56 -#define NOTE_E3 164.81 -#define NOTE_F3 174.61 -#define NOTE_FS3 185.00 -#define NOTE_G3 196.00 -#define NOTE_GS3 207.65 -#define NOTE_A3 220.00 -#define NOTE_AS3 233.08 -#define NOTE_B3 246.94 -#define NOTE_C4 261.63 -#define NOTE_CS4 277.18 -#define NOTE_D4 293.66 -#define NOTE_DS4 311.13 -#define NOTE_E4 329.63 -#define NOTE_F4 349.23 -#define NOTE_FS4 369.99 -#define NOTE_G4 392.00 -#define NOTE_GS4 415.30 -#define NOTE_A4 440.00 -#define NOTE_AS4 466.16 -#define NOTE_B4 493.88 -#define NOTE_C5 523.25 -#define NOTE_CS5 554.37 -#define NOTE_D5 587.33 -#define NOTE_DS5 622.25 -#define NOTE_E5 659.26 -#define NOTE_F5 698.46 -#define NOTE_FS5 739.99 -#define NOTE_G5 783.99 -#define NOTE_GS5 830.61 -#define NOTE_A5 880.00 -#define NOTE_AS5 932.33 -#define NOTE_B5 987.77 -#define NOTE_C6 1046.50 -#define NOTE_CS6 1108.73 -#define NOTE_D6 1174.66 -#define NOTE_DS6 1244.51 -#define NOTE_E6 1318.51 -#define NOTE_F6 1396.91 -#define NOTE_FS6 1479.98 -#define NOTE_G6 1567.98 -#define NOTE_GS6 1661.22 -#define NOTE_A6 1760.00 -#define NOTE_AS6 1864.66 -#define NOTE_B6 1975.53 -#define NOTE_C7 2093.00 -#define NOTE_CS7 2217.46 -#define NOTE_D7 2349.32 -#define NOTE_DS7 2489.02 -#define NOTE_E7 2637.02 -#define NOTE_F7 2793.83 -#define NOTE_FS7 2959.96 -#define NOTE_G7 3135.96 -#define NOTE_GS7 3322.44 -#define NOTE_A7 3520.00 -#define NOTE_AS7 3729.31 -#define NOTE_B7 3951.07 -#define NOTE_C8 4186.01 -#define NOTE_CS8 4434.92 -#define NOTE_D8 4698.64 -#define NOTE_DS8 4978.03 -#define NOTE_E8 5274.04 -#define NOTE_F8 5587.65 -#define NOTE_FS8 5919.91 -#define NOTE_G8 6271.93 -#define NOTE_GS8 6644.88 -#define NOTE_A8 7040.00 -#define NOTE_AS8 7458.62 -#define NOTE_B8 7902.13 - -// Flat Aliases -#define NOTE_DF0 NOTE_CS0 -#define NOTE_EF0 NOTE_DS0 -#define NOTE_GF0 NOTE_FS0 -#define NOTE_AF0 NOTE_GS0 -#define NOTE_BF0 NOTE_AS0 -#define NOTE_DF1 NOTE_CS1 -#define NOTE_EF1 NOTE_DS1 -#define NOTE_GF1 NOTE_FS1 -#define NOTE_AF1 NOTE_GS1 -#define NOTE_BF1 NOTE_AS1 -#define NOTE_DF2 NOTE_CS2 -#define NOTE_EF2 NOTE_DS2 -#define NOTE_GF2 NOTE_FS2 -#define NOTE_AF2 NOTE_GS2 -#define NOTE_BF2 NOTE_AS2 -#define NOTE_DF3 NOTE_CS3 -#define NOTE_EF3 NOTE_DS3 -#define NOTE_GF3 NOTE_FS3 -#define NOTE_AF3 NOTE_GS3 -#define NOTE_BF3 NOTE_AS3 -#define NOTE_DF4 NOTE_CS4 -#define NOTE_EF4 NOTE_DS4 -#define NOTE_GF4 NOTE_FS4 -#define NOTE_AF4 NOTE_GS4 -#define NOTE_BF4 NOTE_AS4 -#define NOTE_DF5 NOTE_CS5 -#define NOTE_EF5 NOTE_DS5 -#define NOTE_GF5 NOTE_FS5 -#define NOTE_AF5 NOTE_GS5 -#define NOTE_BF5 NOTE_AS5 -#define NOTE_DF6 NOTE_CS6 -#define NOTE_EF6 NOTE_DS6 -#define NOTE_GF6 NOTE_FS6 -#define NOTE_AF6 NOTE_GS6 -#define NOTE_BF6 NOTE_AS6 -#define NOTE_DF7 NOTE_CS7 -#define NOTE_EF7 NOTE_DS7 -#define NOTE_GF7 NOTE_FS7 -#define NOTE_AF7 NOTE_GS7 -#define NOTE_BF7 NOTE_AS7 -#define NOTE_DF8 NOTE_CS8 -#define NOTE_EF8 NOTE_DS8 -#define NOTE_GF8 NOTE_FS8 -#define NOTE_AF8 NOTE_GS8 -#define NOTE_BF8 NOTE_AS8 - - -#endif \ No newline at end of file diff --git a/quantum/quantum.mk b/quantum/quantum.mk index 1fe7390eb..83c4f1d1d 100644 --- a/quantum/quantum.mk +++ b/quantum/quantum.mk @@ -28,7 +28,7 @@ ifeq ($(strip $(MIDI_ENABLE)), yes) endif ifeq ($(strip $(AUDIO_ENABLE)), yes) - SRC += $(QUANTUM_DIR)/audio.c + SRC += $(QUANTUM_DIR)/audio/audio.c $(QUANTUM_DIR)/audio/voices.c endif ifeq ($(strip $(UNICODE_ENABLE)), yes) @@ -47,6 +47,7 @@ endif # Search Path VPATH += $(TOP_DIR)/$(QUANTUM_DIR) VPATH += $(TOP_DIR)/$(QUANTUM_DIR)/keymap_extras +VPATH += $(TOP_DIR)/$(QUANTUM_DIR)/audio include $(TMK_DIR)/protocol/lufa.mk diff --git a/quantum/song_list.h b/quantum/song_list.h deleted file mode 100644 index fc6fcdeef..000000000 --- a/quantum/song_list.h +++ /dev/null @@ -1,117 +0,0 @@ -#include "musical_notes.h" - -#ifndef SONG_LIST_H -#define SONG_LIST_H - -#define ODE_TO_JOY \ - Q__NOTE(_E4), Q__NOTE(_E4), Q__NOTE(_F4), Q__NOTE(_G4), \ - Q__NOTE(_G4), Q__NOTE(_F4), Q__NOTE(_E4), Q__NOTE(_D4), \ - Q__NOTE(_C4), Q__NOTE(_C4), Q__NOTE(_D4), Q__NOTE(_E4), \ - QD_NOTE(_E4), E__NOTE(_D4), H__NOTE(_D4), - -#define ROCK_A_BYE_BABY \ - QD_NOTE(_B4), E__NOTE(_D4), Q__NOTE(_B5), \ - H__NOTE(_A5), Q__NOTE(_G5), \ - QD_NOTE(_B4), E__NOTE(_D5), Q__NOTE(_G5), \ - H__NOTE(_FS5), - -#define CLOSE_ENCOUNTERS_5_NOTE \ - Q__NOTE(_D5), \ - Q__NOTE(_E5), \ - Q__NOTE(_C5), \ - Q__NOTE(_C4), \ - Q__NOTE(_G4), - -#define DOE_A_DEER \ - QD_NOTE(_C4), E__NOTE(_D4), \ - QD_NOTE(_E4), E__NOTE(_C4), \ - Q__NOTE(_E4), Q__NOTE(_C4), \ - Q__NOTE(_E4), - -#define GOODBYE_SOUND \ - E__NOTE(_E7), \ - E__NOTE(_A6), \ - ED_NOTE(_E6), - -#define STARTUP_SOUND \ - ED_NOTE(_E7 ), \ - E__NOTE(_CS7), \ - E__NOTE(_E6 ), \ - E__NOTE(_A6 ), \ - M__NOTE(_CS7, 20), - -#define QWERTY_SOUND \ - E__NOTE(_GS6 ), \ - E__NOTE(_A6 ), \ - S__NOTE(_REST), \ - Q__NOTE(_E7 ), - -#define COLEMAK_SOUND \ - E__NOTE(_GS6 ), \ - E__NOTE(_A6 ), \ - S__NOTE(_REST), \ - ED_NOTE(_E7 ), \ - S__NOTE(_REST), \ - ED_NOTE(_GS7 ), - -#define DVORAK_SOUND \ - E__NOTE(_GS6 ), \ - E__NOTE(_A6 ), \ - S__NOTE(_REST), \ - E__NOTE(_E7 ), \ - S__NOTE(_REST), \ - E__NOTE(_FS7 ), \ - S__NOTE(_REST), \ - E__NOTE(_E7 ), - -#define PLOVER_SOUND \ - E__NOTE(_GS6 ), \ - E__NOTE(_A6 ), \ - S__NOTE(_REST), \ - ED_NOTE(_E7 ), \ - S__NOTE(_REST), \ - ED_NOTE(_A7 ), - -#define PLOVER_GOODBYE_SOUND \ - E__NOTE(_GS6 ), \ - E__NOTE(_A6 ), \ - S__NOTE(_REST), \ - ED_NOTE(_A7 ), \ - S__NOTE(_REST), \ - ED_NOTE(_E7 ), - -#define MUSIC_SCALE_SOUND \ - E__NOTE(_A5 ), \ - E__NOTE(_B5 ), \ - E__NOTE(_CS6), \ - E__NOTE(_D6 ), \ - E__NOTE(_E6 ), \ - E__NOTE(_FS6), \ - E__NOTE(_GS6), \ - E__NOTE(_A6 ), - -#define CAPS_LOCK_ON_SOUND \ - E__NOTE(_A3), \ - E__NOTE(_B3), - -#define CAPS_LOCK_OFF_SOUND \ - E__NOTE(_B3), \ - E__NOTE(_A3), - -#define SCROLL_LOCK_ON_SOUND \ - E__NOTE(_D4), \ - E__NOTE(_E4), - -#define SCROLL_LOCK_OFF_SOUND \ - E__NOTE(_E4), \ - E__NOTE(_D4), - -#define NUM_LOCK_ON_SOUND \ - E__NOTE(_D5), \ - E__NOTE(_E5), - -#define NUM_LOCK_OFF_SOUND \ - E__NOTE(_E5), \ - E__NOTE(_D5), - -#endif diff --git a/quantum/vibrato_lut.h b/quantum/vibrato_lut.h deleted file mode 100644 index a2b1f3e5c..000000000 --- a/quantum/vibrato_lut.h +++ /dev/null @@ -1,28 +0,0 @@ -#include -#include -#include - -#define VIBRATO_LUT_LENGTH 20 - -const float VIBRATO_LUT[VIBRATO_LUT_LENGTH] = { \ -1.00223368114872, -1.00425299436105, -1.00585842560279, -1.00689052852052, -1.0072464122237, -1.00689052852052, -1.00585842560279, -1.00425299436105, -1.00223368114872, -1, -0.99777129706302, -0.99576501699778, -0.994175695650927, -0.993156625943589, -0.992805720491269, -0.993156625943589, -0.994175695650927, -0.99576501699778, -0.99777129706302, -1 -}; \ No newline at end of file diff --git a/quantum/wave.h b/quantum/wave.h deleted file mode 100644 index 6ebc34851..000000000 --- a/quantum/wave.h +++ /dev/null @@ -1,265 +0,0 @@ -#include -#include -#include - -#define SINE_LENGTH 2048 - -const uint8_t sinewave[] PROGMEM= //2048 values -{ -0x80,0x80,0x80,0x81,0x81,0x81,0x82,0x82, -0x83,0x83,0x83,0x84,0x84,0x85,0x85,0x85, -0x86,0x86,0x87,0x87,0x87,0x88,0x88,0x88, -0x89,0x89,0x8a,0x8a,0x8a,0x8b,0x8b,0x8c, -0x8c,0x8c,0x8d,0x8d,0x8e,0x8e,0x8e,0x8f, -0x8f,0x8f,0x90,0x90,0x91,0x91,0x91,0x92, -0x92,0x93,0x93,0x93,0x94,0x94,0x95,0x95, -0x95,0x96,0x96,0x96,0x97,0x97,0x98,0x98, -0x98,0x99,0x99,0x9a,0x9a,0x9a,0x9b,0x9b, -0x9b,0x9c,0x9c,0x9d,0x9d,0x9d,0x9e,0x9e, -0x9e,0x9f,0x9f,0xa0,0xa0,0xa0,0xa1,0xa1, -0xa2,0xa2,0xa2,0xa3,0xa3,0xa3,0xa4,0xa4, -0xa5,0xa5,0xa5,0xa6,0xa6,0xa6,0xa7,0xa7, -0xa7,0xa8,0xa8,0xa9,0xa9,0xa9,0xaa,0xaa, -0xaa,0xab,0xab,0xac,0xac,0xac,0xad,0xad, -0xad,0xae,0xae,0xae,0xaf,0xaf,0xb0,0xb0, -0xb0,0xb1,0xb1,0xb1,0xb2,0xb2,0xb2,0xb3, -0xb3,0xb4,0xb4,0xb4,0xb5,0xb5,0xb5,0xb6, -0xb6,0xb6,0xb7,0xb7,0xb7,0xb8,0xb8,0xb8, -0xb9,0xb9,0xba,0xba,0xba,0xbb,0xbb,0xbb, -0xbc,0xbc,0xbc,0xbd,0xbd,0xbd,0xbe,0xbe, -0xbe,0xbf,0xbf,0xbf,0xc0,0xc0,0xc0,0xc1, -0xc1,0xc1,0xc2,0xc2,0xc2,0xc3,0xc3,0xc3, -0xc4,0xc4,0xc4,0xc5,0xc5,0xc5,0xc6,0xc6, -0xc6,0xc7,0xc7,0xc7,0xc8,0xc8,0xc8,0xc9, -0xc9,0xc9,0xca,0xca,0xca,0xcb,0xcb,0xcb, -0xcb,0xcc,0xcc,0xcc,0xcd,0xcd,0xcd,0xce, -0xce,0xce,0xcf,0xcf,0xcf,0xcf,0xd0,0xd0, -0xd0,0xd1,0xd1,0xd1,0xd2,0xd2,0xd2,0xd2, -0xd3,0xd3,0xd3,0xd4,0xd4,0xd4,0xd5,0xd5, -0xd5,0xd5,0xd6,0xd6,0xd6,0xd7,0xd7,0xd7, -0xd7,0xd8,0xd8,0xd8,0xd9,0xd9,0xd9,0xd9, -0xda,0xda,0xda,0xda,0xdb,0xdb,0xdb,0xdc, -0xdc,0xdc,0xdc,0xdd,0xdd,0xdd,0xdd,0xde, -0xde,0xde,0xde,0xdf,0xdf,0xdf,0xe0,0xe0, -0xe0,0xe0,0xe1,0xe1,0xe1,0xe1,0xe2,0xe2, -0xe2,0xe2,0xe3,0xe3,0xe3,0xe3,0xe4,0xe4, -0xe4,0xe4,0xe4,0xe5,0xe5,0xe5,0xe5,0xe6, -0xe6,0xe6,0xe6,0xe7,0xe7,0xe7,0xe7,0xe8, -0xe8,0xe8,0xe8,0xe8,0xe9,0xe9,0xe9,0xe9, -0xea,0xea,0xea,0xea,0xea,0xeb,0xeb,0xeb, -0xeb,0xeb,0xec,0xec,0xec,0xec,0xec,0xed, -0xed,0xed,0xed,0xed,0xee,0xee,0xee,0xee, -0xee,0xef,0xef,0xef,0xef,0xef,0xf0,0xf0, -0xf0,0xf0,0xf0,0xf0,0xf1,0xf1,0xf1,0xf1, -0xf1,0xf2,0xf2,0xf2,0xf2,0xf2,0xf2,0xf3, -0xf3,0xf3,0xf3,0xf3,0xf3,0xf4,0xf4,0xf4, -0xf4,0xf4,0xf4,0xf5,0xf5,0xf5,0xf5,0xf5, -0xf5,0xf5,0xf6,0xf6,0xf6,0xf6,0xf6,0xf6, -0xf6,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7, -0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8, -0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9, -0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa, -0xfa,0xfa,0xfb,0xfb,0xfb,0xfb,0xfb,0xfb, -0xfb,0xfb,0xfb,0xfb,0xfc,0xfc,0xfc,0xfc, -0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc, -0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd, -0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfe,0xfe, -0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe, -0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe, -0xfe,0xfe,0xfe,0xfe,0xff,0xff,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfe, -0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe, -0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe, -0xfe,0xfe,0xfe,0xfd,0xfd,0xfd,0xfd,0xfd, -0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd, -0xfd,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc, -0xfc,0xfc,0xfc,0xfc,0xfc,0xfb,0xfb,0xfb, -0xfb,0xfb,0xfb,0xfb,0xfb,0xfb,0xfb,0xfa, -0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa, -0xfa,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9, -0xf9,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8, -0xf8,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7, -0xf6,0xf6,0xf6,0xf6,0xf6,0xf6,0xf6,0xf5, -0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf4,0xf4, -0xf4,0xf4,0xf4,0xf4,0xf3,0xf3,0xf3,0xf3, -0xf3,0xf3,0xf2,0xf2,0xf2,0xf2,0xf2,0xf2, -0xf1,0xf1,0xf1,0xf1,0xf1,0xf0,0xf0,0xf0, -0xf0,0xf0,0xf0,0xef,0xef,0xef,0xef,0xef, -0xee,0xee,0xee,0xee,0xee,0xed,0xed,0xed, -0xed,0xed,0xec,0xec,0xec,0xec,0xec,0xeb, -0xeb,0xeb,0xeb,0xeb,0xea,0xea,0xea,0xea, -0xea,0xe9,0xe9,0xe9,0xe9,0xe8,0xe8,0xe8, -0xe8,0xe8,0xe7,0xe7,0xe7,0xe7,0xe6,0xe6, -0xe6,0xe6,0xe5,0xe5,0xe5,0xe5,0xe4,0xe4, -0xe4,0xe4,0xe4,0xe3,0xe3,0xe3,0xe3,0xe2, -0xe2,0xe2,0xe2,0xe1,0xe1,0xe1,0xe1,0xe0, -0xe0,0xe0,0xe0,0xdf,0xdf,0xdf,0xde,0xde, -0xde,0xde,0xdd,0xdd,0xdd,0xdd,0xdc,0xdc, -0xdc,0xdc,0xdb,0xdb,0xdb,0xda,0xda,0xda, -0xda,0xd9,0xd9,0xd9,0xd9,0xd8,0xd8,0xd8, -0xd7,0xd7,0xd7,0xd7,0xd6,0xd6,0xd6,0xd5, -0xd5,0xd5,0xd5,0xd4,0xd4,0xd4,0xd3,0xd3, -0xd3,0xd2,0xd2,0xd2,0xd2,0xd1,0xd1,0xd1, -0xd0,0xd0,0xd0,0xcf,0xcf,0xcf,0xcf,0xce, -0xce,0xce,0xcd,0xcd,0xcd,0xcc,0xcc,0xcc, -0xcb,0xcb,0xcb,0xcb,0xca,0xca,0xca,0xc9, -0xc9,0xc9,0xc8,0xc8,0xc8,0xc7,0xc7,0xc7, -0xc6,0xc6,0xc6,0xc5,0xc5,0xc5,0xc4,0xc4, -0xc4,0xc3,0xc3,0xc3,0xc2,0xc2,0xc2,0xc1, -0xc1,0xc1,0xc0,0xc0,0xc0,0xbf,0xbf,0xbf, -0xbe,0xbe,0xbe,0xbd,0xbd,0xbd,0xbc,0xbc, -0xbc,0xbb,0xbb,0xbb,0xba,0xba,0xba,0xb9, -0xb9,0xb8,0xb8,0xb8,0xb7,0xb7,0xb7,0xb6, -0xb6,0xb6,0xb5,0xb5,0xb5,0xb4,0xb4,0xb4, -0xb3,0xb3,0xb2,0xb2,0xb2,0xb1,0xb1,0xb1, -0xb0,0xb0,0xb0,0xaf,0xaf,0xae,0xae,0xae, -0xad,0xad,0xad,0xac,0xac,0xac,0xab,0xab, -0xaa,0xaa,0xaa,0xa9,0xa9,0xa9,0xa8,0xa8, -0xa7,0xa7,0xa7,0xa6,0xa6,0xa6,0xa5,0xa5, -0xa5,0xa4,0xa4,0xa3,0xa3,0xa3,0xa2,0xa2, -0xa2,0xa1,0xa1,0xa0,0xa0,0xa0,0x9f,0x9f, -0x9e,0x9e,0x9e,0x9d,0x9d,0x9d,0x9c,0x9c, -0x9b,0x9b,0x9b,0x9a,0x9a,0x9a,0x99,0x99, -0x98,0x98,0x98,0x97,0x97,0x96,0x96,0x96, -0x95,0x95,0x95,0x94,0x94,0x93,0x93,0x93, -0x92,0x92,0x91,0x91,0x91,0x90,0x90,0x8f, -0x8f,0x8f,0x8e,0x8e,0x8e,0x8d,0x8d,0x8c, -0x8c,0x8c,0x8b,0x8b,0x8a,0x8a,0x8a,0x89, -0x89,0x88,0x88,0x88,0x87,0x87,0x87,0x86, -0x86,0x85,0x85,0x85,0x84,0x84,0x83,0x83, -0x83,0x82,0x82,0x81,0x81,0x81,0x80,0x80, -0x80,0x7f,0x7f,0x7e,0x7e,0x7e,0x7d,0x7d, -0x7c,0x7c,0x7c,0x7b,0x7b,0x7a,0x7a,0x7a, -0x79,0x79,0x78,0x78,0x78,0x77,0x77,0x77, -0x76,0x76,0x75,0x75,0x75,0x74,0x74,0x73, -0x73,0x73,0x72,0x72,0x71,0x71,0x71,0x70, -0x70,0x70,0x6f,0x6f,0x6e,0x6e,0x6e,0x6d, -0x6d,0x6c,0x6c,0x6c,0x6b,0x6b,0x6a,0x6a, -0x6a,0x69,0x69,0x69,0x68,0x68,0x67,0x67, -0x67,0x66,0x66,0x65,0x65,0x65,0x64,0x64, -0x64,0x63,0x63,0x62,0x62,0x62,0x61,0x61, -0x61,0x60,0x60,0x5f,0x5f,0x5f,0x5e,0x5e, -0x5d,0x5d,0x5d,0x5c,0x5c,0x5c,0x5b,0x5b, -0x5a,0x5a,0x5a,0x59,0x59,0x59,0x58,0x58, -0x58,0x57,0x57,0x56,0x56,0x56,0x55,0x55, -0x55,0x54,0x54,0x53,0x53,0x53,0x52,0x52, -0x52,0x51,0x51,0x51,0x50,0x50,0x4f,0x4f, -0x4f,0x4e,0x4e,0x4e,0x4d,0x4d,0x4d,0x4c, -0x4c,0x4b,0x4b,0x4b,0x4a,0x4a,0x4a,0x49, -0x49,0x49,0x48,0x48,0x48,0x47,0x47,0x47, -0x46,0x46,0x45,0x45,0x45,0x44,0x44,0x44, -0x43,0x43,0x43,0x42,0x42,0x42,0x41,0x41, -0x41,0x40,0x40,0x40,0x3f,0x3f,0x3f,0x3e, -0x3e,0x3e,0x3d,0x3d,0x3d,0x3c,0x3c,0x3c, -0x3b,0x3b,0x3b,0x3a,0x3a,0x3a,0x39,0x39, -0x39,0x38,0x38,0x38,0x37,0x37,0x37,0x36, -0x36,0x36,0x35,0x35,0x35,0x34,0x34,0x34, -0x34,0x33,0x33,0x33,0x32,0x32,0x32,0x31, -0x31,0x31,0x30,0x30,0x30,0x30,0x2f,0x2f, -0x2f,0x2e,0x2e,0x2e,0x2d,0x2d,0x2d,0x2d, -0x2c,0x2c,0x2c,0x2b,0x2b,0x2b,0x2a,0x2a, -0x2a,0x2a,0x29,0x29,0x29,0x28,0x28,0x28, -0x28,0x27,0x27,0x27,0x26,0x26,0x26,0x26, -0x25,0x25,0x25,0x25,0x24,0x24,0x24,0x23, -0x23,0x23,0x23,0x22,0x22,0x22,0x22,0x21, -0x21,0x21,0x21,0x20,0x20,0x20,0x1f,0x1f, -0x1f,0x1f,0x1e,0x1e,0x1e,0x1e,0x1d,0x1d, -0x1d,0x1d,0x1c,0x1c,0x1c,0x1c,0x1b,0x1b, -0x1b,0x1b,0x1b,0x1a,0x1a,0x1a,0x1a,0x19, -0x19,0x19,0x19,0x18,0x18,0x18,0x18,0x17, -0x17,0x17,0x17,0x17,0x16,0x16,0x16,0x16, -0x15,0x15,0x15,0x15,0x15,0x14,0x14,0x14, -0x14,0x14,0x13,0x13,0x13,0x13,0x13,0x12, -0x12,0x12,0x12,0x12,0x11,0x11,0x11,0x11, -0x11,0x10,0x10,0x10,0x10,0x10,0xf,0xf, -0xf,0xf,0xf,0xf,0xe,0xe,0xe,0xe, -0xe,0xd,0xd,0xd,0xd,0xd,0xd,0xc, -0xc,0xc,0xc,0xc,0xc,0xb,0xb,0xb, -0xb,0xb,0xb,0xa,0xa,0xa,0xa,0xa, -0xa,0xa,0x9,0x9,0x9,0x9,0x9,0x9, -0x9,0x8,0x8,0x8,0x8,0x8,0x8,0x8, -0x7,0x7,0x7,0x7,0x7,0x7,0x7,0x7, -0x6,0x6,0x6,0x6,0x6,0x6,0x6,0x6, -0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5, -0x5,0x5,0x4,0x4,0x4,0x4,0x4,0x4, -0x4,0x4,0x4,0x4,0x3,0x3,0x3,0x3, -0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3, -0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2, -0x2,0x2,0x2,0x2,0x2,0x2,0x1,0x1, -0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1, -0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1, -0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0, -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, -0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1, -0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1, -0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1, -0x1,0x1,0x1,0x2,0x2,0x2,0x2,0x2, -0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2, -0x2,0x3,0x3,0x3,0x3,0x3,0x3,0x3, -0x3,0x3,0x3,0x3,0x3,0x4,0x4,0x4, -0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x5, -0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5, -0x5,0x6,0x6,0x6,0x6,0x6,0x6,0x6, -0x6,0x7,0x7,0x7,0x7,0x7,0x7,0x7, -0x7,0x8,0x8,0x8,0x8,0x8,0x8,0x8, -0x9,0x9,0x9,0x9,0x9,0x9,0x9,0xa, -0xa,0xa,0xa,0xa,0xa,0xa,0xb,0xb, -0xb,0xb,0xb,0xb,0xc,0xc,0xc,0xc, -0xc,0xc,0xd,0xd,0xd,0xd,0xd,0xd, -0xe,0xe,0xe,0xe,0xe,0xf,0xf,0xf, -0xf,0xf,0xf,0x10,0x10,0x10,0x10,0x10, -0x11,0x11,0x11,0x11,0x11,0x12,0x12,0x12, -0x12,0x12,0x13,0x13,0x13,0x13,0x13,0x14, -0x14,0x14,0x14,0x14,0x15,0x15,0x15,0x15, -0x15,0x16,0x16,0x16,0x16,0x17,0x17,0x17, -0x17,0x17,0x18,0x18,0x18,0x18,0x19,0x19, -0x19,0x19,0x1a,0x1a,0x1a,0x1a,0x1b,0x1b, -0x1b,0x1b,0x1b,0x1c,0x1c,0x1c,0x1c,0x1d, -0x1d,0x1d,0x1d,0x1e,0x1e,0x1e,0x1e,0x1f, -0x1f,0x1f,0x1f,0x20,0x20,0x20,0x21,0x21, -0x21,0x21,0x22,0x22,0x22,0x22,0x23,0x23, -0x23,0x23,0x24,0x24,0x24,0x25,0x25,0x25, -0x25,0x26,0x26,0x26,0x26,0x27,0x27,0x27, -0x28,0x28,0x28,0x28,0x29,0x29,0x29,0x2a, -0x2a,0x2a,0x2a,0x2b,0x2b,0x2b,0x2c,0x2c, -0x2c,0x2d,0x2d,0x2d,0x2d,0x2e,0x2e,0x2e, -0x2f,0x2f,0x2f,0x30,0x30,0x30,0x30,0x31, -0x31,0x31,0x32,0x32,0x32,0x33,0x33,0x33, -0x34,0x34,0x34,0x34,0x35,0x35,0x35,0x36, -0x36,0x36,0x37,0x37,0x37,0x38,0x38,0x38, -0x39,0x39,0x39,0x3a,0x3a,0x3a,0x3b,0x3b, -0x3b,0x3c,0x3c,0x3c,0x3d,0x3d,0x3d,0x3e, -0x3e,0x3e,0x3f,0x3f,0x3f,0x40,0x40,0x40, -0x41,0x41,0x41,0x42,0x42,0x42,0x43,0x43, -0x43,0x44,0x44,0x44,0x45,0x45,0x45,0x46, -0x46,0x47,0x47,0x47,0x48,0x48,0x48,0x49, -0x49,0x49,0x4a,0x4a,0x4a,0x4b,0x4b,0x4b, -0x4c,0x4c,0x4d,0x4d,0x4d,0x4e,0x4e,0x4e, -0x4f,0x4f,0x4f,0x50,0x50,0x51,0x51,0x51, -0x52,0x52,0x52,0x53,0x53,0x53,0x54,0x54, -0x55,0x55,0x55,0x56,0x56,0x56,0x57,0x57, -0x58,0x58,0x58,0x59,0x59,0x59,0x5a,0x5a, -0x5a,0x5b,0x5b,0x5c,0x5c,0x5c,0x5d,0x5d, -0x5d,0x5e,0x5e,0x5f,0x5f,0x5f,0x60,0x60, -0x61,0x61,0x61,0x62,0x62,0x62,0x63,0x63, -0x64,0x64,0x64,0x65,0x65,0x65,0x66,0x66, -0x67,0x67,0x67,0x68,0x68,0x69,0x69,0x69, -0x6a,0x6a,0x6a,0x6b,0x6b,0x6c,0x6c,0x6c, -0x6d,0x6d,0x6e,0x6e,0x6e,0x6f,0x6f,0x70, -0x70,0x70,0x71,0x71,0x71,0x72,0x72,0x73, -0x73,0x73,0x74,0x74,0x75,0x75,0x75,0x76, -0x76,0x77,0x77,0x77,0x78,0x78,0x78,0x79, -0x79,0x7a,0x7a,0x7a,0x7b,0x7b,0x7c,0x7c, -0x7c,0x7d,0x7d,0x7e,0x7e,0x7e,0x7f,0x7f -}; \ No newline at end of file -- cgit v1.2.3-24-g4f1b From e89b806b850ad1b5484176664288b71b0131683e Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Thu, 21 Apr 2016 00:40:00 -0400 Subject: converts tabs to spaces --- quantum/audio/voices.c | 88 +++++++++++++++++++++++++------------------------- quantum/audio/voices.h | 6 ++-- 2 files changed, 47 insertions(+), 47 deletions(-) (limited to 'quantum') diff --git a/quantum/audio/voices.c b/quantum/audio/voices.c index 30e8be641..51652927b 100644 --- a/quantum/audio/voices.c +++ b/quantum/audio/voices.c @@ -6,55 +6,55 @@ extern float note_timbre; voice_type voice = default_voice; void set_voice(voice_type v) { - voice = v; + voice = v; } float voice_envelope(float frequency) { - // envelope_index ranges from 0 to 0xFFFF, which is preserved at 880.0 Hz + // envelope_index ranges from 0 to 0xFFFF, which is preserved at 880.0 Hz uint16_t compensated_index = (uint16_t)((float)envelope_index * (880.0 / frequency)); switch (voice) { - case default_voice: - // nothing here on purpose - break; - case butts_fader: - switch (compensated_index) { - case 0 ... 9: - frequency = frequency / 4; - note_timbre = TIMBRE_12; - break; - case 10 ... 19: - frequency = frequency / 2; - note_timbre = TIMBRE_12; - break; - case 20 ... 200: - note_timbre = .125 - pow(((float)compensated_index - 20) / (200 - 20), 2)*.125; - break; - default: - note_timbre = 0; - break; - } - break; - case octave_crunch: - switch (compensated_index) { - case 0 ... 9: - case 20 ... 24: - case 30 ... 32: - frequency = frequency / 2; - note_timbre = TIMBRE_12; - break; - case 10 ... 19: - case 25 ... 29: - case 33 ... 35: - frequency = frequency * 2; - note_timbre = TIMBRE_12; - break; - default: - note_timbre = TIMBRE_12; - break; - } - break; - } + case default_voice: + // nothing here on purpose + break; + case butts_fader: + switch (compensated_index) { + case 0 ... 9: + frequency = frequency / 4; + note_timbre = TIMBRE_12; + break; + case 10 ... 19: + frequency = frequency / 2; + note_timbre = TIMBRE_12; + break; + case 20 ... 200: + note_timbre = .125 - pow(((float)compensated_index - 20) / (200 - 20), 2)*.125; + break; + default: + note_timbre = 0; + break; + } + break; + case octave_crunch: + switch (compensated_index) { + case 0 ... 9: + case 20 ... 24: + case 30 ... 32: + frequency = frequency / 2; + note_timbre = TIMBRE_12; + break; + case 10 ... 19: + case 25 ... 29: + case 33 ... 35: + frequency = frequency * 2; + note_timbre = TIMBRE_12; + break; + default: + note_timbre = TIMBRE_12; + break; + } + break; + } - return frequency; + return frequency; } \ No newline at end of file diff --git a/quantum/audio/voices.h b/quantum/audio/voices.h index 32135dac7..317f5d98c 100644 --- a/quantum/audio/voices.h +++ b/quantum/audio/voices.h @@ -11,9 +11,9 @@ float voice_envelope(float frequency); typedef enum { - default_voice, - butts_fader, - octave_crunch + default_voice, + butts_fader, + octave_crunch } voice_type; void set_voice(voice_type v); -- cgit v1.2.3-24-g4f1b From 9828aba2a12f03fccbc1095bc8e4918ae58fa31b Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Thu, 21 Apr 2016 18:14:25 -0400 Subject: adds multiple voices and the ability to iterate/deiterate between them --- quantum/audio/voices.c | 31 +++++++++++++++++++++++++++++-- quantum/audio/voices.h | 6 +++++- 2 files changed, 34 insertions(+), 3 deletions(-) (limited to 'quantum') diff --git a/quantum/audio/voices.c b/quantum/audio/voices.c index 51652927b..92ada47f7 100644 --- a/quantum/audio/voices.c +++ b/quantum/audio/voices.c @@ -1,23 +1,35 @@ #include "voices.h" +// these are imported from audio.c extern uint16_t envelope_index; extern float note_timbre; +extern float polyphony_rate; -voice_type voice = default_voice; +voice_type voice = duty_osc; void set_voice(voice_type v) { voice = v; } +void voice_iterate() { + voice = (voice + 1) % number_of_voices; +} + +void voice_deiterate() { + voice = (voice - 1) % number_of_voices; +} + float voice_envelope(float frequency) { // envelope_index ranges from 0 to 0xFFFF, which is preserved at 880.0 Hz uint16_t compensated_index = (uint16_t)((float)envelope_index * (880.0 / frequency)); switch (voice) { case default_voice: - // nothing here on purpose + note_timbre = TIMBRE_50; + polyphony_rate = 0; break; case butts_fader: + polyphony_rate = 0; switch (compensated_index) { case 0 ... 9: frequency = frequency / 4; @@ -36,6 +48,7 @@ float voice_envelope(float frequency) { } break; case octave_crunch: + polyphony_rate = 0; switch (compensated_index) { case 0 ... 9: case 20 ... 24: @@ -54,6 +67,20 @@ float voice_envelope(float frequency) { break; } break; + case duty_osc: + // This slows the loop down a substantial amount, so higher notes may freeze + polyphony_rate = 0; + switch (compensated_index) { + default: + #define SPEED 10 + #define AMP .75 + // sine wave is slow + // note_timbre = (sin((float)compensated_index/10000*SPEED) * AMP / 2) + .5; + // triangle wave is a bit faster + note_timbre = (float)abs((compensated_index*SPEED % 3000) - 1500) * ( AMP / 1500 ) + (1 - AMP) / 2; + break; + } + break; } return frequency; diff --git a/quantum/audio/voices.h b/quantum/audio/voices.h index 317f5d98c..44c5066b5 100644 --- a/quantum/audio/voices.h +++ b/quantum/audio/voices.h @@ -13,9 +13,13 @@ float voice_envelope(float frequency); typedef enum { default_voice, butts_fader, - octave_crunch + octave_crunch, + duty_osc, + number_of_voices // important that this is last } voice_type; void set_voice(voice_type v); +void voice_iterate(); +void voice_deiterate(); #endif \ No newline at end of file -- cgit v1.2.3-24-g4f1b From 620ac4b260fa663d12b11a0b15ac50379523c125 Mon Sep 17 00:00:00 2001 From: Eric Tang Date: Thu, 21 Apr 2016 19:35:18 -0700 Subject: Update functions used to write to EEPROM --- quantum/audio/audio.c | 6 +++--- quantum/keymap_common.c | 2 +- quantum/rgblight.c | 20 ++++++++++---------- quantum/rgblight.h | 4 ++-- 4 files changed, 16 insertions(+), 16 deletions(-) (limited to 'quantum') diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index 3225557ba..e85370d95 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -85,17 +85,17 @@ uint16_t envelope_index = 0; void audio_toggle(void) { audio_config.enable ^= 1; - eeconfig_write_audio(audio_config.raw); + eeconfig_update_audio(audio_config.raw); } void audio_on(void) { audio_config.enable = 1; - eeconfig_write_audio(audio_config.raw); + eeconfig_update_audio(audio_config.raw); } void audio_off(void) { audio_config.enable = 0; - eeconfig_write_audio(audio_config.raw); + eeconfig_update_audio(audio_config.raw); } #ifdef VIBRATO_ENABLE diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c index 43debf4ef..4b4bd6210 100644 --- a/quantum/keymap_common.c +++ b/quantum/keymap_common.c @@ -245,7 +245,7 @@ static action_t keycode_to_action(uint16_t keycode) keymap_config.swap_lalt_lgui = 0; keymap_config.swap_ralt_rgui = 0; } - eeconfig_write_keymap(keymap_config.raw); + eeconfig_update_keymap(keymap_config.raw); break; case 0x5100 ... 0x5FFF: ; // Layer movement shortcuts diff --git a/quantum/rgblight.c b/quantum/rgblight.c index 2215cf5cd..5623c65de 100644 --- a/quantum/rgblight.c +++ b/quantum/rgblight.c @@ -107,17 +107,17 @@ void setrgb(uint8_t r, uint8_t g, uint8_t b, struct cRGB *led1) { uint32_t eeconfig_read_rgblight(void) { return eeprom_read_dword(EECONFIG_RGBLIGHT); } -void eeconfig_write_rgblight(uint32_t val) { - eeprom_write_dword(EECONFIG_RGBLIGHT, val); +void eeconfig_update_rgblight(uint32_t val) { + eeprom_update_dword(EECONFIG_RGBLIGHT, val); } -void eeconfig_write_rgblight_default(void) { - dprintf("eeconfig_write_rgblight_default\n"); +void eeconfig_update_rgblight_default(void) { + dprintf("eeconfig_update_rgblight_default\n"); rgblight_config.enable = 1; rgblight_config.mode = 1; rgblight_config.hue = 200; rgblight_config.sat = 204; rgblight_config.val = 204; - eeconfig_write_rgblight(rgblight_config.raw); + eeconfig_update_rgblight(rgblight_config.raw); } void eeconfig_debug_rgblight(void) { dprintf("rgblight_config eprom\n"); @@ -136,12 +136,12 @@ void rgblight_init(void) { if (!eeconfig_is_enabled()) { dprintf("rgblight_init eeconfig is not enabled.\n"); eeconfig_init(); - eeconfig_write_rgblight_default(); + eeconfig_update_rgblight_default(); } rgblight_config.raw = eeconfig_read_rgblight(); if (!rgblight_config.mode) { dprintf("rgblight_init rgblight_config.mode = 0. Write default values to EEPROM.\n"); - eeconfig_write_rgblight_default(); + eeconfig_update_rgblight_default(); rgblight_config.raw = eeconfig_read_rgblight(); } eeconfig_debug_rgblight(); // display current eeprom values @@ -189,7 +189,7 @@ void rgblight_mode(uint8_t mode) { } else { rgblight_config.mode = mode; } - eeconfig_write_rgblight(rgblight_config.raw); + eeconfig_update_rgblight(rgblight_config.raw); dprintf("rgblight mode: %u\n", rgblight_config.mode); if (rgblight_config.mode == 1) { rgblight_timer_disable(); @@ -206,7 +206,7 @@ void rgblight_mode(uint8_t mode) { void rgblight_toggle(void) { rgblight_config.enable ^= 1; - eeconfig_write_rgblight(rgblight_config.raw); + eeconfig_update_rgblight(rgblight_config.raw); dprintf("rgblight toggle: rgblight_config.enable = %u\n", rgblight_config.enable); if (rgblight_config.enable) { rgblight_mode(rgblight_config.mode); @@ -299,7 +299,7 @@ void rgblight_sethsv(uint16_t hue, uint8_t sat, uint8_t val){ rgblight_config.hue = hue; rgblight_config.sat = sat; rgblight_config.val = val; - eeconfig_write_rgblight(rgblight_config.raw); + eeconfig_update_rgblight(rgblight_config.raw); dprintf("rgblight set hsv [EEPROM]: %u,%u,%u\n", rgblight_config.hue, rgblight_config.sat, rgblight_config.val); } } diff --git a/quantum/rgblight.h b/quantum/rgblight.h index 9e1562328..37e207578 100644 --- a/quantum/rgblight.h +++ b/quantum/rgblight.h @@ -66,8 +66,8 @@ void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b); #define EECONFIG_RGBLIGHT (uint8_t *)7 uint32_t eeconfig_read_rgblight(void); -void eeconfig_write_rgblight(uint32_t val); -void eeconfig_write_rgblight_default(void); +void eeconfig_update_rgblight(uint32_t val); +void eeconfig_update_rgblight_default(void); void eeconfig_debug_rgblight(void); void sethsv(uint16_t hue, uint8_t sat, uint8_t val, struct cRGB *led1); -- cgit v1.2.3-24-g4f1b From 7b3f212500210ae85063b043952b5b3ef6988ad6 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Thu, 21 Apr 2016 23:10:47 -0400 Subject: adds more voices, fixes macro redefines --- quantum/audio/voices.c | 12 ++++++++---- quantum/audio/voices.h | 1 + 2 files changed, 9 insertions(+), 4 deletions(-) (limited to 'quantum') diff --git a/quantum/audio/voices.c b/quantum/audio/voices.c index 92ada47f7..98631f0cb 100644 --- a/quantum/audio/voices.c +++ b/quantum/audio/voices.c @@ -72,15 +72,19 @@ float voice_envelope(float frequency) { polyphony_rate = 0; switch (compensated_index) { default: - #define SPEED 10 - #define AMP .75 + #define OCS_SPEED 10 + #define OCS_AMP .25 // sine wave is slow - // note_timbre = (sin((float)compensated_index/10000*SPEED) * AMP / 2) + .5; + // note_timbre = (sin((float)compensated_index/10000*OCS_SPEED) * OCS_AMP / 2) + .5; // triangle wave is a bit faster - note_timbre = (float)abs((compensated_index*SPEED % 3000) - 1500) * ( AMP / 1500 ) + (1 - AMP) / 2; + note_timbre = (float)abs((compensated_index*OCS_SPEED % 3000) - 1500) * ( OCS_AMP / 1500 ) + (1 - OCS_AMP) / 2; break; } break; + case duty_octave_down: + polyphony_rate = 0; + note_timbre = (envelope_index % 2) * .125 + .375 * 2; + break; } return frequency; diff --git a/quantum/audio/voices.h b/quantum/audio/voices.h index 44c5066b5..5aa99f4b1 100644 --- a/quantum/audio/voices.h +++ b/quantum/audio/voices.h @@ -15,6 +15,7 @@ typedef enum { butts_fader, octave_crunch, duty_osc, + duty_octave_down, number_of_voices // important that this is last } voice_type; -- cgit v1.2.3-24-g4f1b From 082a0f313d8c842a5de7bae30ec8a3597e35880b Mon Sep 17 00:00:00 2001 From: IBNobody Date: Fri, 22 Apr 2016 00:01:38 -0500 Subject: fixed compiler warnings (#273) --- quantum/audio/audio.h | 6 +++--- quantum/audio/voices.c | 37 +++++++++++++++++++++++++------------ quantum/audio/voices.h | 4 ++-- 3 files changed, 30 insertions(+), 17 deletions(-) (limited to 'quantum') diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index d1ccfdb82..89769507e 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -50,8 +50,8 @@ void decrease_vibrato_strength(float change); // Polyphony functions void set_polyphony_rate(float rate); -void enable_polyphony(); -void disable_polyphony(); +void enable_polyphony(void); +void disable_polyphony(void); void increase_polyphony_rate(float change); void decrease_polyphony_rate(float change); @@ -61,7 +61,7 @@ void set_tempo(float tempo); void increase_tempo(uint8_t tempo_change); void decrease_tempo(uint8_t tempo_change); -void audio_init(); +void audio_init(void); #ifdef PWM_AUDIO void play_sample(uint8_t * s, uint16_t l, bool r); diff --git a/quantum/audio/voices.c b/quantum/audio/voices.c index 98631f0cb..330ffb803 100644 --- a/quantum/audio/voices.c +++ b/quantum/audio/voices.c @@ -1,4 +1,5 @@ #include "voices.h" +#include "stdlib.h" // these are imported from audio.c extern uint16_t envelope_index; @@ -27,26 +28,31 @@ float voice_envelope(float frequency) { case default_voice: note_timbre = TIMBRE_50; polyphony_rate = 0; - break; + break; + case butts_fader: polyphony_rate = 0; switch (compensated_index) { case 0 ... 9: frequency = frequency / 4; note_timbre = TIMBRE_12; - break; + break; + case 10 ... 19: frequency = frequency / 2; note_timbre = TIMBRE_12; - break; + break; + case 20 ... 200: note_timbre = .125 - pow(((float)compensated_index - 20) / (200 - 20), 2)*.125; - break; + break; + default: note_timbre = 0; - break; + break; } - break; + break; + case octave_crunch: polyphony_rate = 0; switch (compensated_index) { @@ -56,17 +62,20 @@ float voice_envelope(float frequency) { frequency = frequency / 2; note_timbre = TIMBRE_12; break; + case 10 ... 19: case 25 ... 29: case 33 ... 35: frequency = frequency * 2; note_timbre = TIMBRE_12; - break; + break; + default: note_timbre = TIMBRE_12; - break; + break; } - break; + break; + case duty_osc: // This slows the loop down a substantial amount, so higher notes may freeze polyphony_rate = 0; @@ -78,13 +87,17 @@ float voice_envelope(float frequency) { // note_timbre = (sin((float)compensated_index/10000*OCS_SPEED) * OCS_AMP / 2) + .5; // triangle wave is a bit faster note_timbre = (float)abs((compensated_index*OCS_SPEED % 3000) - 1500) * ( OCS_AMP / 1500 ) + (1 - OCS_AMP) / 2; - break; + break; } - break; + break; + case duty_octave_down: polyphony_rate = 0; note_timbre = (envelope_index % 2) * .125 + .375 * 2; - break; + break; + + default: + break; } return frequency; diff --git a/quantum/audio/voices.h b/quantum/audio/voices.h index 5aa99f4b1..2822fb6ac 100644 --- a/quantum/audio/voices.h +++ b/quantum/audio/voices.h @@ -20,7 +20,7 @@ typedef enum { } voice_type; void set_voice(voice_type v); -void voice_iterate(); -void voice_deiterate(); +void voice_iterate(void); +void voice_deiterate(void); #endif \ No newline at end of file -- cgit v1.2.3-24-g4f1b From b1900c8dde2a68e87aaabd84280a99bf6658ea9f Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Fri, 22 Apr 2016 01:02:50 -0400 Subject: adds fifth and fourth down voices --- quantum/audio/voices.c | 15 +++++++++++++++ quantum/audio/voices.h | 2 ++ 2 files changed, 17 insertions(+) (limited to 'quantum') diff --git a/quantum/audio/voices.c b/quantum/audio/voices.c index 98631f0cb..8b3978f3d 100644 --- a/quantum/audio/voices.c +++ b/quantum/audio/voices.c @@ -84,6 +84,21 @@ float voice_envelope(float frequency) { case duty_octave_down: polyphony_rate = 0; note_timbre = (envelope_index % 2) * .125 + .375 * 2; + if ((envelope_index % 4) == 0) + note_timbre = 0.5; + if ((envelope_index % 8) == 0) + note_timbre = 0; + break; + case duty_fifth_down: + note_timbre = 0.5; + if ((envelope_index % 5) == 0) + note_timbre = 0.75; + break; + case duty_fourth_down: + if ((envelope_index % 12) == 0) + note_timbre = 0.25; + else + note_timbre = 0.5; break; } diff --git a/quantum/audio/voices.h b/quantum/audio/voices.h index 5aa99f4b1..718671f77 100644 --- a/quantum/audio/voices.h +++ b/quantum/audio/voices.h @@ -16,6 +16,8 @@ typedef enum { octave_crunch, duty_osc, duty_octave_down, + duty_fifth_down, + duty_fourth_down, number_of_voices // important that this is last } voice_type; -- cgit v1.2.3-24-g4f1b From a718c53fe77f0b3b4361c850531eee5f23e3e13d Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Fri, 22 Apr 2016 11:58:29 -0400 Subject: adds more voice harmonics --- quantum/audio/voices.c | 19 ++++++++++++++++--- quantum/audio/voices.h | 2 ++ 2 files changed, 18 insertions(+), 3 deletions(-) (limited to 'quantum') diff --git a/quantum/audio/voices.c b/quantum/audio/voices.c index 886101187..0b4b463c4 100644 --- a/quantum/audio/voices.c +++ b/quantum/audio/voices.c @@ -101,14 +101,27 @@ float voice_envelope(float frequency) { break; case duty_fifth_down: note_timbre = 0.5; - if ((envelope_index % 5) == 0) + if ((envelope_index % 3) == 0) note_timbre = 0.75; break; case duty_fourth_down: + note_timbre = 0.0; if ((envelope_index % 12) == 0) + note_timbre = 0.75; + if (((envelope_index % 12) % 4) != 1) + note_timbre = 0.75; + break; + case duty_third_down: + note_timbre = 0.5; + if ((envelope_index % 5) == 0) + note_timbre = 0.75; + break; + case duty_fifth_third_down: + note_timbre = 0.5; + if ((envelope_index % 5) == 0) + note_timbre = 0.75; + if ((envelope_index % 3) == 0) note_timbre = 0.25; - else - note_timbre = 0.5; break; default: diff --git a/quantum/audio/voices.h b/quantum/audio/voices.h index cdd14798b..66184c3a2 100644 --- a/quantum/audio/voices.h +++ b/quantum/audio/voices.h @@ -18,6 +18,8 @@ typedef enum { duty_octave_down, duty_fifth_down, duty_fourth_down, + duty_third_down, + duty_fifth_third_down, number_of_voices // important that this is last } voice_type; -- cgit v1.2.3-24-g4f1b From eb09c450de2886ce1811929dec8b42ada0227f04 Mon Sep 17 00:00:00 2001 From: Eric Tang Date: Fri, 22 Apr 2016 13:44:50 -0700 Subject: Fix typo (#276) --- quantum/keymap_common.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'quantum') diff --git a/quantum/keymap_common.h b/quantum/keymap_common.h index ce87e4770..0ede0296b 100644 --- a/quantum/keymap_common.h +++ b/quantum/keymap_common.h @@ -213,7 +213,7 @@ extern const uint16_t fn_actions[]; #define GUI_T(kc) MT(0x8, kc) #define C_S_T(kc) MT(0x3, kc) // Control + Shift e.g. for gnome-terminal #define MEH_T(kc) MT(0x7, kc) // Meh is a less hyper version of the Hyper key -- doesn't include Win or Cmd, so just alt+shift+ctrl -#define LCAG_T(kc) MT(0xD, kc) // Left control alt and gui +#define LCAG_T(kc) MT(0xD, kc) // Left control alt and gui #define ALL_T(kc) MT(0xF, kc) // see http://brettterpstra.com/2012/12/08/a-useful-caps-lock-key/ // Dedicated keycode versions for Hyper and Meh, if you want to use them as standalone keys rather than mod-tap @@ -231,8 +231,8 @@ extern const uint16_t fn_actions[]; // For tri-layer void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3); -#define IS_LAYER_ON(layer) ((layer_state) & (1UL<<(layer))) -#define IS_LAYER_OFF(layer) ((!layer_state) & (1UL<<(layer))) +#define IS_LAYER_ON(layer) (layer_state & (1UL << (layer))) +#define IS_LAYER_OFF(layer) (~layer_state & (1UL << (layer))) #endif -- cgit v1.2.3-24-g4f1b From 7ccfaf750d08bdb3a25ef2869cac251b7cd4d3ad Mon Sep 17 00:00:00 2001 From: James ‘Twey’ Kay Date: Sat, 23 Apr 2016 18:49:10 +0100 Subject: Add a keymap_extras header for Plover --- quantum/keymap_extras/keymap_plover.h | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 quantum/keymap_extras/keymap_plover.h (limited to 'quantum') diff --git a/quantum/keymap_extras/keymap_plover.h b/quantum/keymap_extras/keymap_plover.h new file mode 100644 index 000000000..98e57ab7b --- /dev/null +++ b/quantum/keymap_extras/keymap_plover.h @@ -0,0 +1,32 @@ +#ifndef KEYMAP_PLOVER_H +#define KEYMAP_PLOVER_H + +#include "keymap_common.h" + +#define PV_NUM KC_1 +#define PV_LS KC_Q +#define PV_LT KC_W +#define PV_LP KC_E +#define PV_LH KC_R +#define PV_LK KC_S +#define PV_LW KC_D +#define PV_LR KC_F + +#define PV_STAR KC_Y +#define PV_RF KC_U +#define PV_RP KC_I +#define PV_RL KC_O +#define PV_RT KC_P +#define PV_RD KC_LBRC +#define PV_RR KC_J +#define PV_RB KC_K +#define PV_RG KC_L +#define PV_RS KC_SCLN +#define PV_RZ KC_QUOT + +#define PV_A KC_C +#define PV_O KC_V +#define PV_E KC_N +#define PV_U KC_M + +#endif -- cgit v1.2.3-24-g4f1b From e7b6bb641c0636c01e3781fe51865fdb20014eeb Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Mon, 25 Apr 2016 00:59:47 -0400 Subject: updates default voice, prunes voices --- quantum/audio/voices.c | 50 +++++++++++++++++++++++++------------------------- quantum/audio/voices.h | 8 ++++---- 2 files changed, 29 insertions(+), 29 deletions(-) (limited to 'quantum') diff --git a/quantum/audio/voices.c b/quantum/audio/voices.c index 0b4b463c4..de9f8ae54 100644 --- a/quantum/audio/voices.c +++ b/quantum/audio/voices.c @@ -6,7 +6,7 @@ extern uint16_t envelope_index; extern float note_timbre; extern float polyphony_rate; -voice_type voice = duty_osc; +voice_type voice = default_voice; void set_voice(voice_type v) { voice = v; @@ -99,30 +99,30 @@ float voice_envelope(float frequency) { if ((envelope_index % 8) == 0) note_timbre = 0; break; - case duty_fifth_down: - note_timbre = 0.5; - if ((envelope_index % 3) == 0) - note_timbre = 0.75; - break; - case duty_fourth_down: - note_timbre = 0.0; - if ((envelope_index % 12) == 0) - note_timbre = 0.75; - if (((envelope_index % 12) % 4) != 1) - note_timbre = 0.75; - break; - case duty_third_down: - note_timbre = 0.5; - if ((envelope_index % 5) == 0) - note_timbre = 0.75; - break; - case duty_fifth_third_down: - note_timbre = 0.5; - if ((envelope_index % 5) == 0) - note_timbre = 0.75; - if ((envelope_index % 3) == 0) - note_timbre = 0.25; - break; + // case duty_fifth_down: + // note_timbre = 0.5; + // if ((envelope_index % 3) == 0) + // note_timbre = 0.75; + // break; + // case duty_fourth_down: + // note_timbre = 0.0; + // if ((envelope_index % 12) == 0) + // note_timbre = 0.75; + // if (((envelope_index % 12) % 4) != 1) + // note_timbre = 0.75; + // break; + // case duty_third_down: + // note_timbre = 0.5; + // if ((envelope_index % 5) == 0) + // note_timbre = 0.75; + // break; + // case duty_fifth_third_down: + // note_timbre = 0.5; + // if ((envelope_index % 5) == 0) + // note_timbre = 0.75; + // if ((envelope_index % 3) == 0) + // note_timbre = 0.25; + // break; default: break; diff --git a/quantum/audio/voices.h b/quantum/audio/voices.h index 66184c3a2..4b894f28d 100644 --- a/quantum/audio/voices.h +++ b/quantum/audio/voices.h @@ -16,10 +16,10 @@ typedef enum { octave_crunch, duty_osc, duty_octave_down, - duty_fifth_down, - duty_fourth_down, - duty_third_down, - duty_fifth_third_down, + // duty_fifth_down, + // duty_fourth_down, + // duty_third_down, + // duty_fifth_third_down, number_of_voices // important that this is last } voice_type; -- cgit v1.2.3-24-g4f1b From 140b97a1cd226432a8ec647004943698e3d87f0b Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Tue, 26 Apr 2016 01:16:47 -0400 Subject: adds delayed vibrato --- quantum/audio/voices.c | 31 +++++++++++++++++++++++++++++++ quantum/audio/voices.h | 2 ++ 2 files changed, 33 insertions(+) (limited to 'quantum') diff --git a/quantum/audio/voices.c b/quantum/audio/voices.c index de9f8ae54..0921bd593 100644 --- a/quantum/audio/voices.c +++ b/quantum/audio/voices.c @@ -1,5 +1,6 @@ #include "voices.h" #include "stdlib.h" +#include "vibrato_lut.h" // these are imported from audio.c extern uint16_t envelope_index; @@ -99,6 +100,36 @@ float voice_envelope(float frequency) { if ((envelope_index % 8) == 0) note_timbre = 0; break; + case delayed_vibrato: + polyphony_rate = 0; + note_timbre = TIMBRE_50; + #define VOICE_VIBRATO_DELAY 150 + #define VOICE_VIBRATO_SPEED 50 + switch (compensated_index) { + case 0 ... VOICE_VIBRATO_DELAY: + break; + default: + frequency = frequency * VIBRATO_LUT[(int)fmod((((float)compensated_index - (VOICE_VIBRATO_DELAY + 1))/1000*VOICE_VIBRATO_SPEED), VIBRATO_LUT_LENGTH)]; + break; + } + break; + // case delayed_vibrato_octave: + // polyphony_rate = 0; + // if ((envelope_index % 2) == 1) { + // note_timbre = 0.55; + // } else { + // note_timbre = 0.45; + // } + // #define VOICE_VIBRATO_DELAY 150 + // #define VOICE_VIBRATO_SPEED 50 + // switch (compensated_index) { + // case 0 ... VOICE_VIBRATO_DELAY: + // break; + // default: + // frequency = frequency * VIBRATO_LUT[(int)fmod((((float)compensated_index - (VOICE_VIBRATO_DELAY + 1))/1000*VOICE_VIBRATO_SPEED), VIBRATO_LUT_LENGTH)]; + // break; + // } + // break; // case duty_fifth_down: // note_timbre = 0.5; // if ((envelope_index % 3) == 0) diff --git a/quantum/audio/voices.h b/quantum/audio/voices.h index 4b894f28d..74c873f42 100644 --- a/quantum/audio/voices.h +++ b/quantum/audio/voices.h @@ -16,6 +16,8 @@ typedef enum { octave_crunch, duty_osc, duty_octave_down, + delayed_vibrato, + // delayed_vibrato_octave, // duty_fifth_down, // duty_fourth_down, // duty_third_down, -- cgit v1.2.3-24-g4f1b From bf56838fe99aafd37559d560e47b707a83c87588 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Tue, 26 Apr 2016 01:17:00 -0400 Subject: adds freq LUT for future use --- quantum/audio/frequency_lut.h | 357 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 357 insertions(+) create mode 100644 quantum/audio/frequency_lut.h (limited to 'quantum') diff --git a/quantum/audio/frequency_lut.h b/quantum/audio/frequency_lut.h new file mode 100644 index 000000000..e62da5be4 --- /dev/null +++ b/quantum/audio/frequency_lut.h @@ -0,0 +1,357 @@ +#include +#include +#include + +#define FREQUENCY_LUT_LENGTH 349 + +const uint16_t FREQUENCY_LUT[FREQUENCY_LUT_LENGTH] = { +0x8E0B, +0x8C02, +0x8A00, +0x8805, +0x8612, +0x8426, +0x8241, +0x8063, +0x7E8C, +0x7CBB, +0x7AF2, +0x792E, +0x7772, +0x75BB, +0x740B, +0x7261, +0x70BD, +0x6F20, +0x6D88, +0x6BF6, +0x6A69, +0x68E3, +0x6762, +0x65E6, +0x6470, +0x6300, +0x6194, +0x602E, +0x5ECD, +0x5D71, +0x5C1A, +0x5AC8, +0x597B, +0x5833, +0x56EF, +0x55B0, +0x5475, +0x533F, +0x520E, +0x50E1, +0x4FB8, +0x4E93, +0x4D73, +0x4C57, +0x4B3E, +0x4A2A, +0x491A, +0x480E, +0x4705, +0x4601, +0x4500, +0x4402, +0x4309, +0x4213, +0x4120, +0x4031, +0x3F46, +0x3E5D, +0x3D79, +0x3C97, +0x3BB9, +0x3ADD, +0x3A05, +0x3930, +0x385E, +0x3790, +0x36C4, +0x35FB, +0x3534, +0x3471, +0x33B1, +0x32F3, +0x3238, +0x3180, +0x30CA, +0x3017, +0x2F66, +0x2EB8, +0x2E0D, +0x2D64, +0x2CBD, +0x2C19, +0x2B77, +0x2AD8, +0x2A3A, +0x299F, +0x2907, +0x2870, +0x27DC, +0x2749, +0x26B9, +0x262B, +0x259F, +0x2515, +0x248D, +0x2407, +0x2382, +0x2300, +0x2280, +0x2201, +0x2184, +0x2109, +0x2090, +0x2018, +0x1FA3, +0x1F2E, +0x1EBC, +0x1E4B, +0x1DDC, +0x1D6E, +0x1D02, +0x1C98, +0x1C2F, +0x1BC8, +0x1B62, +0x1AFD, +0x1A9A, +0x1A38, +0x19D8, +0x1979, +0x191C, +0x18C0, +0x1865, +0x180B, +0x17B3, +0x175C, +0x1706, +0x16B2, +0x165E, +0x160C, +0x15BB, +0x156C, +0x151D, +0x14CF, +0x1483, +0x1438, +0x13EE, +0x13A4, +0x135C, +0x1315, +0x12CF, +0x128A, +0x1246, +0x1203, +0x11C1, +0x1180, +0x1140, +0x1100, +0x10C2, +0x1084, +0x1048, +0x100C, +0xFD1, +0xF97, +0xF5E, +0xF25, +0xEEE, +0xEB7, +0xE81, +0xE4C, +0xE17, +0xDE4, +0xDB1, +0xD7E, +0xD4D, +0xD1C, +0xCEC, +0xCBC, +0xC8E, +0xC60, +0xC32, +0xC05, +0xBD9, +0xBAE, +0xB83, +0xB59, +0xB2F, +0xB06, +0xADD, +0xAB6, +0xA8E, +0xA67, +0xA41, +0xA1C, +0x9F7, +0x9D2, +0x9AE, +0x98A, +0x967, +0x945, +0x923, +0x901, +0x8E0, +0x8C0, +0x8A0, +0x880, +0x861, +0x842, +0x824, +0x806, +0x7E8, +0x7CB, +0x7AF, +0x792, +0x777, +0x75B, +0x740, +0x726, +0x70B, +0x6F2, +0x6D8, +0x6BF, +0x6A6, +0x68E, +0x676, +0x65E, +0x647, +0x630, +0x619, +0x602, +0x5EC, +0x5D7, +0x5C1, +0x5AC, +0x597, +0x583, +0x56E, +0x55B, +0x547, +0x533, +0x520, +0x50E, +0x4FB, +0x4E9, +0x4D7, +0x4C5, +0x4B3, +0x4A2, +0x491, +0x480, +0x470, +0x460, +0x450, +0x440, +0x430, +0x421, +0x412, +0x403, +0x3F4, +0x3E5, +0x3D7, +0x3C9, +0x3BB, +0x3AD, +0x3A0, +0x393, +0x385, +0x379, +0x36C, +0x35F, +0x353, +0x347, +0x33B, +0x32F, +0x323, +0x318, +0x30C, +0x301, +0x2F6, +0x2EB, +0x2E0, +0x2D6, +0x2CB, +0x2C1, +0x2B7, +0x2AD, +0x2A3, +0x299, +0x290, +0x287, +0x27D, +0x274, +0x26B, +0x262, +0x259, +0x251, +0x248, +0x240, +0x238, +0x230, +0x228, +0x220, +0x218, +0x210, +0x209, +0x201, +0x1FA, +0x1F2, +0x1EB, +0x1E4, +0x1DD, +0x1D6, +0x1D0, +0x1C9, +0x1C2, +0x1BC, +0x1B6, +0x1AF, +0x1A9, +0x1A3, +0x19D, +0x197, +0x191, +0x18C, +0x186, +0x180, +0x17B, +0x175, +0x170, +0x16B, +0x165, +0x160, +0x15B, +0x156, +0x151, +0x14C, +0x148, +0x143, +0x13E, +0x13A, +0x135, +0x131, +0x12C, +0x128, +0x124, +0x120, +0x11C, +0x118, +0x114, +0x110, +0x10C, +0x108, +0x104, +0x100, +0xFD, +0xF9, +0xF5, +0xF2, +0xEE +}; \ No newline at end of file -- cgit v1.2.3-24-g4f1b From e024c11f7a849a38e478cda9fb9939a838cfa2e0 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Tue, 26 Apr 2016 13:50:04 -0400 Subject: actually resolves conflicts in rgblight.c --- quantum/rgblight.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'quantum') diff --git a/quantum/rgblight.c b/quantum/rgblight.c index 789af73d8..8c9ad7736 100644 --- a/quantum/rgblight.c +++ b/quantum/rgblight.c @@ -189,13 +189,8 @@ void rgblight_mode(uint8_t mode) { } else { rgblight_config.mode = mode; } -<<<<<<< HEAD eeconfig_update_rgblight(rgblight_config.raw); - dprintf("rgblight mode: %u\n", rgblight_config.mode); -======= - eeconfig_write_rgblight(rgblight_config.raw); xprintf("rgblight mode: %u\n", rgblight_config.mode); ->>>>>>> pr/286 if (rgblight_config.mode == 1) { rgblight_timer_disable(); } else if (rgblight_config.mode >=2 && rgblight_config.mode <=23) { -- cgit v1.2.3-24-g4f1b From 66e0323881a5a3da65e14daeec41a1e9cfbda431 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Fri, 29 Apr 2016 12:42:55 -0400 Subject: removes extra voices, updates .hex files --- quantum/audio/voices.c | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) (limited to 'quantum') diff --git a/quantum/audio/voices.c b/quantum/audio/voices.c index 0921bd593..d2316ba1b 100644 --- a/quantum/audio/voices.c +++ b/quantum/audio/voices.c @@ -54,28 +54,28 @@ float voice_envelope(float frequency) { } break; - case octave_crunch: - polyphony_rate = 0; - switch (compensated_index) { - case 0 ... 9: - case 20 ... 24: - case 30 ... 32: - frequency = frequency / 2; - note_timbre = TIMBRE_12; - break; - - case 10 ... 19: - case 25 ... 29: - case 33 ... 35: - frequency = frequency * 2; - note_timbre = TIMBRE_12; - break; + // case octave_crunch: + // polyphony_rate = 0; + // switch (compensated_index) { + // case 0 ... 9: + // case 20 ... 24: + // case 30 ... 32: + // frequency = frequency / 2; + // note_timbre = TIMBRE_12; + // break; + + // case 10 ... 19: + // case 25 ... 29: + // case 33 ... 35: + // frequency = frequency * 2; + // note_timbre = TIMBRE_12; + // break; - default: - note_timbre = TIMBRE_12; - break; - } - break; + // default: + // note_timbre = TIMBRE_12; + // break; + // } + // break; case duty_osc: // This slows the loop down a substantial amount, so higher notes may freeze -- cgit v1.2.3-24-g4f1b From 0656f2fa10e25e160617c3e5d14cfbae35dd9c8d Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Fri, 29 Apr 2016 22:19:40 -0400 Subject: moves backlight functionality to keyboard files and updates template makefile previously there were two backlight.c files (bad) --- quantum/template/Makefile | 46 +++++++++++++++++++++++----------- quantum/template/template.c | 61 +++++++++++++++++++++++++++++++++++++++++++++ quantum/template/template.h | 5 +++- 3 files changed, 97 insertions(+), 15 deletions(-) (limited to 'quantum') diff --git a/quantum/template/Makefile b/quantum/template/Makefile index 4fa195468..1a535ef2c 100644 --- a/quantum/template/Makefile +++ b/quantum/template/Makefile @@ -111,23 +111,41 @@ OPT_DEFS += -DBOOTLOADER_SIZE=512 # Build Options -# comment out to disable the options. -# -BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000) -MOUSEKEY_ENABLE = yes # Mouse keys(+4700) -EXTRAKEY_ENABLE = yes # Audio control and System control(+450) -CONSOLE_ENABLE = yes # Console for debug(+400) -COMMAND_ENABLE = yes # Commands for debug and configuration -KEYBOARD_LOCK_ENABLE = yes # Allow locking of keyboard via magic key +# change yes to no to disable +# +BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000) +MOUSEKEY_ENABLE = yes # Mouse keys(+4700) +EXTRAKEY_ENABLE = yes # Audio control and System control(+450) +CONSOLE_ENABLE = yes # Console for debug(+400) +COMMAND_ENABLE = yes # Commands for debug and configuration +KEYBOARD_LOCK_ENABLE = yes # Allow locking of keyboard via magic key # Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE -# SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend -#NKRO_ENABLE = yes # USB Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work -# BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality -# MIDI_ENABLE = YES # MIDI controls -# UNICODE_ENABLE = YES # Unicode -# BLUETOOTH_ENABLE = yes # Enable Bluetooth with the Adafruit EZ-Key HID +SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend +# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work +NKRO_ENABLE = no # USB Nkey Rollover +BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality +MIDI_ENABLE = no # MIDI controls +UNICODE_ENABLE = no # Unicode +BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID +AUDIO_ENABLE = no # Audio output on port C6 +ifdef KEYMAP + +ifeq ("$(wildcard keymaps/$(KEYMAP).c)","") +ifneq ("$(wildcard keymaps/$(KEYMAP)/makefile.mk)","") + include keymaps/$(KEYMAP)/makefile.mk +endif +endif + +else + +ifneq ("$(wildcard keymaps/default/makefile.mk)","") + include keymaps/default/makefile.mk +endif + +endif + # Optimize size but this may cause error "relocation truncated to fit" #EXTRALDFLAGS = -Wl,--relax diff --git a/quantum/template/template.c b/quantum/template/template.c index cc52e496f..6050a2d20 100644 --- a/quantum/template/template.c +++ b/quantum/template/template.c @@ -46,3 +46,64 @@ void led_set_kb(uint8_t usb_led) { led_set_user(usb_led); } + +#ifdef BACKLIGHT_ENABLE +#define CHANNEL OCR1C + +void backlight_init_ports() +{ + + // Setup PB7 as output and output low. + DDRB |= (1<<7); + PORTB &= ~(1<<7); + + // Use full 16-bit resolution. + ICR1 = 0xFFFF; + + // I could write a wall of text here to explain... but TL;DW + // Go read the ATmega32u4 datasheet. + // And this: http://blog.saikoled.com/post/43165849837/secret-konami-cheat-code-to-high-resolution-pwm-on + + // Pin PB7 = OCR1C (Timer 1, Channel C) + // Compare Output Mode = Clear on compare match, Channel C = COM1C1=1 COM1C0=0 + // (i.e. start high, go low when counter matches.) + // WGM Mode 14 (Fast PWM) = WGM13=1 WGM12=1 WGM11=1 WGM10=0 + // Clock Select = clk/1 (no prescaling) = CS12=0 CS11=0 CS10=1 + + TCCR1A = _BV(COM1C1) | _BV(WGM11); // = 0b00001010; + TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // = 0b00011001; + + backlight_init(); +} + +void backlight_set(uint8_t level) +{ + if ( level == 0 ) + { + // Turn off PWM control on PB7, revert to output low. + TCCR1A &= ~(_BV(COM1C1)); + CHANNEL = 0x0; + // Prevent backlight blink on lowest level + PORTB &= ~(_BV(PORTB7)); + } + else if ( level == BACKLIGHT_LEVELS ) + { + // Prevent backlight blink on lowest level + PORTB &= ~(_BV(PORTB7)); + // Turn on PWM control of PB7 + TCCR1A |= _BV(COM1C1); + // Set the brightness + CHANNEL = 0xFFFF; + } + else + { + // Prevent backlight blink on lowest level + PORTB &= ~(_BV(PORTB7)); + // Turn on PWM control of PB7 + TCCR1A |= _BV(COM1C1); + // Set the brightness + CHANNEL = 0xFFFF >> ((BACKLIGHT_LEVELS - level) * ((BACKLIGHT_LEVELS + 1) / 2)); + } +} + +#endif \ No newline at end of file diff --git a/quantum/template/template.h b/quantum/template/template.h index b1c34d3cb..22742105a 100644 --- a/quantum/template/template.h +++ b/quantum/template/template.h @@ -3,7 +3,10 @@ #include "matrix.h" #include "keymap_common.h" -#include "backlight.h" +#ifdef BACKLIGHT_ENABLE + #include "backlight.h" +#endif +#include #include // This a shortcut to help you visually see your layout. -- cgit v1.2.3-24-g4f1b From 83e1cc241e3aabd69f6cdcd2581477d4b85bb8d3 Mon Sep 17 00:00:00 2001 From: IBNobody Date: Tue, 3 May 2016 12:56:40 -0500 Subject: Clarified audio.c (#302) * Updated personal layouts * tweaked personal * Nightly - Audio Cleanup Refactored the LUTs. Abstracted some of the registers out of audio to use more functional names. Split audio into audio and audio_pwm. WIP * nightly - collapsed code * Added check for note playing to LEDs --- quantum/audio/audio.c | 766 ++++++++++++++++++------------------------ quantum/audio/audio.h | 6 +- quantum/audio/audio_pwm.c | 643 +++++++++++++++++++++++++++++++++++ quantum/audio/frequency_lut.h | 357 -------------------- quantum/audio/luts.c | 382 +++++++++++++++++++++ quantum/audio/luts.h | 15 + quantum/audio/vibrato_lut.h | 28 -- quantum/audio/voices.c | 8 +- quantum/audio/voices.h | 3 +- quantum/keymap_common.c | 6 +- quantum/quantum.mk | 1 + 11 files changed, 1379 insertions(+), 836 deletions(-) create mode 100644 quantum/audio/audio_pwm.c delete mode 100644 quantum/audio/frequency_lut.h create mode 100644 quantum/audio/luts.c create mode 100644 quantum/audio/luts.h delete mode 100644 quantum/audio/vibrato_lut.h (limited to 'quantum') diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index e85370d95..3a7f0f556 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -1,6 +1,6 @@ #include #include -#include +//#include #include #include #include @@ -10,30 +10,28 @@ #include "eeconfig.h" -#ifdef VIBRATO_ENABLE - #include "vibrato_lut.h" -#endif +#define CPU_PRESCALER 8 -#define PI 3.14159265 +// ----------------------------------------------------------------------------- +// Timer Abstractions +// ----------------------------------------------------------------------------- -#define CPU_PRESCALER 8 +// TIMSK3 - Timer/Counter #3 Interrupt Mask Register +// Turn on/off 3A interputs, stopping/enabling the ISR calls +#define ENABLE_AUDIO_COUNTER_3_ISR TIMSK3 |= _BV(OCIE3A) +#define DISABLE_AUDIO_COUNTER_3_ISR TIMSK3 &= ~_BV(OCIE3A) -#ifdef PWM_AUDIO - #include "wave.h" - #define SAMPLE_DIVIDER 39 - #define SAMPLE_RATE (2000000.0/SAMPLE_DIVIDER/2048) - // Resistor value of 1/ (2 * PI * 10nF * (2000000 hertz / SAMPLE_DIVIDER / 10)) for 10nF cap +// TCCR3A: Timer/Counter #3 Control Register +// Compare Output Mode (COM3An) = 0b00 = Normal port operation, OC3A disconnected from PC6 +#define ENABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A |= _BV(COM3A1); +#define DISABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A &= ~(_BV(COM3A1) | _BV(COM3A0)); - float places[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - uint16_t place_int = 0; - bool repeat = true; -#endif +// Fast PWM Mode Controls +#define TIMER_3_PERIOD ICR3 +#define TIMER_3_DUTY_CYCLE OCR3A + +// ----------------------------------------------------------------------------- -void delay_us(int count) { - while(count--) { - _delay_us(1); - } -} int voices = 0; int voice_place = 0; @@ -45,26 +43,23 @@ float frequencies[8] = {0, 0, 0, 0, 0, 0, 0, 0}; int volumes[8] = {0, 0, 0, 0, 0, 0, 0, 0}; bool sliding = false; -int max = 0xFF; -float sum = 0; float place = 0; uint8_t * sample; uint16_t sample_length = 0; -// float freq = 0; - -bool notes = false; -bool note = false; -float note_frequency = 0; -float note_length = 0; -float note_tempo = TEMPO_DEFAULT; -float note_timbre = TIMBRE_DEFAULT; + +bool playing_notes = false; +bool playing_note = false; +float note_frequency = 0; +float note_length = 0; +uint8_t note_tempo = TEMPO_DEFAULT; +float note_timbre = TIMBRE_DEFAULT; uint16_t note_position = 0; float (* notes_pointer)[][2]; uint16_t notes_count; -bool notes_repeat; -float notes_rest; -bool note_resting = false; +bool notes_repeat; +float notes_rest; +bool note_resting = false; uint8_t current_note = 0; uint8_t rest_counter = 0; @@ -77,175 +72,65 @@ float vibrato_rate = 0.125; float polyphony_rate = 0; -bool inited = false; +static bool audio_initialized = false; audio_config_t audio_config; uint16_t envelope_index = 0; -void audio_toggle(void) { - audio_config.enable ^= 1; - eeconfig_update_audio(audio_config.raw); -} - -void audio_on(void) { - audio_config.enable = 1; - eeconfig_update_audio(audio_config.raw); -} - -void audio_off(void) { - audio_config.enable = 0; - eeconfig_update_audio(audio_config.raw); -} - -#ifdef VIBRATO_ENABLE -// Vibrato rate functions - -void set_vibrato_rate(float rate) { - vibrato_rate = rate; -} - -void increase_vibrato_rate(float change) { - vibrato_rate *= change; -} - -void decrease_vibrato_rate(float change) { - vibrato_rate /= change; -} - -#ifdef VIBRATO_STRENGTH_ENABLE - -void set_vibrato_strength(float strength) { - vibrato_strength = strength; -} - -void increase_vibrato_strength(float change) { - vibrato_strength *= change; -} - -void decrease_vibrato_strength(float change) { - vibrato_strength /= change; -} - -#endif - -#endif - -// Polyphony functions - -void set_polyphony_rate(float rate) { - polyphony_rate = rate; -} - -void enable_polyphony() { - polyphony_rate = 5; -} - -void disable_polyphony() { - polyphony_rate = 0; -} - -void increase_polyphony_rate(float change) { - polyphony_rate *= change; -} - -void decrease_polyphony_rate(float change) { - polyphony_rate /= change; -} - -// Timbre function - -void set_timbre(float timbre) { - note_timbre = timbre; -} - -// Tempo functions - -void set_tempo(float tempo) { - note_tempo = tempo; -} - -void decrease_tempo(uint8_t tempo_change) { - note_tempo += (float) tempo_change; -} - -void increase_tempo(uint8_t tempo_change) { - if (note_tempo - (float) tempo_change < 10) { - note_tempo = 10; - } else { - note_tempo -= (float) tempo_change; - } -} - -void audio_init() { +void audio_init() +{ - /* check signature */ - if (!eeconfig_is_enabled()) { + // Check EEPROM + if (!eeconfig_is_enabled()) + { eeconfig_init(); } audio_config.raw = eeconfig_read_audio(); - #ifdef PWM_AUDIO - PLLFRQ = _BV(PDIV2); - PLLCSR = _BV(PLLE); - while(!(PLLCSR & _BV(PLOCK))); - PLLFRQ |= _BV(PLLTM0); /* PCK 48MHz */ + // Set port PC6 (OC3A and /OC4A) as output + DDRC |= _BV(PORTC6); - /* Init a fast PWM on Timer4 */ - TCCR4A = _BV(COM4A0) | _BV(PWM4A); /* Clear OC4A on Compare Match */ - TCCR4B = _BV(CS40); /* No prescaling => f = PCK/256 = 187500Hz */ - OCR4A = 0; + DISABLE_AUDIO_COUNTER_3_ISR; - /* Enable the OC4A output */ - DDRC |= _BV(PORTC6); + // TCCR3A / TCCR3B: Timer/Counter #3 Control Registers + // Compare Output Mode (COM3An) = 0b00 = Normal port operation, OC3A disconnected from PC6 + // Waveform Generation Mode (WGM3n) = 0b1110 = Fast PWM Mode 14 (Period = ICR3, Duty Cycle = OCR3A) + // Clock Select (CS3n) = 0b010 = Clock / 8 + TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30); + TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30); - TIMSK3 &= ~_BV(OCIE3A); // Turn off 3A interputs - - TCCR3A = 0x0; // Options not needed - TCCR3B = _BV(CS31) | _BV(CS30) | _BV(WGM32); // 64th prescaling and CTC - OCR3A = SAMPLE_DIVIDER - 1; // Correct count/compare, related to sample playback - #else - DDRC |= _BV(PORTC6); - - TIMSK3 &= ~_BV(OCIE3A); // Turn off 3A interputs - - TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30); - TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30); - #endif - - inited = true; + audio_initialized = true; } -void stop_all_notes() { - if (!inited) { +void stop_all_notes() +{ + if (!audio_initialized) { audio_init(); } voices = 0; - #ifdef PWM_AUDIO - TIMSK3 &= ~_BV(OCIE3A); - #else - TIMSK3 &= ~_BV(OCIE3A); - TCCR3A &= ~_BV(COM3A1); - #endif - notes = false; - note = false; + + DISABLE_AUDIO_COUNTER_3_ISR; + DISABLE_AUDIO_COUNTER_3_OUTPUT; + + playing_notes = false; + playing_note = false; frequency = 0; volume = 0; - for (int i = 0; i < 8; i++) { + for (uint8_t i = 0; i < 8; i++) + { frequencies[i] = 0; volumes[i] = 0; } } -void stop_note(float freq) { - if (note) { - if (!inited) { +void stop_note(float freq) +{ + if (playing_note) { + if (!audio_initialized) { audio_init(); } - #ifdef PWM_AUDIO - freq = freq / SAMPLE_RATE; - #endif for (int i = 7; i >= 0; i--) { if (frequencies[i] == freq) { frequencies[i] = 0; @@ -266,15 +151,11 @@ void stop_note(float freq) { voice_place = 0; } if (voices == 0) { - #ifdef PWM_AUDIO - TIMSK3 &= ~_BV(OCIE3A); - #else - TIMSK3 &= ~_BV(OCIE3A); - TCCR3A &= ~_BV(COM3A1); - #endif + DISABLE_AUDIO_COUNTER_3_ISR; + DISABLE_AUDIO_COUNTER_3_OUTPUT; frequency = 0; volume = 0; - note = false; + playing_note = false; } } } @@ -289,9 +170,9 @@ float mod(float a, int b) float vibrato(float average_freq) { #ifdef VIBRATO_STRENGTH_ENABLE - float vibrated_freq = average_freq * pow(VIBRATO_LUT[(int)vibrato_counter], vibrato_strength); + float vibrated_freq = average_freq * pow(vibrato_lut[(int)vibrato_counter], vibrato_strength); #else - float vibrated_freq = average_freq * VIBRATO_LUT[(int)vibrato_counter]; + float vibrated_freq = average_freq * vibrato_lut[(int)vibrato_counter]; #endif vibrato_counter = mod((vibrato_counter + vibrato_rate * (1.0 + 440.0/average_freq)), VIBRATO_LUT_LENGTH); return vibrated_freq; @@ -299,295 +180,295 @@ float vibrato(float average_freq) { #endif -ISR(TIMER3_COMPA_vect) { - if (note) { - #ifdef PWM_AUDIO - if (voices == 1) { - // SINE - OCR4A = pgm_read_byte(&sinewave[(uint16_t)place]) >> 2; - - // SQUARE - // if (((int)place) >= 1024){ - // OCR4A = 0xFF >> 2; - // } else { - // OCR4A = 0x00; - // } - - // SAWTOOTH - // OCR4A = (int)place / 4; - - // TRIANGLE - // if (((int)place) >= 1024) { - // OCR4A = (int)place / 2; - // } else { - // OCR4A = 2048 - (int)place / 2; - // } - - place += frequency; - - if (place >= SINE_LENGTH) - place -= SINE_LENGTH; - - } else { - int sum = 0; - for (int i = 0; i < voices; i++) { - // SINE - sum += pgm_read_byte(&sinewave[(uint16_t)places[i]]) >> 2; - - // SQUARE - // if (((int)places[i]) >= 1024){ - // sum += 0xFF >> 2; - // } else { - // sum += 0x00; - // } - - places[i] += frequencies[i]; - - if (places[i] >= SINE_LENGTH) - places[i] -= SINE_LENGTH; - } - OCR4A = sum; - } - #else - if (voices > 0) { - float freq; - if (polyphony_rate > 0) { - if (voices > 1) { - voice_place %= voices; - if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER)) { - voice_place = (voice_place + 1) % voices; - place = 0.0; - } - } - #ifdef VIBRATO_ENABLE - if (vibrato_strength > 0) { - freq = vibrato(frequencies[voice_place]); - } else { - #else - { - #endif - freq = frequencies[voice_place]; - } - } else { - if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440/frequencies[voices - 1]/12/2)) { - frequency = frequency * pow(2, 440/frequency/12/2); - } else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440/frequencies[voices - 1]/12/2)) { - frequency = frequency * pow(2, -440/frequency/12/2); - } else { - frequency = frequencies[voices - 1]; - } - - - #ifdef VIBRATO_ENABLE - if (vibrato_strength > 0) { - freq = vibrato(frequency); - } else { - #else - { - #endif - freq = frequency; - } - } +ISR(TIMER3_COMPA_vect) +{ + float freq; + + if (playing_note) { + if (voices > 0) { + if (polyphony_rate > 0) { + if (voices > 1) { + voice_place %= voices; + if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER)) { + voice_place = (voice_place + 1) % voices; + place = 0.0; + } + } + + #ifdef VIBRATO_ENABLE + if (vibrato_strength > 0) { + freq = vibrato(frequencies[voice_place]); + } else { + freq = frequencies[voice_place]; + } + #else + freq = frequencies[voice_place]; + #endif + } else { + if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440/frequencies[voices - 1]/12/2)) { + frequency = frequency * pow(2, 440/frequency/12/2); + } else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440/frequencies[voices - 1]/12/2)) { + frequency = frequency * pow(2, -440/frequency/12/2); + } else { + frequency = frequencies[voices - 1]; + } + + #ifdef VIBRATO_ENABLE + if (vibrato_strength > 0) { + freq = vibrato(frequency); + } else { + freq = frequency; + } + #else + freq = frequency; + #endif + } + + if (envelope_index < 65535) { + envelope_index++; + } + + freq = voice_envelope(freq); + + if (freq < 30.517578125) { + freq = 30.52; + } + + TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); + TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); + } + } + + if (playing_notes) { + if (note_frequency > 0) { + #ifdef VIBRATO_ENABLE + if (vibrato_strength > 0) { + freq = vibrato(note_frequency); + } else { + freq = note_frequency; + } + #else + freq = note_frequency; + #endif + + if (envelope_index < 65535) { + envelope_index++; + } + freq = voice_envelope(freq); + + TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); + TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); + } else { + TIMER_3_PERIOD = 0; + TIMER_3_DUTY_CYCLE = 0; + } + + note_position++; + bool end_of_note = false; + if (TIMER_3_PERIOD > 0) { + end_of_note = (note_position >= (note_length / TIMER_3_PERIOD * 0xFFFF)); + } else { + end_of_note = (note_position >= (note_length * 0x7FF)); + } + + if (end_of_note) { + current_note++; + if (current_note >= notes_count) { + if (notes_repeat) { + current_note = 0; + } else { + DISABLE_AUDIO_COUNTER_3_ISR; + DISABLE_AUDIO_COUNTER_3_OUTPUT; + playing_notes = false; + return; + } + } + if (!note_resting && (notes_rest > 0)) { + note_resting = true; + note_frequency = 0; + note_length = notes_rest; + current_note--; + } else { + note_resting = false; + envelope_index = 0; + note_frequency = (*notes_pointer)[current_note][0]; + note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100); + } + + note_position = 0; + } + } + + if (!audio_config.enable) { + playing_notes = false; + playing_note = false; + } +} - if (envelope_index < 65535) { - envelope_index++; - } - freq = voice_envelope(freq); +void play_note(float freq, int vol) { - if (freq < 30.517578125) - freq = 30.52; - ICR3 = (int)(((double)F_CPU) / (freq * CPU_PRESCALER)); // Set max to the period - OCR3A = (int)((((double)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); // Set compare to half the period - } - #endif + if (!audio_initialized) { + audio_init(); } - // SAMPLE - // OCR4A = pgm_read_byte(&sample[(uint16_t)place_int]); - - // place_int++; - - // if (place_int >= sample_length) - // if (repeat) - // place_int -= sample_length; - // else - // TIMSK3 &= ~_BV(OCIE3A); - - - if (notes) { - #ifdef PWM_AUDIO - OCR4A = pgm_read_byte(&sinewave[(uint16_t)place]) >> 0; - - place += note_frequency; - if (place >= SINE_LENGTH) - place -= SINE_LENGTH; - #else - if (note_frequency > 0) { - float freq; - - #ifdef VIBRATO_ENABLE - if (vibrato_strength > 0) { - freq = vibrato(note_frequency); - } else { - #else - { - #endif - freq = note_frequency; - } + if (audio_config.enable && voices < 8) { + DISABLE_AUDIO_COUNTER_3_ISR; - if (envelope_index < 65535) { - envelope_index++; - } - freq = voice_envelope(freq); + // Cancel notes if notes are playing + if (playing_notes) + stop_all_notes(); - ICR3 = (int)(((double)F_CPU) / (freq * CPU_PRESCALER)); // Set max to the period - OCR3A = (int)((((double)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); // Set compare to half the period - } else { - ICR3 = 0; - OCR3A = 0; - } - #endif - - - note_position++; - bool end_of_note = false; - if (ICR3 > 0) - end_of_note = (note_position >= (note_length / ICR3 * 0xFFFF)); - else - end_of_note = (note_position >= (note_length * 0x7FF)); - if (end_of_note) { - current_note++; - if (current_note >= notes_count) { - if (notes_repeat) { - current_note = 0; - } else { - #ifdef PWM_AUDIO - TIMSK3 &= ~_BV(OCIE3A); - #else - TIMSK3 &= ~_BV(OCIE3A); - TCCR3A &= ~_BV(COM3A1); - #endif - notes = false; - return; - } - } - if (!note_resting && (notes_rest > 0)) { - note_resting = true; - note_frequency = 0; - note_length = notes_rest; - current_note--; - } else { - note_resting = false; - #ifdef PWM_AUDIO - note_frequency = (*notes_pointer)[current_note][0] / SAMPLE_RATE; - note_length = (*notes_pointer)[current_note][1] * (note_tempo / 100); - #else - envelope_index = 0; - note_frequency = (*notes_pointer)[current_note][0]; - note_length = ((*notes_pointer)[current_note][1] / 4) * (note_tempo / 100); - #endif - } - note_position = 0; - } + playing_note = true; - } + envelope_index = 0; + + if (freq > 0) { + frequencies[voices] = freq; + volumes[voices] = vol; + voices++; + } + + ENABLE_AUDIO_COUNTER_3_ISR; + ENABLE_AUDIO_COUNTER_3_OUTPUT; + } - if (!audio_config.enable) { - notes = false; - note = false; - } } -void play_note(float freq, int vol) { +void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat, float n_rest) +{ - if (!inited) { + if (!audio_initialized) { audio_init(); } -if (audio_config.enable && voices < 8) { - TIMSK3 &= ~_BV(OCIE3A); - // Cancel notes if notes are playing - if (notes) - stop_all_notes(); - note = true; - envelope_index = 0; - #ifdef PWM_AUDIO - freq = freq / SAMPLE_RATE; - #endif - if (freq > 0) { - frequencies[voices] = freq; - volumes[voices] = vol; - voices++; - } + if (audio_config.enable) { + + DISABLE_AUDIO_COUNTER_3_ISR; + + // Cancel note if a note is playing + if (playing_note) + stop_all_notes(); + + playing_notes = true; + + notes_pointer = np; + notes_count = n_count; + notes_repeat = n_repeat; + notes_rest = n_rest; + + place = 0; + current_note = 0; + + note_frequency = (*notes_pointer)[current_note][0]; + note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100); + note_position = 0; + + + ENABLE_AUDIO_COUNTER_3_ISR; + ENABLE_AUDIO_COUNTER_3_OUTPUT; + } - #ifdef PWM_AUDIO - TIMSK3 |= _BV(OCIE3A); - #else - TIMSK3 |= _BV(OCIE3A); - TCCR3A |= _BV(COM3A1); - #endif } +bool is_playing_notes(void) { + return playing_notes; } -void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat, float n_rest) { +void audio_toggle(void) { + audio_config.enable ^= 1; + eeconfig_update_audio(audio_config.raw); +} - if (!inited) { - audio_init(); - } +void audio_on(void) { + audio_config.enable = 1; + eeconfig_update_audio(audio_config.raw); +} -if (audio_config.enable) { - TIMSK3 &= ~_BV(OCIE3A); - // Cancel note if a note is playing - if (note) - stop_all_notes(); - notes = true; - - notes_pointer = np; - notes_count = n_count; - notes_repeat = n_repeat; - notes_rest = n_rest; - - place = 0; - current_note = 0; - #ifdef PWM_AUDIO - note_frequency = (*notes_pointer)[current_note][0] / SAMPLE_RATE; - note_length = (*notes_pointer)[current_note][1] * (note_tempo / 100); - #else - note_frequency = (*notes_pointer)[current_note][0]; - note_length = ((*notes_pointer)[current_note][1] / 4) * (note_tempo / 100); - #endif - note_position = 0; +void audio_off(void) { + audio_config.enable = 0; + eeconfig_update_audio(audio_config.raw); +} +#ifdef VIBRATO_ENABLE - #ifdef PWM_AUDIO - TIMSK3 |= _BV(OCIE3A); - #else - TIMSK3 |= _BV(OCIE3A); - TCCR3A |= _BV(COM3A1); - #endif +// Vibrato rate functions + +void set_vibrato_rate(float rate) { + vibrato_rate = rate; } +void increase_vibrato_rate(float change) { + vibrato_rate *= change; } -#ifdef PWM_AUDIO -void play_sample(uint8_t * s, uint16_t l, bool r) { - if (!inited) { - audio_init(); - } +void decrease_vibrato_rate(float change) { + vibrato_rate /= change; +} - if (audio_config.enable) { - TIMSK3 &= ~_BV(OCIE3A); - stop_all_notes(); - place_int = 0; - sample = s; - sample_length = l; - repeat = r; +#ifdef VIBRATO_STRENGTH_ENABLE + +void set_vibrato_strength(float strength) { + vibrato_strength = strength; +} + +void increase_vibrato_strength(float change) { + vibrato_strength *= change; +} + +void decrease_vibrato_strength(float change) { + vibrato_strength /= change; +} + +#endif /* VIBRATO_STRENGTH_ENABLE */ + +#endif /* VIBRATO_ENABLE */ - TIMSK3 |= _BV(OCIE3A); +// Polyphony functions + +void set_polyphony_rate(float rate) { + polyphony_rate = rate; +} + +void enable_polyphony() { + polyphony_rate = 5; +} + +void disable_polyphony() { + polyphony_rate = 0; +} + +void increase_polyphony_rate(float change) { + polyphony_rate *= change; +} + +void decrease_polyphony_rate(float change) { + polyphony_rate /= change; +} + +// Timbre function + +void set_timbre(float timbre) { + note_timbre = timbre; +} + +// Tempo functions + +void set_tempo(uint8_t tempo) { + note_tempo = tempo; +} + +void decrease_tempo(uint8_t tempo_change) { + note_tempo += tempo_change; +} + +void increase_tempo(uint8_t tempo_change) { + if (note_tempo - tempo_change < 10) { + note_tempo = 10; + } else { + note_tempo -= tempo_change; } } -#endif + //------------------------------------------------------------------------------ // Override these functions in your keymap file to play different tunes on @@ -597,11 +478,8 @@ void play_startup_tone() { } - - __attribute__ ((weak)) void play_goodbye_tone() { - } //------------------------------------------------------------------------------ diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index 89769507e..3d706587a 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -56,7 +56,7 @@ void increase_polyphony_rate(float change); void decrease_polyphony_rate(float change); void set_timbre(float timbre); -void set_tempo(float tempo); +void set_tempo(uint8_t tempo); void increase_tempo(uint8_t tempo_change); void decrease_tempo(uint8_t tempo_change); @@ -83,7 +83,11 @@ void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat, float n_rest) #define NOTE_ARRAY_SIZE(x) ((int16_t)(sizeof(x) / (sizeof(x[0])))) #define PLAY_NOTE_ARRAY(note_array, note_repeat, note_rest_style) play_notes(¬e_array, NOTE_ARRAY_SIZE((note_array)), (note_repeat), (note_rest_style)); + +bool is_playing_notes(void); void play_goodbye_tone(void); void play_startup_tone(void); + + #endif \ No newline at end of file diff --git a/quantum/audio/audio_pwm.c b/quantum/audio/audio_pwm.c new file mode 100644 index 000000000..328a253a7 --- /dev/null +++ b/quantum/audio/audio_pwm.c @@ -0,0 +1,643 @@ +#include +#include +//#include +#include +#include +#include +#include "print.h" +#include "audio.h" +#include "keymap_common.h" + +#include "eeconfig.h" + +#define PI 3.14159265 + +#define CPU_PRESCALER 8 + + +// Timer Abstractions + +// TIMSK3 - Timer/Counter #3 Interrupt Mask Register +// Turn on/off 3A interputs, stopping/enabling the ISR calls +#define ENABLE_AUDIO_COUNTER_3_ISR TIMSK3 |= _BV(OCIE3A) +#define DISABLE_AUDIO_COUNTER_3_ISR TIMSK3 &= ~_BV(OCIE3A) + + +// TCCR3A: Timer/Counter #3 Control Register +// Compare Output Mode (COM3An) = 0b00 = Normal port operation, OC3A disconnected from PC6 +#define ENABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A |= _BV(COM3A1); +#define DISABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A &= ~(_BV(COM3A1) | _BV(COM3A0)); + + +#define NOTE_PERIOD ICR3 +#define NOTE_DUTY_CYCLE OCR3A + + +#ifdef PWM_AUDIO + #include "wave.h" + #define SAMPLE_DIVIDER 39 + #define SAMPLE_RATE (2000000.0/SAMPLE_DIVIDER/2048) + // Resistor value of 1/ (2 * PI * 10nF * (2000000 hertz / SAMPLE_DIVIDER / 10)) for 10nF cap + + float places[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + uint16_t place_int = 0; + bool repeat = true; +#endif + +void delay_us(int count) { + while(count--) { + _delay_us(1); + } +} + +int voices = 0; +int voice_place = 0; +float frequency = 0; +int volume = 0; +long position = 0; + +float frequencies[8] = {0, 0, 0, 0, 0, 0, 0, 0}; +int volumes[8] = {0, 0, 0, 0, 0, 0, 0, 0}; +bool sliding = false; + +float place = 0; + +uint8_t * sample; +uint16_t sample_length = 0; +// float freq = 0; + +bool playing_notes = false; +bool playing_note = false; +float note_frequency = 0; +float note_length = 0; +uint8_t note_tempo = TEMPO_DEFAULT; +float note_timbre = TIMBRE_DEFAULT; +uint16_t note_position = 0; +float (* notes_pointer)[][2]; +uint16_t notes_count; +bool notes_repeat; +float notes_rest; +bool note_resting = false; + +uint8_t current_note = 0; +uint8_t rest_counter = 0; + +#ifdef VIBRATO_ENABLE +float vibrato_counter = 0; +float vibrato_strength = .5; +float vibrato_rate = 0.125; +#endif + +float polyphony_rate = 0; + +static bool audio_initialized = false; + +audio_config_t audio_config; + +uint16_t envelope_index = 0; + +void audio_init() { + + // Check EEPROM + if (!eeconfig_is_enabled()) + { + eeconfig_init(); + } + audio_config.raw = eeconfig_read_audio(); + + #ifdef PWM_AUDIO + + PLLFRQ = _BV(PDIV2); + PLLCSR = _BV(PLLE); + while(!(PLLCSR & _BV(PLOCK))); + PLLFRQ |= _BV(PLLTM0); /* PCK 48MHz */ + + /* Init a fast PWM on Timer4 */ + TCCR4A = _BV(COM4A0) | _BV(PWM4A); /* Clear OC4A on Compare Match */ + TCCR4B = _BV(CS40); /* No prescaling => f = PCK/256 = 187500Hz */ + OCR4A = 0; + + /* Enable the OC4A output */ + DDRC |= _BV(PORTC6); + + DISABLE_AUDIO_COUNTER_3_ISR; // Turn off 3A interputs + + TCCR3A = 0x0; // Options not needed + TCCR3B = _BV(CS31) | _BV(CS30) | _BV(WGM32); // 64th prescaling and CTC + OCR3A = SAMPLE_DIVIDER - 1; // Correct count/compare, related to sample playback + + #else + + // Set port PC6 (OC3A and /OC4A) as output + DDRC |= _BV(PORTC6); + + DISABLE_AUDIO_COUNTER_3_ISR; + + // TCCR3A / TCCR3B: Timer/Counter #3 Control Registers + // Compare Output Mode (COM3An) = 0b00 = Normal port operation, OC3A disconnected from PC6 + // Waveform Generation Mode (WGM3n) = 0b1110 = Fast PWM Mode 14 (Period = ICR3, Duty Cycle = OCR3A) + // Clock Select (CS3n) = 0b010 = Clock / 8 + TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30); + TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30); + + #endif + + audio_initialized = true; +} + +void stop_all_notes() { + if (!audio_initialized) { + audio_init(); + } + voices = 0; + #ifdef PWM_AUDIO + DISABLE_AUDIO_COUNTER_3_ISR; + #else + DISABLE_AUDIO_COUNTER_3_ISR; + DISABLE_AUDIO_COUNTER_3_OUTPUT; + #endif + + playing_notes = false; + playing_note = false; + frequency = 0; + volume = 0; + + for (uint8_t i = 0; i < 8; i++) + { + frequencies[i] = 0; + volumes[i] = 0; + } +} + +void stop_note(float freq) +{ + if (playing_note) { + if (!audio_initialized) { + audio_init(); + } + #ifdef PWM_AUDIO + freq = freq / SAMPLE_RATE; + #endif + for (int i = 7; i >= 0; i--) { + if (frequencies[i] == freq) { + frequencies[i] = 0; + volumes[i] = 0; + for (int j = i; (j < 7); j++) { + frequencies[j] = frequencies[j+1]; + frequencies[j+1] = 0; + volumes[j] = volumes[j+1]; + volumes[j+1] = 0; + } + break; + } + } + voices--; + if (voices < 0) + voices = 0; + if (voice_place >= voices) { + voice_place = 0; + } + if (voices == 0) { + #ifdef PWM_AUDIO + DISABLE_AUDIO_COUNTER_3_ISR; + #else + DISABLE_AUDIO_COUNTER_3_ISR; + DISABLE_AUDIO_COUNTER_3_OUTPUT; + #endif + frequency = 0; + volume = 0; + playing_note = false; + } + } +} + +#ifdef VIBRATO_ENABLE + +float mod(float a, int b) +{ + float r = fmod(a, b); + return r < 0 ? r + b : r; +} + +float vibrato(float average_freq) { + #ifdef VIBRATO_STRENGTH_ENABLE + float vibrated_freq = average_freq * pow(vibrato_lut[(int)vibrato_counter], vibrato_strength); + #else + float vibrated_freq = average_freq * vibrato_lut[(int)vibrato_counter]; + #endif + vibrato_counter = mod((vibrato_counter + vibrato_rate * (1.0 + 440.0/average_freq)), VIBRATO_LUT_LENGTH); + return vibrated_freq; +} + +#endif + +ISR(TIMER3_COMPA_vect) +{ + if (playing_note) { + #ifdef PWM_AUDIO + if (voices == 1) { + // SINE + OCR4A = pgm_read_byte(&sinewave[(uint16_t)place]) >> 2; + + // SQUARE + // if (((int)place) >= 1024){ + // OCR4A = 0xFF >> 2; + // } else { + // OCR4A = 0x00; + // } + + // SAWTOOTH + // OCR4A = (int)place / 4; + + // TRIANGLE + // if (((int)place) >= 1024) { + // OCR4A = (int)place / 2; + // } else { + // OCR4A = 2048 - (int)place / 2; + // } + + place += frequency; + + if (place >= SINE_LENGTH) + place -= SINE_LENGTH; + + } else { + int sum = 0; + for (int i = 0; i < voices; i++) { + // SINE + sum += pgm_read_byte(&sinewave[(uint16_t)places[i]]) >> 2; + + // SQUARE + // if (((int)places[i]) >= 1024){ + // sum += 0xFF >> 2; + // } else { + // sum += 0x00; + // } + + places[i] += frequencies[i]; + + if (places[i] >= SINE_LENGTH) + places[i] -= SINE_LENGTH; + } + OCR4A = sum; + } + #else + if (voices > 0) { + float freq; + if (polyphony_rate > 0) { + if (voices > 1) { + voice_place %= voices; + if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER)) { + voice_place = (voice_place + 1) % voices; + place = 0.0; + } + } + #ifdef VIBRATO_ENABLE + if (vibrato_strength > 0) { + freq = vibrato(frequencies[voice_place]); + } else { + #else + { + #endif + freq = frequencies[voice_place]; + } + } else { + if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440/frequencies[voices - 1]/12/2)) { + frequency = frequency * pow(2, 440/frequency/12/2); + } else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440/frequencies[voices - 1]/12/2)) { + frequency = frequency * pow(2, -440/frequency/12/2); + } else { + frequency = frequencies[voices - 1]; + } + + + #ifdef VIBRATO_ENABLE + if (vibrato_strength > 0) { + freq = vibrato(frequency); + } else { + #else + { + #endif + freq = frequency; + } + } + + if (envelope_index < 65535) { + envelope_index++; + } + freq = voice_envelope(freq); + + if (freq < 30.517578125) + freq = 30.52; + NOTE_PERIOD = (int)(((double)F_CPU) / (freq * CPU_PRESCALER)); // Set max to the period + NOTE_DUTY_CYCLE = (int)((((double)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); // Set compare to half the period + } + #endif + } + + // SAMPLE + // OCR4A = pgm_read_byte(&sample[(uint16_t)place_int]); + + // place_int++; + + // if (place_int >= sample_length) + // if (repeat) + // place_int -= sample_length; + // else + // DISABLE_AUDIO_COUNTER_3_ISR; + + + if (playing_notes) { + #ifdef PWM_AUDIO + OCR4A = pgm_read_byte(&sinewave[(uint16_t)place]) >> 0; + + place += note_frequency; + if (place >= SINE_LENGTH) + place -= SINE_LENGTH; + #else + if (note_frequency > 0) { + float freq; + + #ifdef VIBRATO_ENABLE + if (vibrato_strength > 0) { + freq = vibrato(note_frequency); + } else { + #else + { + #endif + freq = note_frequency; + } + + if (envelope_index < 65535) { + envelope_index++; + } + freq = voice_envelope(freq); + + NOTE_PERIOD = (int)(((double)F_CPU) / (freq * CPU_PRESCALER)); // Set max to the period + NOTE_DUTY_CYCLE = (int)((((double)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); // Set compare to half the period + } else { + NOTE_PERIOD = 0; + NOTE_DUTY_CYCLE = 0; + } + #endif + + + note_position++; + bool end_of_note = false; + if (NOTE_PERIOD > 0) + end_of_note = (note_position >= (note_length / NOTE_PERIOD * 0xFFFF)); + else + end_of_note = (note_position >= (note_length * 0x7FF)); + if (end_of_note) { + current_note++; + if (current_note >= notes_count) { + if (notes_repeat) { + current_note = 0; + } else { + #ifdef PWM_AUDIO + DISABLE_AUDIO_COUNTER_3_ISR; + #else + DISABLE_AUDIO_COUNTER_3_ISR; + DISABLE_AUDIO_COUNTER_3_OUTPUT; + #endif + playing_notes = false; + return; + } + } + if (!note_resting && (notes_rest > 0)) { + note_resting = true; + note_frequency = 0; + note_length = notes_rest; + current_note--; + } else { + note_resting = false; + #ifdef PWM_AUDIO + note_frequency = (*notes_pointer)[current_note][0] / SAMPLE_RATE; + note_length = (*notes_pointer)[current_note][1] * (((float)note_tempo) / 100); + #else + envelope_index = 0; + note_frequency = (*notes_pointer)[current_note][0]; + note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100); + #endif + } + note_position = 0; + } + + } + + if (!audio_config.enable) { + playing_notes = false; + playing_note = false; + } +} + +void play_note(float freq, int vol) { + + if (!audio_initialized) { + audio_init(); + } + + if (audio_config.enable && voices < 8) { + DISABLE_AUDIO_COUNTER_3_ISR; + + // Cancel notes if notes are playing + if (playing_notes) + stop_all_notes(); + + playing_note = true; + + envelope_index = 0; + + #ifdef PWM_AUDIO + freq = freq / SAMPLE_RATE; + #endif + if (freq > 0) { + frequencies[voices] = freq; + volumes[voices] = vol; + voices++; + } + + #ifdef PWM_AUDIO + ENABLE_AUDIO_COUNTER_3_ISR; + #else + ENABLE_AUDIO_COUNTER_3_ISR; + ENABLE_AUDIO_COUNTER_3_OUTPUT; + #endif + } + +} + +void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat, float n_rest) +{ + + if (!audio_initialized) { + audio_init(); + } + + if (audio_config.enable) { + + DISABLE_AUDIO_COUNTER_3_ISR; + + // Cancel note if a note is playing + if (playing_note) + stop_all_notes(); + + playing_notes = true; + + notes_pointer = np; + notes_count = n_count; + notes_repeat = n_repeat; + notes_rest = n_rest; + + place = 0; + current_note = 0; + + #ifdef PWM_AUDIO + note_frequency = (*notes_pointer)[current_note][0] / SAMPLE_RATE; + note_length = (*notes_pointer)[current_note][1] * (((float)note_tempo) / 100); + #else + note_frequency = (*notes_pointer)[current_note][0]; + note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100); + #endif + note_position = 0; + + + #ifdef PWM_AUDIO + ENABLE_AUDIO_COUNTER_3_ISR; + #else + ENABLE_AUDIO_COUNTER_3_ISR; + ENABLE_AUDIO_COUNTER_3_OUTPUT; + #endif + } + +} + +#ifdef PWM_AUDIO +void play_sample(uint8_t * s, uint16_t l, bool r) { + if (!audio_initialized) { + audio_init(); + } + + if (audio_config.enable) { + DISABLE_AUDIO_COUNTER_3_ISR; + stop_all_notes(); + place_int = 0; + sample = s; + sample_length = l; + repeat = r; + + ENABLE_AUDIO_COUNTER_3_ISR; + } +} +#endif + + +void audio_toggle(void) { + audio_config.enable ^= 1; + eeconfig_update_audio(audio_config.raw); +} + +void audio_on(void) { + audio_config.enable = 1; + eeconfig_update_audio(audio_config.raw); +} + +void audio_off(void) { + audio_config.enable = 0; + eeconfig_update_audio(audio_config.raw); +} + +#ifdef VIBRATO_ENABLE + +// Vibrato rate functions + +void set_vibrato_rate(float rate) { + vibrato_rate = rate; +} + +void increase_vibrato_rate(float change) { + vibrato_rate *= change; +} + +void decrease_vibrato_rate(float change) { + vibrato_rate /= change; +} + +#ifdef VIBRATO_STRENGTH_ENABLE + +void set_vibrato_strength(float strength) { + vibrato_strength = strength; +} + +void increase_vibrato_strength(float change) { + vibrato_strength *= change; +} + +void decrease_vibrato_strength(float change) { + vibrato_strength /= change; +} + +#endif /* VIBRATO_STRENGTH_ENABLE */ + +#endif /* VIBRATO_ENABLE */ + +// Polyphony functions + +void set_polyphony_rate(float rate) { + polyphony_rate = rate; +} + +void enable_polyphony() { + polyphony_rate = 5; +} + +void disable_polyphony() { + polyphony_rate = 0; +} + +void increase_polyphony_rate(float change) { + polyphony_rate *= change; +} + +void decrease_polyphony_rate(float change) { + polyphony_rate /= change; +} + +// Timbre function + +void set_timbre(float timbre) { + note_timbre = timbre; +} + +// Tempo functions + +void set_tempo(uint8_t tempo) { + note_tempo = tempo; +} + +void decrease_tempo(uint8_t tempo_change) { + note_tempo += tempo_change; +} + +void increase_tempo(uint8_t tempo_change) { + if (note_tempo - tempo_change < 10) { + note_tempo = 10; + } else { + note_tempo -= tempo_change; + } +} + + +//------------------------------------------------------------------------------ +// Override these functions in your keymap file to play different tunes on +// startup and bootloader jump +__attribute__ ((weak)) +void play_startup_tone() +{ +} + +__attribute__ ((weak)) +void play_goodbye_tone() +{ +} +//------------------------------------------------------------------------------ diff --git a/quantum/audio/frequency_lut.h b/quantum/audio/frequency_lut.h deleted file mode 100644 index e62da5be4..000000000 --- a/quantum/audio/frequency_lut.h +++ /dev/null @@ -1,357 +0,0 @@ -#include -#include -#include - -#define FREQUENCY_LUT_LENGTH 349 - -const uint16_t FREQUENCY_LUT[FREQUENCY_LUT_LENGTH] = { -0x8E0B, -0x8C02, -0x8A00, -0x8805, -0x8612, -0x8426, -0x8241, -0x8063, -0x7E8C, -0x7CBB, -0x7AF2, -0x792E, -0x7772, -0x75BB, -0x740B, -0x7261, -0x70BD, -0x6F20, -0x6D88, -0x6BF6, -0x6A69, -0x68E3, -0x6762, -0x65E6, -0x6470, -0x6300, -0x6194, -0x602E, -0x5ECD, -0x5D71, -0x5C1A, -0x5AC8, -0x597B, -0x5833, -0x56EF, -0x55B0, -0x5475, -0x533F, -0x520E, -0x50E1, -0x4FB8, -0x4E93, -0x4D73, -0x4C57, -0x4B3E, -0x4A2A, -0x491A, -0x480E, -0x4705, -0x4601, -0x4500, -0x4402, -0x4309, -0x4213, -0x4120, -0x4031, -0x3F46, -0x3E5D, -0x3D79, -0x3C97, -0x3BB9, -0x3ADD, -0x3A05, -0x3930, -0x385E, -0x3790, -0x36C4, -0x35FB, -0x3534, -0x3471, -0x33B1, -0x32F3, -0x3238, -0x3180, -0x30CA, -0x3017, -0x2F66, -0x2EB8, -0x2E0D, -0x2D64, -0x2CBD, -0x2C19, -0x2B77, -0x2AD8, -0x2A3A, -0x299F, -0x2907, -0x2870, -0x27DC, -0x2749, -0x26B9, -0x262B, -0x259F, -0x2515, -0x248D, -0x2407, -0x2382, -0x2300, -0x2280, -0x2201, -0x2184, -0x2109, -0x2090, -0x2018, -0x1FA3, -0x1F2E, -0x1EBC, -0x1E4B, -0x1DDC, -0x1D6E, -0x1D02, -0x1C98, -0x1C2F, -0x1BC8, -0x1B62, -0x1AFD, -0x1A9A, -0x1A38, -0x19D8, -0x1979, -0x191C, -0x18C0, -0x1865, -0x180B, -0x17B3, -0x175C, -0x1706, -0x16B2, -0x165E, -0x160C, -0x15BB, -0x156C, -0x151D, -0x14CF, -0x1483, -0x1438, -0x13EE, -0x13A4, -0x135C, -0x1315, -0x12CF, -0x128A, -0x1246, -0x1203, -0x11C1, -0x1180, -0x1140, -0x1100, -0x10C2, -0x1084, -0x1048, -0x100C, -0xFD1, -0xF97, -0xF5E, -0xF25, -0xEEE, -0xEB7, -0xE81, -0xE4C, -0xE17, -0xDE4, -0xDB1, -0xD7E, -0xD4D, -0xD1C, -0xCEC, -0xCBC, -0xC8E, -0xC60, -0xC32, -0xC05, -0xBD9, -0xBAE, -0xB83, -0xB59, -0xB2F, -0xB06, -0xADD, -0xAB6, -0xA8E, -0xA67, -0xA41, -0xA1C, -0x9F7, -0x9D2, -0x9AE, -0x98A, -0x967, -0x945, -0x923, -0x901, -0x8E0, -0x8C0, -0x8A0, -0x880, -0x861, -0x842, -0x824, -0x806, -0x7E8, -0x7CB, -0x7AF, -0x792, -0x777, -0x75B, -0x740, -0x726, -0x70B, -0x6F2, -0x6D8, -0x6BF, -0x6A6, -0x68E, -0x676, -0x65E, -0x647, -0x630, -0x619, -0x602, -0x5EC, -0x5D7, -0x5C1, -0x5AC, -0x597, -0x583, -0x56E, -0x55B, -0x547, -0x533, -0x520, -0x50E, -0x4FB, -0x4E9, -0x4D7, -0x4C5, -0x4B3, -0x4A2, -0x491, -0x480, -0x470, -0x460, -0x450, -0x440, -0x430, -0x421, -0x412, -0x403, -0x3F4, -0x3E5, -0x3D7, -0x3C9, -0x3BB, -0x3AD, -0x3A0, -0x393, -0x385, -0x379, -0x36C, -0x35F, -0x353, -0x347, -0x33B, -0x32F, -0x323, -0x318, -0x30C, -0x301, -0x2F6, -0x2EB, -0x2E0, -0x2D6, -0x2CB, -0x2C1, -0x2B7, -0x2AD, -0x2A3, -0x299, -0x290, -0x287, -0x27D, -0x274, -0x26B, -0x262, -0x259, -0x251, -0x248, -0x240, -0x238, -0x230, -0x228, -0x220, -0x218, -0x210, -0x209, -0x201, -0x1FA, -0x1F2, -0x1EB, -0x1E4, -0x1DD, -0x1D6, -0x1D0, -0x1C9, -0x1C2, -0x1BC, -0x1B6, -0x1AF, -0x1A9, -0x1A3, -0x19D, -0x197, -0x191, -0x18C, -0x186, -0x180, -0x17B, -0x175, -0x170, -0x16B, -0x165, -0x160, -0x15B, -0x156, -0x151, -0x14C, -0x148, -0x143, -0x13E, -0x13A, -0x135, -0x131, -0x12C, -0x128, -0x124, -0x120, -0x11C, -0x118, -0x114, -0x110, -0x10C, -0x108, -0x104, -0x100, -0xFD, -0xF9, -0xF5, -0xF2, -0xEE -}; \ No newline at end of file diff --git a/quantum/audio/luts.c b/quantum/audio/luts.c new file mode 100644 index 000000000..9f3de9a05 --- /dev/null +++ b/quantum/audio/luts.c @@ -0,0 +1,382 @@ +#include +#include +#include +#include "luts.h" + +const float vibrato_lut[VIBRATO_LUT_LENGTH] = +{ + 1.0022336811487, + 1.0042529943610, + 1.0058584256028, + 1.0068905285205, + 1.0072464122237, + 1.0068905285205, + 1.0058584256028, + 1.0042529943610, + 1.0022336811487, + 1.0000000000000, + 0.9977712970630, + 0.9957650169978, + 0.9941756956510, + 0.9931566259436, + 0.9928057204913, + 0.9931566259436, + 0.9941756956510, + 0.9957650169978, + 0.9977712970630, + 1.0000000000000, +}; + +const uint16_t frequency_lut[FREQUENCY_LUT_LENGTH] = +{ + 0x8E0B, + 0x8C02, + 0x8A00, + 0x8805, + 0x8612, + 0x8426, + 0x8241, + 0x8063, + 0x7E8C, + 0x7CBB, + 0x7AF2, + 0x792E, + 0x7772, + 0x75BB, + 0x740B, + 0x7261, + 0x70BD, + 0x6F20, + 0x6D88, + 0x6BF6, + 0x6A69, + 0x68E3, + 0x6762, + 0x65E6, + 0x6470, + 0x6300, + 0x6194, + 0x602E, + 0x5ECD, + 0x5D71, + 0x5C1A, + 0x5AC8, + 0x597B, + 0x5833, + 0x56EF, + 0x55B0, + 0x5475, + 0x533F, + 0x520E, + 0x50E1, + 0x4FB8, + 0x4E93, + 0x4D73, + 0x4C57, + 0x4B3E, + 0x4A2A, + 0x491A, + 0x480E, + 0x4705, + 0x4601, + 0x4500, + 0x4402, + 0x4309, + 0x4213, + 0x4120, + 0x4031, + 0x3F46, + 0x3E5D, + 0x3D79, + 0x3C97, + 0x3BB9, + 0x3ADD, + 0x3A05, + 0x3930, + 0x385E, + 0x3790, + 0x36C4, + 0x35FB, + 0x3534, + 0x3471, + 0x33B1, + 0x32F3, + 0x3238, + 0x3180, + 0x30CA, + 0x3017, + 0x2F66, + 0x2EB8, + 0x2E0D, + 0x2D64, + 0x2CBD, + 0x2C19, + 0x2B77, + 0x2AD8, + 0x2A3A, + 0x299F, + 0x2907, + 0x2870, + 0x27DC, + 0x2749, + 0x26B9, + 0x262B, + 0x259F, + 0x2515, + 0x248D, + 0x2407, + 0x2382, + 0x2300, + 0x2280, + 0x2201, + 0x2184, + 0x2109, + 0x2090, + 0x2018, + 0x1FA3, + 0x1F2E, + 0x1EBC, + 0x1E4B, + 0x1DDC, + 0x1D6E, + 0x1D02, + 0x1C98, + 0x1C2F, + 0x1BC8, + 0x1B62, + 0x1AFD, + 0x1A9A, + 0x1A38, + 0x19D8, + 0x1979, + 0x191C, + 0x18C0, + 0x1865, + 0x180B, + 0x17B3, + 0x175C, + 0x1706, + 0x16B2, + 0x165E, + 0x160C, + 0x15BB, + 0x156C, + 0x151D, + 0x14CF, + 0x1483, + 0x1438, + 0x13EE, + 0x13A4, + 0x135C, + 0x1315, + 0x12CF, + 0x128A, + 0x1246, + 0x1203, + 0x11C1, + 0x1180, + 0x1140, + 0x1100, + 0x10C2, + 0x1084, + 0x1048, + 0x100C, + 0xFD1, + 0xF97, + 0xF5E, + 0xF25, + 0xEEE, + 0xEB7, + 0xE81, + 0xE4C, + 0xE17, + 0xDE4, + 0xDB1, + 0xD7E, + 0xD4D, + 0xD1C, + 0xCEC, + 0xCBC, + 0xC8E, + 0xC60, + 0xC32, + 0xC05, + 0xBD9, + 0xBAE, + 0xB83, + 0xB59, + 0xB2F, + 0xB06, + 0xADD, + 0xAB6, + 0xA8E, + 0xA67, + 0xA41, + 0xA1C, + 0x9F7, + 0x9D2, + 0x9AE, + 0x98A, + 0x967, + 0x945, + 0x923, + 0x901, + 0x8E0, + 0x8C0, + 0x8A0, + 0x880, + 0x861, + 0x842, + 0x824, + 0x806, + 0x7E8, + 0x7CB, + 0x7AF, + 0x792, + 0x777, + 0x75B, + 0x740, + 0x726, + 0x70B, + 0x6F2, + 0x6D8, + 0x6BF, + 0x6A6, + 0x68E, + 0x676, + 0x65E, + 0x647, + 0x630, + 0x619, + 0x602, + 0x5EC, + 0x5D7, + 0x5C1, + 0x5AC, + 0x597, + 0x583, + 0x56E, + 0x55B, + 0x547, + 0x533, + 0x520, + 0x50E, + 0x4FB, + 0x4E9, + 0x4D7, + 0x4C5, + 0x4B3, + 0x4A2, + 0x491, + 0x480, + 0x470, + 0x460, + 0x450, + 0x440, + 0x430, + 0x421, + 0x412, + 0x403, + 0x3F4, + 0x3E5, + 0x3D7, + 0x3C9, + 0x3BB, + 0x3AD, + 0x3A0, + 0x393, + 0x385, + 0x379, + 0x36C, + 0x35F, + 0x353, + 0x347, + 0x33B, + 0x32F, + 0x323, + 0x318, + 0x30C, + 0x301, + 0x2F6, + 0x2EB, + 0x2E0, + 0x2D6, + 0x2CB, + 0x2C1, + 0x2B7, + 0x2AD, + 0x2A3, + 0x299, + 0x290, + 0x287, + 0x27D, + 0x274, + 0x26B, + 0x262, + 0x259, + 0x251, + 0x248, + 0x240, + 0x238, + 0x230, + 0x228, + 0x220, + 0x218, + 0x210, + 0x209, + 0x201, + 0x1FA, + 0x1F2, + 0x1EB, + 0x1E4, + 0x1DD, + 0x1D6, + 0x1D0, + 0x1C9, + 0x1C2, + 0x1BC, + 0x1B6, + 0x1AF, + 0x1A9, + 0x1A3, + 0x19D, + 0x197, + 0x191, + 0x18C, + 0x186, + 0x180, + 0x17B, + 0x175, + 0x170, + 0x16B, + 0x165, + 0x160, + 0x15B, + 0x156, + 0x151, + 0x14C, + 0x148, + 0x143, + 0x13E, + 0x13A, + 0x135, + 0x131, + 0x12C, + 0x128, + 0x124, + 0x120, + 0x11C, + 0x118, + 0x114, + 0x110, + 0x10C, + 0x108, + 0x104, + 0x100, + 0xFD, + 0xF9, + 0xF5, + 0xF2, + 0xEE, +}; + diff --git a/quantum/audio/luts.h b/quantum/audio/luts.h new file mode 100644 index 000000000..7df3078a7 --- /dev/null +++ b/quantum/audio/luts.h @@ -0,0 +1,15 @@ +#include +#include +#include + +#ifndef LUTS_H +#define LUTS_H + +#define VIBRATO_LUT_LENGTH 20 + +#define FREQUENCY_LUT_LENGTH 349 + +extern const float vibrato_lut[VIBRATO_LUT_LENGTH]; +extern const uint16_t frequency_lut[FREQUENCY_LUT_LENGTH]; + +#endif /* LUTS_H */ \ No newline at end of file diff --git a/quantum/audio/vibrato_lut.h b/quantum/audio/vibrato_lut.h deleted file mode 100644 index a2b1f3e5c..000000000 --- a/quantum/audio/vibrato_lut.h +++ /dev/null @@ -1,28 +0,0 @@ -#include -#include -#include - -#define VIBRATO_LUT_LENGTH 20 - -const float VIBRATO_LUT[VIBRATO_LUT_LENGTH] = { \ -1.00223368114872, -1.00425299436105, -1.00585842560279, -1.00689052852052, -1.0072464122237, -1.00689052852052, -1.00585842560279, -1.00425299436105, -1.00223368114872, -1, -0.99777129706302, -0.99576501699778, -0.994175695650927, -0.993156625943589, -0.992805720491269, -0.993156625943589, -0.994175695650927, -0.99576501699778, -0.99777129706302, -1 -}; \ No newline at end of file diff --git a/quantum/audio/voices.c b/quantum/audio/voices.c index d2316ba1b..6d4172a06 100644 --- a/quantum/audio/voices.c +++ b/quantum/audio/voices.c @@ -1,6 +1,6 @@ #include "voices.h" +#include "audio.h" #include "stdlib.h" -#include "vibrato_lut.h" // these are imported from audio.c extern uint16_t envelope_index; @@ -109,7 +109,7 @@ float voice_envelope(float frequency) { case 0 ... VOICE_VIBRATO_DELAY: break; default: - frequency = frequency * VIBRATO_LUT[(int)fmod((((float)compensated_index - (VOICE_VIBRATO_DELAY + 1))/1000*VOICE_VIBRATO_SPEED), VIBRATO_LUT_LENGTH)]; + frequency = frequency * vibrato_lut[(int)fmod((((float)compensated_index - (VOICE_VIBRATO_DELAY + 1))/1000*VOICE_VIBRATO_SPEED), VIBRATO_LUT_LENGTH)]; break; } break; @@ -160,4 +160,6 @@ float voice_envelope(float frequency) { } return frequency; -} \ No newline at end of file +} + + diff --git a/quantum/audio/voices.h b/quantum/audio/voices.h index 74c873f42..b2495b23b 100644 --- a/quantum/audio/voices.h +++ b/quantum/audio/voices.h @@ -2,8 +2,7 @@ #include #include #include -#include "musical_notes.h" -#include "song_list.h" +#include "luts.h" #ifndef VOICES_H #define VOICES_H diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c index 4b4bd6210..5e78d1157 100644 --- a/quantum/keymap_common.c +++ b/quantum/keymap_common.c @@ -24,10 +24,14 @@ along with this program. If not, see . #include "action_macro.h" #include "debug.h" #include "backlight.h" -#include "keymap_midi.h" #include "bootloader.h" #include "eeconfig.h" +#ifdef MIDI_ENABLE + #include "keymap_midi.h" +#endif + + extern keymap_config_t keymap_config; #include diff --git a/quantum/quantum.mk b/quantum/quantum.mk index 83c4f1d1d..4a076eca4 100644 --- a/quantum/quantum.mk +++ b/quantum/quantum.mk @@ -29,6 +29,7 @@ endif ifeq ($(strip $(AUDIO_ENABLE)), yes) SRC += $(QUANTUM_DIR)/audio/audio.c $(QUANTUM_DIR)/audio/voices.c + SRC += $(QUANTUM_DIR)/audio/audio.c $(QUANTUM_DIR)/audio/luts.c endif ifeq ($(strip $(UNICODE_ENABLE)), yes) -- cgit v1.2.3-24-g4f1b From d4520cd3ac7550fc7243e9a76824d9ba674875c6 Mon Sep 17 00:00:00 2001 From: Tom Duckering Date: Thu, 5 May 2016 23:27:28 +0100 Subject: Referencing the hex file (#309) Seems that this is a typo. When I used the hex file it worked so presuming that means it's right ;) --- quantum/tools/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'quantum') diff --git a/quantum/tools/README.md b/quantum/tools/README.md index 070214423..5f355256d 100644 --- a/quantum/tools/README.md +++ b/quantum/tools/README.md @@ -1,6 +1,6 @@ `eeprom_reset.hex` is to reset the eeprom on the Atmega32u4, like this: dfu-programmer atmega32u4 erase - dfu-programmer atmega32u4 flash --eeprom eeprom-reset.bin + dfu-programmer atmega32u4 flash --eeprom eeprom_reset.hex - You'll need to reflash afterwards, because DFU requires the flash to be erased before messing with the eeprom. \ No newline at end of file + You'll need to reflash afterwards, because DFU requires the flash to be erased before messing with the eeprom. -- cgit v1.2.3-24-g4f1b From 41b3e399b1d43db9574c6016951d92974b3d93e7 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Thu, 5 May 2016 21:50:51 -0400 Subject: adds keycode shortcuts for OSL and OSM --- quantum/keymap_common.c | 8 ++++++++ quantum/keymap_common.h | 6 ++++++ 2 files changed, 14 insertions(+) (limited to 'quantum') diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c index 5e78d1157..8f00f9cc3 100644 --- a/quantum/keymap_common.c +++ b/quantum/keymap_common.c @@ -272,6 +272,14 @@ static action_t keycode_to_action(uint16_t keycode) // Set default layer int layer = keycode & 0xFF; action.code = ACTION_LAYER_TOGGLE(layer); + } else if (type == 0x5) { + // OSL(layer) - One-shot layer + int layer = keycode & 0xFF; + action.code = ACTION_LAYER_ONESHOT(layer); + } else if (type == 0x6) { + // OSM(mod) - One-shot mod + int mod = keycode & 0xFF; + action.code = ACTION_MODS_ONESHOT(mod); } break; #ifdef MIDI_ENABLE diff --git a/quantum/keymap_common.h b/quantum/keymap_common.h index 0ede0296b..ae10bc78d 100644 --- a/quantum/keymap_common.h +++ b/quantum/keymap_common.h @@ -205,6 +205,12 @@ extern const uint16_t fn_actions[]; // Toggle to layer - 256 layer max #define TG(layer) (layer | 0x5400) +// One-shot layer - 256 layer max +#define OSL(layer) (layer | 0x5500) + +// One-shot mod +#define OSM(layer) (layer | 0x5600) + // M-od, T-ap - 256 keycode max #define MT(mod, kc) (kc | 0x7000 | ((mod & 0xF) << 8)) #define CTL_T(kc) MT(0x1, kc) -- cgit v1.2.3-24-g4f1b From f293bf23404ea380e779a791e8c6a78d0a2fc45e Mon Sep 17 00:00:00 2001 From: Erez Zukerman Date: Thu, 5 May 2016 22:19:29 -0400 Subject: [Jack & Erez] Removes duplicate reference, sorts whitespace --- quantum/quantum.mk | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'quantum') diff --git a/quantum/quantum.mk b/quantum/quantum.mk index 4a076eca4..ff34c463a 100644 --- a/quantum/quantum.mk +++ b/quantum/quantum.mk @@ -28,8 +28,9 @@ ifeq ($(strip $(MIDI_ENABLE)), yes) endif ifeq ($(strip $(AUDIO_ENABLE)), yes) - SRC += $(QUANTUM_DIR)/audio/audio.c $(QUANTUM_DIR)/audio/voices.c - SRC += $(QUANTUM_DIR)/audio/audio.c $(QUANTUM_DIR)/audio/luts.c + SRC += $(QUANTUM_DIR)/audio/audio.c + SRC += $(QUANTUM_DIR)/audio/voices.c + SRC += $(QUANTUM_DIR)/audio/luts.c endif ifeq ($(strip $(UNICODE_ENABLE)), yes) -- cgit v1.2.3-24-g4f1b From 9bb368a5fb55e069aafb49007871a7045e6d964f Mon Sep 17 00:00:00 2001 From: Erez Zukerman Date: Thu, 5 May 2016 22:44:24 -0400 Subject: [Jack & Erez] Defines MOD_HYPR and MOD_MEH --- quantum/keymap_common.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'quantum') diff --git a/quantum/keymap_common.h b/quantum/keymap_common.h index ae10bc78d..ab80ea45c 100644 --- a/quantum/keymap_common.h +++ b/quantum/keymap_common.h @@ -67,6 +67,9 @@ extern const uint16_t fn_actions[]; #define MEH(kc) kc | 0x0700 #define LCAG(kc) kc | 0x0D00 // Modifier Ctrl Alt and GUI +#define MOD_HYPR 0xf +#define MOD_MEH 0x7 + #define RCTL(kc) kc | 0x1100 #define RSFT(kc) kc | 0x1200 #define RALT(kc) kc | 0x1400 -- cgit v1.2.3-24-g4f1b From 08f31424634d5b614b69e3bb965ab50bdccd6d01 Mon Sep 17 00:00:00 2001 From: Nathan Sharfi Date: Fri, 6 May 2016 05:40:02 -0700 Subject: Add KC_LABK and KC_RABK (< and >) --- quantum/keymap_common.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'quantum') diff --git a/quantum/keymap_common.h b/quantum/keymap_common.h index 0ede0296b..ffd8168f6 100644 --- a/quantum/keymap_common.h +++ b/quantum/keymap_common.h @@ -118,6 +118,12 @@ extern const uint16_t fn_actions[]; #define KC_RCBR LSFT(KC_RBRC) // } #define KC_RIGHT_CURLY_BRACE KC_RCBR +#define KC_LABK LSFT(KC_COMM) // < +#define KC_LEFT_ANGLE_BRACKET KC_LABK + +#define KC_RABK LSFT(KC_DOT) // > +#define KC_RIGHT_ANGLE_BRACKET KC_RABK + #define KC_COLN LSFT(KC_SCLN) // : #define KC_COLON KC_COLN -- cgit v1.2.3-24-g4f1b From 684793360cdb08ac1e50a6d27e1796fadd527adb Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Mon, 9 May 2016 00:36:23 -0400 Subject: quantum accommodates more than 16 columns --- quantum/matrix.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'quantum') diff --git a/quantum/matrix.c b/quantum/matrix.c index 2dab6ae94..7d70f728d 100644 --- a/quantum/matrix.c +++ b/quantum/matrix.c @@ -42,6 +42,13 @@ static matrix_row_t matrix_debouncing[MATRIX_ROWS]; static matrix_row_t matrix_reversed_debouncing[MATRIX_COLS]; #endif + +#if MATRIX_COLS > 16 + #define SHIFTER 1UL +#else + #define SHIFTER 1 +#endif + static matrix_row_t read_cols(void); static void init_cols(void); static void unselect_rows(void); @@ -235,15 +242,15 @@ static matrix_row_t read_cols(void) #endif if ((col & 0xF0) == 0x20) { - result |= (PINB&(1<<(col & 0x0F)) ? 0 : (1< Date: Mon, 9 May 2016 13:17:15 -0400 Subject: Backlight Breathing for Planck and Atomic * Updated personal layouts * tweaked personal * Nightly - Audio Cleanup Refactored the LUTs. Abstracted some of the registers out of audio to use more functional names. Split audio into audio and audio_pwm. WIP * nightly - collapsed code * Added check for note playing to LEDs * Usability tweaks * TWEAE * nightly added extra kcs to keymap common * turned on Plank audio * Added backlight breathing to atomic * reverted accidental merge * adds backlight pulse to planck --- quantum/audio/audio.c | 4 ++++ quantum/audio/audio.h | 11 ++++++----- quantum/keymap_common.h | 18 ++++++++++++++++++ quantum/keymap_midi.h | 10 +++++----- quantum/quantum.mk | 6 +++--- 5 files changed, 36 insertions(+), 13 deletions(-) (limited to 'quantum') diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index 3a7f0f556..27b64f8c9 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -374,6 +374,10 @@ bool is_playing_notes(void) { return playing_notes; } +bool is_audio_on(void) { + return (audio_config.enable != 0); +} + void audio_toggle(void) { audio_config.enable ^= 1; eeconfig_update_audio(audio_config.raw); diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index 3d706587a..4ba879bbb 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -25,6 +25,7 @@ typedef union { }; } audio_config_t; +bool is_audio_on(void); void audio_toggle(void); void audio_on(void); void audio_off(void); @@ -71,11 +72,11 @@ void stop_note(float freq); void stop_all_notes(void); void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat, float n_rest); -#define SCALE (int []){ 0 + (12*0), 2 + (12*0), 4 + (12*0), 5 + (12*0), 7 + (12*0), 9 + (12*0), 11 + (12*0), \ - 0 + (12*1), 2 + (12*1), 4 + (12*1), 5 + (12*1), 7 + (12*1), 9 + (12*1), 11 + (12*1), \ - 0 + (12*2), 2 + (12*2), 4 + (12*2), 5 + (12*2), 7 + (12*2), 9 + (12*2), 11 + (12*2), \ - 0 + (12*3), 2 + (12*3), 4 + (12*3), 5 + (12*3), 7 + (12*3), 9 + (12*3), 11 + (12*3), \ - 0 + (12*4), 2 + (12*4), 4 + (12*4), 5 + (12*4), 7 + (12*4), 9 + (12*4), 11 + (12*4), } +#define SCALE (int8_t []){ 0 + (12*0), 2 + (12*0), 4 + (12*0), 5 + (12*0), 7 + (12*0), 9 + (12*0), 11 + (12*0), \ + 0 + (12*1), 2 + (12*1), 4 + (12*1), 5 + (12*1), 7 + (12*1), 9 + (12*1), 11 + (12*1), \ + 0 + (12*2), 2 + (12*2), 4 + (12*2), 5 + (12*2), 7 + (12*2), 9 + (12*2), 11 + (12*2), \ + 0 + (12*3), 2 + (12*3), 4 + (12*3), 5 + (12*3), 7 + (12*3), 9 + (12*3), 11 + (12*3), \ + 0 + (12*4), 2 + (12*4), 4 + (12*4), 5 + (12*4), 7 + (12*4), 9 + (12*4), 11 + (12*4), } // These macros are used to allow play_notes to play an array of indeterminate // length. This works around the limitation of C's sizeof operation on pointers. diff --git a/quantum/keymap_common.h b/quantum/keymap_common.h index 8c27e9035..322fda498 100644 --- a/quantum/keymap_common.h +++ b/quantum/keymap_common.h @@ -87,8 +87,11 @@ extern const uint16_t fn_actions[]; #define KC_EXCLAIM KC_EXLM #define KC_AT LSFT(KC_2) // @ + + #define KC_HASH LSFT(KC_3) // # + #define KC_DLR LSFT(KC_4) // $ #define KC_DOLLAR KC_DLR @@ -110,11 +113,13 @@ extern const uint16_t fn_actions[]; #define KC_RPRN LSFT(KC_0) // ) #define KC_RIGHT_PAREN KC_RPRN + #define KC_UNDS LSFT(KC_MINS) // _ #define KC_UNDERSCORE KC_UNDS #define KC_PLUS LSFT(KC_EQL) // + + #define KC_LCBR LSFT(KC_LBRC) // { #define KC_LEFT_CURLY_BRACE KC_LCBR @@ -132,6 +137,19 @@ extern const uint16_t fn_actions[]; #define KC_PIPE LSFT(KC_BSLS) // | +#define KC_LT LSFT(KC_COMM) // < + + +#define KC_GT LSFT(KC_DOT) // > + + +#define KC_QUES LSFT(KC_SLSH) // ? +#define KC_QUESTION KC_QUES + + +#define KC_DQT LSFT(KC_QUOT) // " +#define KC_DOUBLE_QUOTE KC_DQT + #define KC_DELT KC_DELETE // Del key (four letter code) // Alias for function layers than expand past FN31 diff --git a/quantum/keymap_midi.h b/quantum/keymap_midi.h index 795f26380..3a2bf3aff 100644 --- a/quantum/keymap_midi.h +++ b/quantum/keymap_midi.h @@ -25,11 +25,11 @@ along with this program. If not, see . #define CHNL(note, channel) (note + (channel << 8)) -#define SCALE (int []){ 0 + (12*0), 2 + (12*0), 4 + (12*0), 5 + (12*0), 7 + (12*0), 9 + (12*0), 11 + (12*0), \ - 0 + (12*1), 2 + (12*1), 4 + (12*1), 5 + (12*1), 7 + (12*1), 9 + (12*1), 11 + (12*1), \ - 0 + (12*2), 2 + (12*2), 4 + (12*2), 5 + (12*2), 7 + (12*2), 9 + (12*2), 11 + (12*2), \ - 0 + (12*3), 2 + (12*3), 4 + (12*3), 5 + (12*3), 7 + (12*3), 9 + (12*3), 11 + (12*3), \ - 0 + (12*4), 2 + (12*4), 4 + (12*4), 5 + (12*4), 7 + (12*4), 9 + (12*4), 11 + (12*4), } +#define SCALE (int8_t []){ 0 + (12*0), 2 + (12*0), 4 + (12*0), 5 + (12*0), 7 + (12*0), 9 + (12*0), 11 + (12*0), \ + 0 + (12*1), 2 + (12*1), 4 + (12*1), 5 + (12*1), 7 + (12*1), 9 + (12*1), 11 + (12*1), \ + 0 + (12*2), 2 + (12*2), 4 + (12*2), 5 + (12*2), 7 + (12*2), 9 + (12*2), 11 + (12*2), \ + 0 + (12*3), 2 + (12*3), 4 + (12*3), 5 + (12*3), 7 + (12*3), 9 + (12*3), 11 + (12*3), \ + 0 + (12*4), 2 + (12*4), 4 + (12*4), 5 + (12*4), 7 + (12*4), 9 + (12*4), 11 + (12*4), } #define N_CN1 (0x600C + (12 * -1) + 0 ) #define N_CN1S (0x600C + (12 * -1) + 1 ) diff --git a/quantum/quantum.mk b/quantum/quantum.mk index ff34c463a..5f4c2f045 100644 --- a/quantum/quantum.mk +++ b/quantum/quantum.mk @@ -28,9 +28,9 @@ ifeq ($(strip $(MIDI_ENABLE)), yes) endif ifeq ($(strip $(AUDIO_ENABLE)), yes) - SRC += $(QUANTUM_DIR)/audio/audio.c - SRC += $(QUANTUM_DIR)/audio/voices.c - SRC += $(QUANTUM_DIR)/audio/luts.c + SRC += $(QUANTUM_DIR)/audio/audio.c + SRC += $(QUANTUM_DIR)/audio/voices.c + SRC += $(QUANTUM_DIR)/audio/luts.c endif ifeq ($(strip $(UNICODE_ENABLE)), yes) -- cgit v1.2.3-24-g4f1b From 1a8c0dd22d6a2255511d0db6a456315541b5815b Mon Sep 17 00:00:00 2001 From: Erez Zukerman Date: Sun, 15 May 2016 00:27:32 -0400 Subject: Leader key implementation (#326) * implements leader key for planck experimental * allows override of leader timeout * adds ability to use the leader key in seq * fixes leader keycode * adds chording prototype * fixes keycode detection * moves music mode to quantum.c * disables chording by default * updates process_action functions to return bool --- quantum/keymap_common.c | 2 +- quantum/keymap_common.h | 4 +- quantum/matrix.c | 8 +-- quantum/quantum.c | 167 ++++++++++++++++++++++++++++++++++++++++++++ quantum/quantum.h | 48 +++++++++++++ quantum/quantum.mk | 3 +- quantum/template/template.c | 7 +- quantum/template/template.h | 2 +- 8 files changed, 230 insertions(+), 11 deletions(-) create mode 100644 quantum/quantum.c create mode 100644 quantum/quantum.h (limited to 'quantum') diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c index 8f00f9cc3..0184770c4 100644 --- a/quantum/keymap_common.c +++ b/quantum/keymap_common.c @@ -251,7 +251,7 @@ static action_t keycode_to_action(uint16_t keycode) } eeconfig_update_keymap(keymap_config.raw); break; - case 0x5100 ... 0x5FFF: ; + case 0x5100 ... 0x56FF: ; // Layer movement shortcuts // See .h to see constraints/usage int type = (keycode >> 0x8) & 0xF; diff --git a/quantum/keymap_common.h b/quantum/keymap_common.h index 322fda498..2ad1ba6c6 100644 --- a/quantum/keymap_common.h +++ b/quantum/keymap_common.h @@ -159,7 +159,7 @@ extern const uint16_t fn_actions[]; #define S(kc) LSFT(kc) #define F(kc) FUNC(kc) -#define M(kc) kc | 0x3000 +#define M(kc) (kc | 0x3000) #define MACRODOWN(...) (record->event.pressed ? MACRO(__VA_ARGS__) : MACRO_NONE) @@ -191,6 +191,8 @@ extern const uint16_t fn_actions[]; #define RESET 0x5000 #define DEBUG 0x5001 +#define KC_LEAD 0x5014 + // MAGIC keycodes #define MAGIC_SWAP_CONTROL_CAPSLOCK 0x5002 diff --git a/quantum/matrix.c b/quantum/matrix.c index 7d70f728d..cab39e117 100644 --- a/quantum/matrix.c +++ b/quantum/matrix.c @@ -55,12 +55,12 @@ static void unselect_rows(void); static void select_row(uint8_t row); __attribute__ ((weak)) -void matrix_init_kb(void) { +void matrix_init_quantum(void) { } __attribute__ ((weak)) -void matrix_scan_kb(void) { +void matrix_scan_quantum(void) { } @@ -93,7 +93,7 @@ void matrix_init(void) matrix_debouncing[i] = 0; } - matrix_init_kb(); + matrix_init_quantum(); } @@ -157,7 +157,7 @@ uint8_t matrix_scan(void) } #endif - matrix_scan_kb(); + matrix_scan_quantum(); return 1; } diff --git a/quantum/quantum.c b/quantum/quantum.c new file mode 100644 index 000000000..e274d846f --- /dev/null +++ b/quantum/quantum.c @@ -0,0 +1,167 @@ +#include "quantum.h" + +__attribute__ ((weak)) +void matrix_init_kb(void) {} + +__attribute__ ((weak)) +void matrix_scan_kb(void) {} + +__attribute__ ((weak)) +bool process_action_kb(keyrecord_t *record) { + return true; +} + +__attribute__ ((weak)) +void leader_start(void) {} + +__attribute__ ((weak)) +void leader_end(void) {} + +#ifdef AUDIO_ENABLE + uint8_t starting_note = 0x0C; + int offset = 0; + bool music_activated = false; +#endif + +// Leader key stuff +bool leading = false; +uint16_t leader_time = 0; + +uint16_t leader_sequence[3] = {0, 0, 0}; +uint8_t leader_sequence_size = 0; + +// Chording stuff +#define CHORDING_MAX 4 +bool chording = false; + +uint8_t chord_keys[CHORDING_MAX] = {0}; +uint8_t chord_key_count = 0; +uint8_t chord_key_down = 0; + +bool keys_chord(uint8_t keys[]) { + uint8_t keys_size = sizeof(keys)/sizeof(keys[0]); + bool pass = true; + uint8_t in = 0; + for (uint8_t i = 0; i < chord_key_count; i++) { + bool found = false; + for (uint8_t j = 0; j < keys_size; j++) { + if (chord_keys[i] == (keys[j] & 0xFF)) { + in++; // detects key in chord + found = true; + break; + } + } + if (found) + continue; + if (chord_keys[i] != 0) { + pass = false; // makes sure rest are blank + } + } + return (pass && (in == keys_size)); +} + +bool process_action_quantum(keyrecord_t *record) { + + /* This gets the keycode from the key pressed */ + keypos_t key = record->event.key; + uint16_t keycode; + + #if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS) + uint8_t layer; + + if (record->event.pressed) { + layer = layer_switch_get_layer(key); + update_source_layers_cache(key, layer); + } else { + layer = read_source_layers_cache(key); + } + keycode = keymap_key_to_keycode(layer, key); + #else + keycode = keymap_key_to_keycode(layer_switch_get_layer(key), key); + #endif + + #ifdef AUDIO_ENABLE + if (music_activated) { + if (record->event.pressed) { + play_note(((double)220.0)*pow(2.0, -4.0)*pow(2.0,(starting_note + SCALE[record->event.key.col + offset])/12.0+(MATRIX_ROWS - record->event.key.row)), 0xF); + } else { + stop_note(((double)220.0)*pow(2.0, -4.0)*pow(2.0,(starting_note + SCALE[record->event.key.col + offset])/12.0+(MATRIX_ROWS - record->event.key.row))); + } + if (keycode < 0xFF) // ignores all normal keycodes, but lets RAISE, LOWER, etc through + return false; + } + #endif + + + +#ifndef DISABLE_LEADER + // Leader key set-up + if (record->event.pressed) { + if (!leading && keycode == KC_LEAD) { + leader_start(); + leading = true; + leader_time = timer_read(); + leader_sequence_size = 0; + leader_sequence[0] = 0; + leader_sequence[1] = 0; + leader_sequence[2] = 0; + return false; + } + if (leading && timer_elapsed(leader_time) < LEADER_TIMEOUT) { + leader_sequence[leader_sequence_size] = keycode; + leader_sequence_size++; + return false; + } + } +#endif + +#define DISABLE_CHORDING +#ifndef DISABLE_CHORDING + + if (keycode >= 0x5700 && keycode <= 0x57FF) { + if (record->event.pressed) { + if (!chording) { + chording = true; + for (uint8_t i = 0; i < CHORDING_MAX; i++) + chord_keys[i] = 0; + chord_key_count = 0; + chord_key_down = 0; + } + chord_keys[chord_key_count] = (keycode & 0xFF); + chord_key_count++; + chord_key_down++; + return false; + } else { + if (chording) { + chord_key_down--; + if (chord_key_down == 0) { + chording = false; + // Chord Dictionary + if (keys_chord((uint8_t[]){KC_ENTER, KC_SPACE})) { + register_code(KC_A); + unregister_code(KC_A); + return false; + } + for (uint8_t i = 0; i < chord_key_count; i++) { + register_code(chord_keys[i]); + unregister_code(chord_keys[i]); + return false; + } + } + } + } + } + +#endif + + + return process_action_kb(record); +} + +void matrix_init_quantum() { + matrix_init_kb(); +} + +void matrix_scan_quantum() { + matrix_scan_kb(); +} \ No newline at end of file diff --git a/quantum/quantum.h b/quantum/quantum.h new file mode 100644 index 000000000..db726ad42 --- /dev/null +++ b/quantum/quantum.h @@ -0,0 +1,48 @@ +#ifndef QUANTUM_H +#define QUANTUM_H + +#include "matrix.h" +#include "keymap_common.h" +#ifdef BACKLIGHT_ENABLE + #include "backlight.h" +#endif +#ifdef RGBLIGHT_ENABLE + #include "rgblight.h" +#endif +#ifdef AUDIO_ENABLE + #include "audio.h" +#endif +#ifdef MIDI_ENABLE + #include +#endif +#include "action_layer.h" +#include "eeconfig.h" +#include +#include + +extern uint32_t default_layer_state; + +#ifndef NO_ACTION_LAYER + extern uint32_t layer_state; +#endif + +bool music_activated; + +void matrix_init_kb(void); +void matrix_scan_kb(void); +bool process_action_kb(keyrecord_t *record); + +void leader_start(void); +void leader_end(void); + +#ifndef LEADER_TIMEOUT + #define LEADER_TIMEOUT 200 +#endif +#define SEQ_ONE_KEY(key) if (leader_sequence[0] == (key) && leader_sequence[1] == 0 && leader_sequence[2] == 0) +#define SEQ_TWO_KEYS(key1, key2) if (leader_sequence[0] == (key1) && leader_sequence[1] == (key2) && leader_sequence[2] == 0) +#define SEQ_THREE_KEYS(key1, key2, key3) if (leader_sequence[0] == (key1) && leader_sequence[1] == (key2) && leader_sequence[2] == (key3)) + +#define LEADER_EXTERNS() extern bool leading; extern uint16_t leader_time; extern uint16_t leader_sequence[3]; extern uint8_t leader_sequence_size +#define LEADER_DICTIONARY() if (leading && timer_elapsed(leader_time) > LEADER_TIMEOUT) + +#endif \ No newline at end of file diff --git a/quantum/quantum.mk b/quantum/quantum.mk index 5f4c2f045..b45ad850a 100644 --- a/quantum/quantum.mk +++ b/quantum/quantum.mk @@ -1,7 +1,8 @@ QUANTUM_DIR = quantum # # project specific files -SRC += $(QUANTUM_DIR)/keymap_common.c \ +SRC += $(QUANTUM_DIR)/quantum.c \ + $(QUANTUM_DIR)/keymap_common.c \ $(QUANTUM_DIR)/led.c # ifdef KEYMAP_FILE diff --git a/quantum/template/template.c b/quantum/template/template.c index 6050a2d20..649072eb2 100644 --- a/quantum/template/template.c +++ b/quantum/template/template.c @@ -11,8 +11,9 @@ void matrix_scan_user(void) { } __attribute__ ((weak)) -void process_action_user(keyrecord_t *record) { +bool process_action_user(keyrecord_t *record) { // leave this function blank - it can be defined in a keymap file + return true; } __attribute__ ((weak)) @@ -34,11 +35,11 @@ void matrix_scan_kb(void) { matrix_scan_user(); } -void process_action_kb(keyrecord_t *record) { +bool process_action_kb(keyrecord_t *record) { // put your per-action keyboard code here // runs for every action, just before processing by the firmware - process_action_user(record); + return process_action_user(record); } void led_set_kb(uint8_t usb_led) { diff --git a/quantum/template/template.h b/quantum/template/template.h index 22742105a..8537e3b4b 100644 --- a/quantum/template/template.h +++ b/quantum/template/template.h @@ -24,7 +24,7 @@ void matrix_init_user(void); void matrix_scan_user(void); -void process_action_user(keyrecord_t *record); +bool process_action_user(keyrecord_t *record); void led_set_user(uint8_t usb_led); #endif -- cgit v1.2.3-24-g4f1b From 15719f3574c6274ee0f3ec87431927c5a523aa3e Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Sun, 15 May 2016 00:40:59 -0400 Subject: adds a sequencer to the music mode (#330) * implements leader key for planck experimental * allows override of leader timeout * adds ability to use the leader key in seq * fixes leader keycode * adds chording prototype * fixes keycode detection * moves music mode to quantum.c * disables chording by default * adds music sequencer functionality * implements audio/music functions in quantum.c * Merge branch 'master' into process-record --- quantum/audio/audio.c | 11 +++-- quantum/audio/audio.h | 1 + quantum/keymap_common.h | 15 ++++++- quantum/quantum.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 119 insertions(+), 12 deletions(-) (limited to 'quantum') diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index 27b64f8c9..243f49f0e 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -478,12 +478,11 @@ void increase_tempo(uint8_t tempo_change) { // Override these functions in your keymap file to play different tunes on // startup and bootloader jump __attribute__ ((weak)) -void play_startup_tone() -{ -} +void play_startup_tone() {} __attribute__ ((weak)) -void play_goodbye_tone() -{ -} +void play_goodbye_tone() {} + +__attribute__ ((weak)) +void audio_on_callback(void) {} //------------------------------------------------------------------------------ diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index 4ba879bbb..fe8506131 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -29,6 +29,7 @@ bool is_audio_on(void); void audio_toggle(void); void audio_on(void); void audio_off(void); +void audio_on_callback(void); // Vibrato rate functions diff --git a/quantum/keymap_common.h b/quantum/keymap_common.h index 2ad1ba6c6..4107d575b 100644 --- a/quantum/keymap_common.h +++ b/quantum/keymap_common.h @@ -191,8 +191,6 @@ extern const uint16_t fn_actions[]; #define RESET 0x5000 #define DEBUG 0x5001 -#define KC_LEAD 0x5014 - // MAGIC keycodes #define MAGIC_SWAP_CONTROL_CAPSLOCK 0x5002 @@ -217,6 +215,19 @@ extern const uint16_t fn_actions[]; #define AG_SWAP MAGIC_SWAP_ALT_GUI #define AG_NORM MAGIC_UNSWAP_ALT_GUI +#define KC_LEAD 0x5014 + +// Audio on/off +#define AU_ON 0x5020 +#define AU_OFF 0x5021 + +// Music mode on/off +#define MU_ON 0x5022 +#define MU_OFF 0x5023 + +// Music voice iterate +#define MUV_IN 0x5024 +#define MUV_DE 0x5025 // GOTO layer - 16 layers max // when: diff --git a/quantum/quantum.c b/quantum/quantum.c index e274d846f..cd7fdbb7f 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -21,6 +21,7 @@ void leader_end(void) {} uint8_t starting_note = 0x0C; int offset = 0; bool music_activated = false; + float music_scale[][2] = SONG(MUSIC_SCALE_SOUND); #endif // Leader key stuff @@ -60,6 +61,15 @@ bool keys_chord(uint8_t keys[]) { return (pass && (in == keys_size)); } +static bool music_sequence_recording = false; +static bool music_sequence_playing = false; +static float music_sequence[16] = {0}; +static uint8_t music_sequence_count = 0; +static uint8_t music_sequence_position = 0; + +static uint16_t music_sequence_timer = 0; +static uint16_t music_sequence_interval = 100; + bool process_action_quantum(keyrecord_t *record) { /* This gets the keycode from the key pressed */ @@ -81,12 +91,87 @@ bool process_action_quantum(keyrecord_t *record) { #endif #ifdef AUDIO_ENABLE - if (music_activated) { + if (keycode == AU_ON && record->event.pressed) { + audio_on(); + audio_on_callback(); + return false; + } + + if (keycode == AU_OFF && record->event.pressed) { + audio_off(); + return false; + } + + if (keycode == MU_ON && record->event.pressed) { + music_activated = true; + PLAY_NOTE_ARRAY(music_scale, false, 0); + return false; + } + + if (keycode == MU_OFF && record->event.pressed) { + music_activated = false; + stop_all_notes(); + return false; + } + + if (keycode == MUV_IN && record->event.pressed) { + voice_iterate(); + PLAY_NOTE_ARRAY(music_scale, false, 0); + return false; + } + + if (keycode == MUV_DE && record->event.pressed) { + voice_deiterate(); + PLAY_NOTE_ARRAY(music_scale, false, 0); + return false; + } + + if (music_activated) { + + if (keycode == KC_LCTL && record->event.pressed) { // Start recording + stop_all_notes(); + music_sequence_recording = true; + music_sequence_playing = false; + music_sequence_count = 0; + return false; + } + if (keycode == KC_LALT && record->event.pressed) { // Stop recording/playing + stop_all_notes(); + music_sequence_recording = false; + music_sequence_playing = false; + return false; + } + if (keycode == KC_LGUI && record->event.pressed) { // Start playing + stop_all_notes(); + music_sequence_recording = false; + music_sequence_playing = true; + music_sequence_position = 0; + music_sequence_timer = 0; + return false; + } + + if (keycode == KC_UP) { + if (record->event.pressed) + music_sequence_interval-=10; + return false; + } + if (keycode == KC_DOWN) { + if (record->event.pressed) + music_sequence_interval+=10; + return false; + } + + float freq = ((float)220.0)*pow(2.0, -4.0)*pow(2.0,(starting_note + SCALE[record->event.key.col + offset])/12.0+(MATRIX_ROWS - record->event.key.row)); if (record->event.pressed) { - play_note(((double)220.0)*pow(2.0, -4.0)*pow(2.0,(starting_note + SCALE[record->event.key.col + offset])/12.0+(MATRIX_ROWS - record->event.key.row)), 0xF); + play_note(freq, 0xF); + if (music_sequence_recording) { + music_sequence[music_sequence_count] = freq; + music_sequence_count++; + } } else { - stop_note(((double)220.0)*pow(2.0, -4.0)*pow(2.0,(starting_note + SCALE[record->event.key.col + offset])/12.0+(MATRIX_ROWS - record->event.key.row))); - } + stop_note(freq); + } + if (keycode < 0xFF) // ignores all normal keycodes, but lets RAISE, LOWER, etc through return false; } @@ -163,5 +248,16 @@ void matrix_init_quantum() { } void matrix_scan_quantum() { + #ifdef AUDIO_ENABLE + if (music_sequence_playing) { + if ((music_sequence_timer == 0) || (timer_elapsed(music_sequence_timer) > music_sequence_interval)) { + music_sequence_timer = timer_read(); + stop_note(music_sequence[(music_sequence_position - 1 < 0)?(music_sequence_position - 1 + music_sequence_count):(music_sequence_position - 1)]); + play_note(music_sequence[music_sequence_position], 0xF); + music_sequence_position = (music_sequence_position + 1) % music_sequence_count; + } + } + + #endif matrix_scan_kb(); } \ No newline at end of file -- cgit v1.2.3-24-g4f1b From bf5c2ccee5497523c214dae7aacdc27fdbb0f235 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Sun, 15 May 2016 00:47:25 -0400 Subject: splits process_action up to handle records separately (#329) * implements leader key for planck experimental * allows override of leader timeout * adds ability to use the leader key in seq * fixes leader keycode * adds chording prototype * fixes keycode detection * moves music mode to quantum.c * disables chording by default * adds music sequencer functionality * implements audio/music functions in quantum.c * splits up process_action to allow independent processing of actions * merging? --- quantum/keymap_common.h | 3 +++ quantum/quantum.c | 11 ++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'quantum') diff --git a/quantum/keymap_common.h b/quantum/keymap_common.h index 4107d575b..0074ab164 100644 --- a/quantum/keymap_common.h +++ b/quantum/keymap_common.h @@ -191,6 +191,9 @@ extern const uint16_t fn_actions[]; #define RESET 0x5000 #define DEBUG 0x5001 +#define KC_LEAD 0x5014 + + // MAGIC keycodes #define MAGIC_SWAP_CONTROL_CAPSLOCK 0x5002 diff --git a/quantum/quantum.c b/quantum/quantum.c index cd7fdbb7f..dd5d84f82 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -70,7 +70,7 @@ static uint8_t music_sequence_position = 0; static uint16_t music_sequence_timer = 0; static uint16_t music_sequence_interval = 100; -bool process_action_quantum(keyrecord_t *record) { +bool process_record_quantum(keyrecord_t *record) { /* This gets the keycode from the key pressed */ keypos_t key = record->event.key; @@ -90,6 +90,14 @@ bool process_action_quantum(keyrecord_t *record) { keycode = keymap_key_to_keycode(layer_switch_get_layer(key), key); #endif + // This is how you use actions here + // if (keycode == KC_LEAD) { + // action_t action; + // action.code = ACTION_DEFAULT_LAYER_SET(0); + // process_action(record, action); + // return false; + // } + #ifdef AUDIO_ENABLE if (keycode == AU_ON && record->event.pressed) { audio_on(); @@ -259,5 +267,6 @@ void matrix_scan_quantum() { } #endif + matrix_scan_kb(); } \ No newline at end of file -- cgit v1.2.3-24-g4f1b From fde477a927edc6b4207a6968d44aeed021e8b300 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Sun, 15 May 2016 00:51:06 -0400 Subject: updates midi functionality (#331) * implements leader key for planck experimental * allows override of leader timeout * adds ability to use the leader key in seq * fixes leader keycode * adds chording prototype * fixes keycode detection * moves music mode to quantum.c * disables chording by default * adds music sequencer functionality * implements audio/music functions in quantum.c * splits up process_action to allow independent processing of actions * moves midi stuff to quantum.c * adds additional scales for midi --- quantum/keymap_common.c | 5 --- quantum/keymap_common.h | 5 +++ quantum/quantum.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++--- quantum/quantum.h | 3 +- quantum/quantum.mk | 6 ++-- 5 files changed, 93 insertions(+), 14 deletions(-) (limited to 'quantum') diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c index 0184770c4..2aae13e67 100644 --- a/quantum/keymap_common.c +++ b/quantum/keymap_common.c @@ -282,11 +282,6 @@ static action_t keycode_to_action(uint16_t keycode) action.code = ACTION_MODS_ONESHOT(mod); } break; - #ifdef MIDI_ENABLE - case 0x6000 ... 0x6FFF: - action.code = ACTION_FUNCTION_OPT(keycode & 0xFF, (keycode & 0x0F00) >> 8); - break; - #endif case 0x7000 ... 0x7FFF: action.code = ACTION_MODS_TAP_KEY((keycode >> 0x8) & 0xF, keycode & 0xFF); break; diff --git a/quantum/keymap_common.h b/quantum/keymap_common.h index 0074ab164..07020150a 100644 --- a/quantum/keymap_common.h +++ b/quantum/keymap_common.h @@ -195,6 +195,7 @@ extern const uint16_t fn_actions[]; + // MAGIC keycodes #define MAGIC_SWAP_CONTROL_CAPSLOCK 0x5002 #define MAGIC_UNSWAP_CONTROL_CAPSLOCK 0x5003 @@ -232,6 +233,10 @@ extern const uint16_t fn_actions[]; #define MUV_IN 0x5024 #define MUV_DE 0x5025 +// Midi mode on/off +#define MI_ON 0x5026 +#define MI_OFF 0x5027 + // GOTO layer - 16 layers max // when: // ON_PRESS = 1 diff --git a/quantum/quantum.c b/quantum/quantum.c index dd5d84f82..5a978d332 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -19,11 +19,15 @@ void leader_end(void) {} #ifdef AUDIO_ENABLE uint8_t starting_note = 0x0C; - int offset = 0; + int offset = 7; bool music_activated = false; float music_scale[][2] = SONG(MUSIC_SCALE_SOUND); #endif +#ifdef MIDI_ENABLE + bool midi_activated = false; +#endif + // Leader key stuff bool leading = false; uint16_t leader_time = 0; @@ -98,6 +102,82 @@ bool process_record_quantum(keyrecord_t *record) { // return false; // } + #ifdef MIDI_ENABLE + if (keycode == MI_ON && record->event.pressed) { + midi_activated = true; + PLAY_NOTE_ARRAY(music_scale, false, 0); + return false; + } + + if (keycode == MI_OFF && record->event.pressed) { + midi_activated = false; + midi_send_cc(&midi_device, 0, 0x7B, 0); + return false; + } + + if (midi_activated) { + if (record->event.key.col == (MATRIX_COLS - 1) && record->event.key.row == (MATRIX_ROWS - 1)) { + if (record->event.pressed) { + starting_note++; // Change key + midi_send_cc(&midi_device, 0, 0x7B, 0); + // midi_send_cc(&midi_device, 1, 0x7B, 0); + // midi_send_cc(&midi_device, 2, 0x7B, 0); + // midi_send_cc(&midi_device, 3, 0x7B, 0); + // midi_send_cc(&midi_device, 4, 0x7B, 0); + } + return false; + } + if (record->event.key.col == (MATRIX_COLS - 2) && record->event.key.row == (MATRIX_ROWS - 1)) { + if (record->event.pressed) { + starting_note--; // Change key + midi_send_cc(&midi_device, 0, 0x7B, 0); + // midi_send_cc(&midi_device, 1, 0x7B, 0); + // midi_send_cc(&midi_device, 2, 0x7B, 0); + // midi_send_cc(&midi_device, 3, 0x7B, 0); + // midi_send_cc(&midi_device, 4, 0x7B, 0); + } + return false; + } + if (record->event.key.col == (MATRIX_COLS - 3) && record->event.key.row == (MATRIX_ROWS - 1) && record->event.pressed) { + offset++; // Change scale + midi_send_cc(&midi_device, 0, 0x7B, 0); + // midi_send_cc(&midi_device, 1, 0x7B, 0); + // midi_send_cc(&midi_device, 2, 0x7B, 0); + // midi_send_cc(&midi_device, 3, 0x7B, 0); + // midi_send_cc(&midi_device, 4, 0x7B, 0); + return false; + } + if (record->event.key.col == (MATRIX_COLS - 4) && record->event.key.row == (MATRIX_ROWS - 1) && record->event.pressed) { + offset--; // Change scale + midi_send_cc(&midi_device, 0, 0x7B, 0); + // midi_send_cc(&midi_device, 1, 0x7B, 0); + // midi_send_cc(&midi_device, 2, 0x7B, 0); + // midi_send_cc(&midi_device, 3, 0x7B, 0); + // midi_send_cc(&midi_device, 4, 0x7B, 0); + return false; + } + // basic + // uint8_t note = (starting_note + SCALE[record->event.key.col + offset])+12*(MATRIX_ROWS - record->event.key.row); + // advanced + // uint8_t note = (starting_note + record->event.key.col + offset)+12*(MATRIX_ROWS - record->event.key.row); + // guitar + uint8_t note = (starting_note + record->event.key.col + offset)+5*(MATRIX_ROWS - record->event.key.row); + // violin + // uint8_t note = (starting_note + record->event.key.col + offset)+7*(MATRIX_ROWS - record->event.key.row); + + if (record->event.pressed) { + // midi_send_noteon(&midi_device, record->event.key.row, starting_note + SCALE[record->event.key.col], 127); + midi_send_noteon(&midi_device, 0, note, 127); + } else { + // midi_send_noteoff(&midi_device, record->event.key.row, starting_note + SCALE[record->event.key.col], 127); + midi_send_noteoff(&midi_device, 0, note, 127); + } + + if (keycode < 0xFF) // ignores all normal keycodes, but lets RAISE, LOWER, etc through + return false; + } + #endif + #ifdef AUDIO_ENABLE if (keycode == AU_ON && record->event.pressed) { audio_on(); @@ -169,7 +249,7 @@ bool process_record_quantum(keyrecord_t *record) { return false; } - float freq = ((float)220.0)*pow(2.0, -4.0)*pow(2.0,(starting_note + SCALE[record->event.key.col + offset])/12.0+(MATRIX_ROWS - record->event.key.row)); + float freq = ((float)220.0)*pow(2.0, -5.0)*pow(2.0,(starting_note + SCALE[record->event.key.col + offset])/12.0+(MATRIX_ROWS - record->event.key.row)); if (record->event.pressed) { play_note(freq, 0xF); if (music_sequence_recording) { @@ -185,8 +265,6 @@ bool process_record_quantum(keyrecord_t *record) { } #endif - - #ifndef DISABLE_LEADER // Leader key set-up if (record->event.pressed) { @@ -267,6 +345,6 @@ void matrix_scan_quantum() { } #endif - + matrix_scan_kb(); } \ No newline at end of file diff --git a/quantum/quantum.h b/quantum/quantum.h index db726ad42..bfecdb262 100644 --- a/quantum/quantum.h +++ b/quantum/quantum.h @@ -13,7 +13,8 @@ #include "audio.h" #endif #ifdef MIDI_ENABLE - #include + // #include + #include #endif #include "action_layer.h" #include "eeconfig.h" diff --git a/quantum/quantum.mk b/quantum/quantum.mk index b45ad850a..e7ccfd659 100644 --- a/quantum/quantum.mk +++ b/quantum/quantum.mk @@ -24,9 +24,9 @@ ifndef CUSTOM_MATRIX SRC += $(QUANTUM_DIR)/matrix.c endif -ifeq ($(strip $(MIDI_ENABLE)), yes) - SRC += $(QUANTUM_DIR)/keymap_midi.c -endif +#ifeq ($(strip $(MIDI_ENABLE)), yes) +# SRC += $(QUANTUM_DIR)/keymap_midi.c +#endif ifeq ($(strip $(AUDIO_ENABLE)), yes) SRC += $(QUANTUM_DIR)/audio/audio.c -- cgit v1.2.3-24-g4f1b From 465aabe11dbd673fb4c68ecbffbfb062273def1a Mon Sep 17 00:00:00 2001 From: heartsekai Date: Wed, 18 May 2016 21:22:04 +0200 Subject: Added Swiss-German keymap. (#335) --- quantum/keymap_extras/keymap_german_ch.h | 102 +++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 quantum/keymap_extras/keymap_german_ch.h (limited to 'quantum') diff --git a/quantum/keymap_extras/keymap_german_ch.h b/quantum/keymap_extras/keymap_german_ch.h new file mode 100644 index 000000000..0874abf7d --- /dev/null +++ b/quantum/keymap_extras/keymap_german_ch.h @@ -0,0 +1,102 @@ +#ifndef KEYMAP_SWISS_GERMAN +#define KEYMAP_SWISS_GERMAN + +#include "keymap_common.h" + +// Alt gr +#define ALGR(kc) kc | 0x1400 +#define CH_ALGR KC_RALT + +// normal characters +#define CH_Z KC_Y +#define CH_Y KC_Z + +#define CH_A KC_A +#define CH_B KC_B +#define CH_C KC_C +#define CH_D KC_D +#define CH_E KC_E +#define CH_F KC_F +#define CH_G KC_G +#define CH_H KC_H +#define CH_I KC_I +#define CH_J KC_J +#define CH_K KC_K +#define CH_L KC_L +#define CH_M KC_M +#define CH_N KC_N +#define CH_O KC_O +#define CH_P KC_P +#define CH_Q KC_Q +#define CH_R KC_R +#define CH_S KC_S +#define CH_T KC_T +#define CH_U KC_U +#define CH_V KC_V +#define CH_W KC_W +#define CH_X KC_X + +#define CH_0 KC_0 +#define CH_1 KC_1 +#define CH_2 KC_2 +#define CH_3 KC_3 +#define CH_4 KC_4 +#define CH_5 KC_5 +#define CH_6 KC_6 +#define CH_7 KC_7 +#define CH_8 KC_8 +#define CH_9 KC_9 + +#define CH_DOT KC_DOT +#define CH_COMM KC_COMM + +#define CH_QUOT KC_MINS // ' ? ´ +#define CH_AE KC_QUOT +#define CH_UE KC_LBRC +#define CH_OE KC_SCLN + +#define CH_PARA KC_GRAVE // secction sign § and ° +#define CH_CARR KC_EQL // carret ^ ` ~ +#define CH_DIER KC_RBRC // dieresis ¨ ! ] +#define CH_DLR KC_BSLS // $ £ } +#define CH_LESS KC_NUBS // < and > and backslash +#define CH_MINS KC_SLSH // - and _ + +// shifted characters +#define CH_RING LSFT(CH_PARA) // ° +#define CH_PLUS LSFT(KC_1) // + +#define CH_DQOT LSFT(KC_2) // " +#define CH_PAST LSFT(KC_3) // * +#define CH_CELA LSFT(KC_4) // ç +#define CH_PERC LSFT(KC_5) // % +#define CH_AMPR LSFT(KC_6) // & +#define CH_SLSH LSFT(KC_7) // / +#define CH_LPRN LSFT(KC_8) // ( +#define CH_RPRN LSFT(KC_9) // ) +#define CH_EQL LSFT(KC_0) // = +#define CH_QST LSFT(CH_QUOT) // ? +#define CH_GRV LSFT(CH_CARR) // ` +#define CH_EXLM LSFT(CH_DIER) // ! +#define CH_POND LSFT(CH_DLR) // £ +#define CH_MORE LSFT(CH_LESS) // > +#define CH_COLN LSFT(KC_DOT) // : +#define CH_SCLN LSFT(KC_COMM) // ; +#define CH_UNDS LSFT(CH_MINS) // _ + +// Alt Gr-ed characters +#define CH_BRBR ALGR(KC_1) // ¦ brocken bar +#define CH_AT ALGR(KC_2) // @ +#define CH_HASH ALGR(KC_3) // # +#define CH_NOTL ALGR(KC_6) // ¬ negative logic +#define CH_PIPE ALGR(KC_7) // | +#define CH_CENT ALGR(KC_8) // ¢ cent +#define CH_ACUT ALGR(CH_QUOT) // ´ +#define CH_TILD ALGR(CH_CARR) // ~ +#define CH_EURO ALGR(KC_E) // € +#define CH_LBRC ALGR(CH_UE) // [ +#define CH_RBRC ALGR(CH_DIER) // ] +#define CH_LCBR ALGR(CH_AE) // { +#define CH_RCBR ALGR(CH_DLR) // } +#define CH_BSLS ALGR(CH_LESS) // backslash + +#endif -- cgit v1.2.3-24-g4f1b From 0428214b905e5f8b3bed721885957ce249ba4991 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Wed, 18 May 2016 23:14:00 -0400 Subject: adds music and audio toggles (#337) * Updated personal layouts * tweaked personal * Nightly - Audio Cleanup Refactored the LUTs. Abstracted some of the registers out of audio to use more functional names. Split audio into audio and audio_pwm. WIP * nightly - collapsed code * Added check for note playing to LEDs * Usability tweaks * TWEAE * nightly added extra kcs to keymap common * turned on Plank audio * Added backlight breathing to atomic * reverted accidental merge * Added music and audio toggles to Quantum.c * Redid the audio callbacks * music/audio_on_user --- quantum/audio/audio.c | 8 +++++- quantum/audio/audio.h | 6 ++-- quantum/keymap_common.h | 14 +++++---- quantum/quantum.c | 75 ++++++++++++++++++++++++++++++++++++++++--------- quantum/quantum.h | 7 +++++ 5 files changed, 86 insertions(+), 24 deletions(-) (limited to 'quantum') diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index 243f49f0e..32f64417e 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -381,11 +381,14 @@ bool is_audio_on(void) { void audio_toggle(void) { audio_config.enable ^= 1; eeconfig_update_audio(audio_config.raw); + if (audio_config.enable) + audio_on_user(); } void audio_on(void) { audio_config.enable = 1; eeconfig_update_audio(audio_config.raw); + audio_on_user(); } void audio_off(void) { @@ -484,5 +487,8 @@ __attribute__ ((weak)) void play_goodbye_tone() {} __attribute__ ((weak)) -void audio_on_callback(void) {} +void audio_on_user() {} + +__attribute__ ((weak)) +void play_music_scale() {} //------------------------------------------------------------------------------ diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index fe8506131..b46f587bb 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -29,7 +29,6 @@ bool is_audio_on(void); void audio_toggle(void); void audio_on(void); void audio_off(void); -void audio_on_callback(void); // Vibrato rate functions @@ -87,9 +86,10 @@ void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat, float n_rest) bool is_playing_notes(void); + void play_goodbye_tone(void); void play_startup_tone(void); - - +void audio_on_user(void); +void play_music_scale(void); #endif \ No newline at end of file diff --git a/quantum/keymap_common.h b/quantum/keymap_common.h index 07020150a..1cbe8c61c 100644 --- a/quantum/keymap_common.h +++ b/quantum/keymap_common.h @@ -224,18 +224,20 @@ extern const uint16_t fn_actions[]; // Audio on/off #define AU_ON 0x5020 #define AU_OFF 0x5021 +#define AU_TOG 0x5022 // Music mode on/off -#define MU_ON 0x5022 -#define MU_OFF 0x5023 +#define MU_ON 0x5023 +#define MU_OFF 0x5024 +#define MU_TOG 0x5025 // Music voice iterate -#define MUV_IN 0x5024 -#define MUV_DE 0x5025 +#define MUV_IN 0x5026 +#define MUV_DE 0x5027 // Midi mode on/off -#define MI_ON 0x5026 -#define MI_OFF 0x5027 +#define MI_ON 0x5028 +#define MI_OFF 0x5029 // GOTO layer - 16 layers max // when: diff --git a/quantum/quantum.c b/quantum/quantum.c index 5a978d332..e4d7b9185 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -1,4 +1,5 @@ #include "quantum.h" +#include "timer.h" __attribute__ ((weak)) void matrix_init_kb(void) {} @@ -17,11 +18,11 @@ void leader_start(void) {} __attribute__ ((weak)) void leader_end(void) {} +uint8_t starting_note = 0x0C; +int offset = 7; + #ifdef AUDIO_ENABLE - uint8_t starting_note = 0x0C; - int offset = 7; bool music_activated = false; - float music_scale[][2] = SONG(MUSIC_SCALE_SOUND); #endif #ifdef MIDI_ENABLE @@ -105,7 +106,7 @@ bool process_record_quantum(keyrecord_t *record) { #ifdef MIDI_ENABLE if (keycode == MI_ON && record->event.pressed) { midi_activated = true; - PLAY_NOTE_ARRAY(music_scale, false, 0); + play_music_scale(); return false; } @@ -181,7 +182,6 @@ bool process_record_quantum(keyrecord_t *record) { #ifdef AUDIO_ENABLE if (keycode == AU_ON && record->event.pressed) { audio_on(); - audio_on_callback(); return false; } @@ -190,31 +190,53 @@ bool process_record_quantum(keyrecord_t *record) { return false; } + if (keycode == AU_TOG && record->event.pressed) { + if (is_audio_on()) + { + audio_off(); + } + else + { + audio_on(); + } + return false; + } + if (keycode == MU_ON && record->event.pressed) { - music_activated = true; - PLAY_NOTE_ARRAY(music_scale, false, 0); + music_on(); return false; } if (keycode == MU_OFF && record->event.pressed) { - music_activated = false; - stop_all_notes(); + music_off(); return false; } + if (keycode == MU_TOG && record->event.pressed) { + if (music_activated) + { + music_off(); + } + else + { + music_on(); + } + return false; + } + if (keycode == MUV_IN && record->event.pressed) { voice_iterate(); - PLAY_NOTE_ARRAY(music_scale, false, 0); + play_music_scale(); return false; } if (keycode == MUV_DE && record->event.pressed) { voice_deiterate(); - PLAY_NOTE_ARRAY(music_scale, false, 0); + play_music_scale(); return false; } - if (music_activated) { + if (music_activated) { if (keycode == KC_LCTL && record->event.pressed) { // Start recording stop_all_notes(); @@ -258,7 +280,7 @@ bool process_record_quantum(keyrecord_t *record) { } } else { stop_note(freq); - } + } if (keycode < 0xFF) // ignores all normal keycodes, but lets RAISE, LOWER, etc through return false; @@ -347,4 +369,29 @@ void matrix_scan_quantum() { #endif matrix_scan_kb(); -} \ No newline at end of file +} + +bool is_music_on(void) { + return (music_activated != 0); +} + +void music_toggle(void) { + if (!music_activated) { + music_on(); + } else { + music_off(); + } +} + +void music_on(void) { + music_activated = 1; + music_on_user(); +} + +void music_off(void) { + music_activated = 0; + stop_all_notes(); +} + +__attribute__ ((weak)) +void music_on_user() {} \ No newline at end of file diff --git a/quantum/quantum.h b/quantum/quantum.h index bfecdb262..f4d8f09d4 100644 --- a/quantum/quantum.h +++ b/quantum/quantum.h @@ -46,4 +46,11 @@ void leader_end(void); #define LEADER_EXTERNS() extern bool leading; extern uint16_t leader_time; extern uint16_t leader_sequence[3]; extern uint8_t leader_sequence_size #define LEADER_DICTIONARY() if (leading && timer_elapsed(leader_time) > LEADER_TIMEOUT) +bool is_music_on(void); +void music_toggle(void); +void music_on(void); +void music_off(void); + +void music_on_user(void); + #endif \ No newline at end of file -- cgit v1.2.3-24-g4f1b From b732b79b49b098dba8e14493c745075f336747d8 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Wed, 18 May 2016 23:47:16 -0400 Subject: adapts unicode to quantum.c (#333) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Unicode to have unicode input you need to: - set your OS input method to UNICODE if needed - enable unicode in your makefile - copy the action_function from keyboard/planck/keymaps/unicode/unicode.c to your keymap.c set the target OS method in your keymap.c: void matrix_init_user() { set_unicode_mode(UC_OSX); } you can then switch when you want with: set_unicode_mode(UC_OSX); set_unicode_mode(UC_LNX); set_unicode_mode(UC_WIN); put some unicode codes in your keymap like so: UC(0x0061) I did change the bit mask in quantum/keymap_common.c and .h I’m afraid we will need uint32 to get a total support for all unicode tables or relocate the handler as @mbarkhau did. * rearranges keycode values, hooks-up unicode * removes extra lalt ref * adds unicode shortcuts and example --- quantum/keymap_common.c | 26 ++++------ quantum/keymap_common.h | 76 ++++++++++++++-------------- quantum/keymap_unicode.c | 61 ---------------------- quantum/quantum.c | 79 ++++++++++++++++++++++++++--- quantum/quantum.h | 44 ++++++++++------ quantum/quantum.mk | 4 -- quantum/unicode.h | 128 +++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 278 insertions(+), 140 deletions(-) delete mode 100644 quantum/keymap_unicode.c create mode 100644 quantum/unicode.h (limited to 'quantum') diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c index 2aae13e67..1d9ab2e05 100644 --- a/quantum/keymap_common.c +++ b/quantum/keymap_common.c @@ -31,7 +31,6 @@ along with this program. If not, see . #include "keymap_midi.h" #endif - extern keymap_config_t keymap_config; #include @@ -154,20 +153,22 @@ static action_t keycode_to_action(uint16_t keycode) case KC_TRNS: action.code = ACTION_TRANSPARENT; break; - case 0x0100 ... 0x1FFF: ; + case LCTL(0) ... 0x1FFF: ; // Has a modifier // Split it up action.code = ACTION_MODS_KEY(keycode >> 8, keycode & 0xFF); // adds modifier to key break; - case 0x2000 ... 0x2FFF: + case FUNC(0) ... FUNC(0xFFF): ; // Is a shortcut for function layer, pull last 12bits // This means we have 4,096 FN macros at our disposal return keymap_func_to_action(keycode & 0xFFF); break; - case 0x3000 ... 0x3FFF: ; - // When the code starts with 3, it's an action macro. + case M(0) ... M(0xFF): action.code = ACTION_MACRO(keycode & 0xFF); break; + case LT(0, 0) ... LT(0xFF, 0xF): + action.code = ACTION_LAYER_TAP_KEY((keycode >> 0x8) & 0xF, keycode & 0xFF); + break; #ifdef BACKLIGHT_ENABLE case BL_0 ... BL_15: action.code = ACTION_BACKLIGHT_LEVEL(keycode & 0x000F); @@ -201,7 +202,7 @@ static action_t keycode_to_action(uint16_t keycode) print("\nDEBUG: enabled.\n"); debug_enable = true; break; - case 0x5002 ... 0x50FF: + case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_UNSWAP_ALT_GUI: // MAGIC actions (BOOTMAGIC without the boot) if (!eeconfig_is_enabled()) { eeconfig_init(); @@ -251,7 +252,7 @@ static action_t keycode_to_action(uint16_t keycode) } eeconfig_update_keymap(keymap_config.raw); break; - case 0x5100 ... 0x56FF: ; + case TO(0, 1) ... OSM(0xFF): ; // Layer movement shortcuts // See .h to see constraints/usage int type = (keycode >> 0x8) & 0xF; @@ -282,18 +283,9 @@ static action_t keycode_to_action(uint16_t keycode) action.code = ACTION_MODS_ONESHOT(mod); } break; - case 0x7000 ... 0x7FFF: + case MT(0, 0) ... MT(0xF, 0xFF): action.code = ACTION_MODS_TAP_KEY((keycode >> 0x8) & 0xF, keycode & 0xFF); break; - case 0x8000 ... 0x8FFF: - action.code = ACTION_LAYER_TAP_KEY((keycode >> 0x8) & 0xF, keycode & 0xFF); - break; - #ifdef UNICODE_ENABLE - case 0x8000000 ... 0x8FFFFFF: - uint16_t unicode = keycode & ~(0x8000); - action.code = ACTION_FUNCTION_OPT(unicode & 0xFF, (unicode & 0xFF00) >> 8); - break; - #endif default: action.code = ACTION_NO; break; diff --git a/quantum/keymap_common.h b/quantum/keymap_common.h index 1cbe8c61c..91d5c09c1 100644 --- a/quantum/keymap_common.h +++ b/quantum/keymap_common.h @@ -163,38 +163,13 @@ extern const uint16_t fn_actions[]; #define MACRODOWN(...) (record->event.pressed ? MACRO(__VA_ARGS__) : MACRO_NONE) -// These affect the backlight (if your keyboard has one). -// We don't need to comment them out if your keyboard doesn't have a backlight, -// since they don't take up any space. -#define BL_ON 0x4009 -#define BL_OFF 0x4000 -#define BL_0 0x4000 -#define BL_1 0x4001 -#define BL_2 0x4002 -#define BL_3 0x4003 -#define BL_4 0x4004 -#define BL_5 0x4005 -#define BL_6 0x4006 -#define BL_7 0x4007 -#define BL_8 0x4008 -#define BL_9 0x4009 -#define BL_10 0x400A -#define BL_11 0x400B -#define BL_12 0x400C -#define BL_13 0x400D -#define BL_14 0x400E -#define BL_15 0x400F -#define BL_DEC 0x4010 -#define BL_INC 0x4011 -#define BL_TOGG 0x4012 -#define BL_STEP 0x4013 +// 0x3100+ is free + +// L-ayer, T-ap - 256 keycode max, 16 layer max +#define LT(layer, kc) (kc | 0x4000 | ((layer & 0xF) << 8)) #define RESET 0x5000 #define DEBUG 0x5001 -#define KC_LEAD 0x5014 - - - // MAGIC keycodes #define MAGIC_SWAP_CONTROL_CAPSLOCK 0x5002 @@ -239,6 +214,32 @@ extern const uint16_t fn_actions[]; #define MI_ON 0x5028 #define MI_OFF 0x5029 +// These affect the backlight (if your keyboard has one). +// We don't need to comment them out if your keyboard doesn't have a backlight, +// since they don't take up any space. +#define BL_ON 0x5079 +#define BL_OFF 0x5070 +#define BL_0 0x5070 +#define BL_1 0x5071 +#define BL_2 0x5072 +#define BL_3 0x5073 +#define BL_4 0x5074 +#define BL_5 0x5075 +#define BL_6 0x5076 +#define BL_7 0x5077 +#define BL_8 0x5078 +#define BL_9 0x5079 +#define BL_10 0x507A +#define BL_11 0x507B +#define BL_12 0x507C +#define BL_13 0x507D +#define BL_14 0x507E +#define BL_15 0x507F +#define BL_DEC 0x5080 +#define BL_INC 0x5081 +#define BL_TOGG 0x5082 +#define BL_STEP 0x5083 + // GOTO layer - 16 layers max // when: // ON_PRESS = 1 @@ -261,6 +262,8 @@ extern const uint16_t fn_actions[]; // One-shot mod #define OSM(layer) (layer | 0x5600) +// chording is currently at 0x57xx + // M-od, T-ap - 256 keycode max #define MT(mod, kc) (kc | 0x7000 | ((mod & 0xF) << 8)) #define CTL_T(kc) MT(0x1, kc) @@ -276,14 +279,13 @@ extern const uint16_t fn_actions[]; #define KC_HYPR HYPR(KC_NO) #define KC_MEH MEH(KC_NO) -// L-ayer, T-ap - 256 keycode max, 16 layer max -#define LT(layer, kc) (kc | 0x8000 | ((layer & 0xF) << 8)) - -// For sending unicode codes. -// You may not send codes over 1FFF -- this supports most of UTF8. -// To have a key that sends out Œ, go UC(0x0152) -#define UNICODE(n) (n | 0x8000) -#define UC(n) UNICODE(n) +#ifdef UNICODE_ENABLE + // For sending unicode codes. + // You may not send codes over 7FFF -- this supports most of UTF8. + // To have a key that sends out Œ, go UC(0x0152) + #define UNICODE(n) (n | 0x8000) + #define UC(n) UNICODE(n) +#endif // For tri-layer void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3); diff --git a/quantum/keymap_unicode.c b/quantum/keymap_unicode.c deleted file mode 100644 index a44965e61..000000000 --- a/quantum/keymap_unicode.c +++ /dev/null @@ -1,61 +0,0 @@ -/* -Copyright 2015 Jack Humbert - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -#include "keymap_common.h" - -uint16_t hextokeycode(int hex) { - if (hex == 0x0) { - return KC_0; - } else if (hex < 0xA) { - return KC_1 + (hex - 0x1); - } else { - return KC_A + (hex - 0xA); - } -} - -void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) -{ - - // For more info on how this works per OS, see here: https://en.wikipedia.org/wiki/Unicode_input#Hexadecimal_code_input - - if (record->event.pressed) { - uint16_t unicode = (opt << 8) | id; - register_code(KC_LALT); - - register_code(hextokeycode((unicode & 0xF000) >> 12)); - unregister_code(hextokeycode((unicode & 0xF000) >> 12)); - register_code(hextokeycode((unicode & 0x0F00) >> 8)); - unregister_code(hextokeycode((unicode & 0x0F00) >> 8)); - register_code(hextokeycode((unicode & 0x00F0) >> 4)); - unregister_code(hextokeycode((unicode & 0x00F0) >> 4)); - register_code(hextokeycode((unicode & 0x000F))); - unregister_code(hextokeycode((unicode & 0x000F))); - - /* Test 'a' */ - // register_code(hextokeycode(0x0)); - // unregister_code(hextokeycode(0x0)); - // register_code(hextokeycode(0x0)); - // unregister_code(hextokeycode(0x0)); - // register_code(hextokeycode(0x6)); - // unregister_code(hextokeycode(0x6)); - // register_code(hextokeycode(0x1)); - // unregister_code(hextokeycode(0x1)); - - unregister_code(KC_LALT); - } - return; -} \ No newline at end of file diff --git a/quantum/quantum.c b/quantum/quantum.c index e4d7b9185..1e91ac04a 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -23,6 +23,18 @@ int offset = 7; #ifdef AUDIO_ENABLE bool music_activated = false; + float music_scale[][2] = SONG(MUSIC_SCALE_SOUND); + + // music sequencer + static bool music_sequence_recording = false; + static bool music_sequence_playing = false; + static float music_sequence[16] = {0}; + static uint8_t music_sequence_count = 0; + static uint8_t music_sequence_position = 0; + + static uint16_t music_sequence_timer = 0; + static uint16_t music_sequence_interval = 100; + #endif #ifdef MIDI_ENABLE @@ -44,6 +56,10 @@ uint8_t chord_keys[CHORDING_MAX] = {0}; uint8_t chord_key_count = 0; uint8_t chord_key_down = 0; +#ifdef UNICODE_ENABLE + static uint8_t input_mode; +#endif + bool keys_chord(uint8_t keys[]) { uint8_t keys_size = sizeof(keys)/sizeof(keys[0]); bool pass = true; @@ -66,14 +82,25 @@ bool keys_chord(uint8_t keys[]) { return (pass && (in == keys_size)); } -static bool music_sequence_recording = false; -static bool music_sequence_playing = false; -static float music_sequence[16] = {0}; -static uint8_t music_sequence_count = 0; -static uint8_t music_sequence_position = 0; +#ifdef UNICODE_ENABLE + +uint16_t hex_to_keycode(uint8_t hex) +{ + if (hex == 0x0) { + return KC_0; + } else if (hex < 0xA) { + return KC_1 + (hex - 0x1); + } else { + return KC_A + (hex - 0xA); + } +} + +void set_unicode_mode(uint8_t os_target) +{ + input_mode = os_target; +} -static uint16_t music_sequence_timer = 0; -static uint16_t music_sequence_interval = 100; +#endif bool process_record_quantum(keyrecord_t *record) { @@ -347,6 +374,44 @@ bool process_record_quantum(keyrecord_t *record) { #endif +#ifdef UNICODE_ENABLE + + if (keycode > UNICODE(0) && record->event.pressed) { + uint16_t unicode = keycode & 0x7FFF; + switch(input_mode) { + case UC_OSX: + register_code(KC_LALT); + break; + case UC_LNX: + register_code(KC_LCTL); + register_code(KC_LSFT); + register_code(KC_U); + unregister_code(KC_U); + break; + case UC_WIN: + register_code(KC_LALT); + register_code(KC_PPLS); + unregister_code(KC_PPLS); + break; + } + for(int i = 3; i >= 0; i--) { + uint8_t digit = ((unicode >> (i*4)) & 0xF); + register_code(hex_to_keycode(digit)); + unregister_code(hex_to_keycode(digit)); + } + switch(input_mode) { + case UC_OSX: + case UC_WIN: + unregister_code(KC_LALT); + break; + case UC_LNX: + unregister_code(KC_LCTL); + unregister_code(KC_LSFT); + break; + } + } + +#endif return process_action_kb(record); } diff --git a/quantum/quantum.h b/quantum/quantum.h index f4d8f09d4..d4da77289 100644 --- a/quantum/quantum.h +++ b/quantum/quantum.h @@ -13,9 +13,12 @@ #include "audio.h" #endif #ifdef MIDI_ENABLE - // #include #include #endif +#ifdef UNICODE_ENABLE + #include "unicode.h" +#endif + #include "action_layer.h" #include "eeconfig.h" #include @@ -27,24 +30,37 @@ extern uint32_t default_layer_state; extern uint32_t layer_state; #endif -bool music_activated; +#ifdef AUDIO_ENABLE + bool music_activated; +#endif -void matrix_init_kb(void); -void matrix_scan_kb(void); -bool process_action_kb(keyrecord_t *record); +#ifdef UNICODE_ENABLE + #define UC_OSX 0 + #define UC_LNX 1 + #define UC_WIN 2 + #define UC_BSD 3 -void leader_start(void); -void leader_end(void); + void set_unicode_input_mode(uint8_t os_target); +#endif + +#ifndef DISABLE_LEADER + void leader_start(void); + void leader_end(void); + + #ifndef LEADER_TIMEOUT + #define LEADER_TIMEOUT 200 + #endif + #define SEQ_ONE_KEY(key) if (leader_sequence[0] == (key) && leader_sequence[1] == 0 && leader_sequence[2] == 0) + #define SEQ_TWO_KEYS(key1, key2) if (leader_sequence[0] == (key1) && leader_sequence[1] == (key2) && leader_sequence[2] == 0) + #define SEQ_THREE_KEYS(key1, key2, key3) if (leader_sequence[0] == (key1) && leader_sequence[1] == (key2) && leader_sequence[2] == (key3)) -#ifndef LEADER_TIMEOUT - #define LEADER_TIMEOUT 200 + #define LEADER_EXTERNS() extern bool leading; extern uint16_t leader_time; extern uint16_t leader_sequence[3]; extern uint8_t leader_sequence_size + #define LEADER_DICTIONARY() if (leading && timer_elapsed(leader_time) > LEADER_TIMEOUT) #endif -#define SEQ_ONE_KEY(key) if (leader_sequence[0] == (key) && leader_sequence[1] == 0 && leader_sequence[2] == 0) -#define SEQ_TWO_KEYS(key1, key2) if (leader_sequence[0] == (key1) && leader_sequence[1] == (key2) && leader_sequence[2] == 0) -#define SEQ_THREE_KEYS(key1, key2, key3) if (leader_sequence[0] == (key1) && leader_sequence[1] == (key2) && leader_sequence[2] == (key3)) -#define LEADER_EXTERNS() extern bool leading; extern uint16_t leader_time; extern uint16_t leader_sequence[3]; extern uint8_t leader_sequence_size -#define LEADER_DICTIONARY() if (leading && timer_elapsed(leader_time) > LEADER_TIMEOUT) +void matrix_init_kb(void); +void matrix_scan_kb(void); +bool process_action_kb(keyrecord_t *record); bool is_music_on(void); void music_toggle(void); diff --git a/quantum/quantum.mk b/quantum/quantum.mk index e7ccfd659..c099d6793 100644 --- a/quantum/quantum.mk +++ b/quantum/quantum.mk @@ -34,10 +34,6 @@ ifeq ($(strip $(AUDIO_ENABLE)), yes) SRC += $(QUANTUM_DIR)/audio/luts.c endif -ifeq ($(strip $(UNICODE_ENABLE)), yes) - SRC += $(QUANTUM_DIR)/keymap_unicode.c -endif - ifeq ($(strip $(RGBLIGHT_ENABLE)), yes) SRC += $(QUANTUM_DIR)/light_ws2812.c SRC += $(QUANTUM_DIR)/rgblight.c diff --git a/quantum/unicode.h b/quantum/unicode.h new file mode 100644 index 000000000..756ec8bc3 --- /dev/null +++ b/quantum/unicode.h @@ -0,0 +1,128 @@ +/* +Copyright 2016 Jack Humbert +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#ifndef UNICODE_H +#define UNICODE_H + +#include "quantum.h" +#include + +#define UC_BSPC UC(0x0008) + +#define UC_SPC UC(0x0020) + +#define UC_EXLM UC(0x0021) +#define UC_DQUT UC(0x0022) +#define UC_HASH UC(0x0023) +#define UC_DLR UC(0x0024) +#define UC_PERC UC(0x0025) +#define UC_AMPR UC(0x0026) +#define UC_QUOT UC(0x0027) +#define UC_LPRN UC(0x0028) +#define UC_RPRN UC(0x0029) +#define UC_ASTR UC(0x002A) +#define UC_PLUS UC(0x002B) +#define UC_COMM UC(0x002C) +#define UC_DASH UC(0x002D) +#define UC_DOT UC(0x002E) +#define UC_SLSH UC(0x002F) + +#define UC_0 UC(0x0030) +#define UC_1 UC(0x0031) +#define UC_2 UC(0x0032) +#define UC_3 UC(0x0033) +#define UC_4 UC(0x0034) +#define UC_5 UC(0x0035) +#define UC_6 UC(0x0036) +#define UC_7 UC(0x0037) +#define UC_8 UC(0x0038) +#define UC_9 UC(0x0039) + +#define UC_COLN UC(0x003A) +#define UC_SCLN UC(0x003B) +#define UC_LT UC(0x003C) +#define UC_EQL UC(0x003D) +#define UC_GT UC(0x003E) +#define UC_QUES UC(0x003F) +#define UC_AT UC(0x0040) + +#define UC_A UC(0x0041) +#define UC_B UC(0x0042) +#define UC_C UC(0x0043) +#define UC_D UC(0x0044) +#define UC_E UC(0x0045) +#define UC_F UC(0x0046) +#define UC_G UC(0x0047) +#define UC_H UC(0x0048) +#define UC_I UC(0x0049) +#define UC_J UC(0x004A) +#define UC_K UC(0x004B) +#define UC_L UC(0x004C) +#define UC_M UC(0x004D) +#define UC_N UC(0x004E) +#define UC_O UC(0x004F) +#define UC_P UC(0x0050) +#define UC_Q UC(0x0051) +#define UC_R UC(0x0052) +#define UC_S UC(0x0053) +#define UC_T UC(0x0054) +#define UC_U UC(0x0055) +#define UC_V UC(0x0056) +#define UC_W UC(0x0057) +#define UC_X UC(0x0058) +#define UC_Y UC(0x0059) +#define UC_Z UC(0x005A) + +#define UC_LBRC UC(0x005B) +#define UC_BSLS UC(0x005C) +#define UC_RBRC UC(0x005D) +#define UC_CIRM UC(0x005E) +#define UC_UNDR UC(0x005F) + +#define UC_GRV UC(0x0060) + +#define UC_a UC(0x0061) +#define UC_b UC(0x0062) +#define UC_c UC(0x0063) +#define UC_d UC(0x0064) +#define UC_e UC(0x0065) +#define UC_f UC(0x0066) +#define UC_g UC(0x0067) +#define UC_h UC(0x0068) +#define UC_i UC(0x0069) +#define UC_j UC(0x006A) +#define UC_k UC(0x006B) +#define UC_l UC(0x006C) +#define UC_m UC(0x006D) +#define UC_n UC(0x006E) +#define UC_o UC(0x006F) +#define UC_p UC(0x0070) +#define UC_q UC(0x0071) +#define UC_r UC(0x0072) +#define UC_s UC(0x0073) +#define UC_t UC(0x0074) +#define UC_u UC(0x0075) +#define UC_v UC(0x0076) +#define UC_w UC(0x0077) +#define UC_x UC(0x0078) +#define UC_y UC(0x0079) +#define UC_z UC(0x007A) + +#define UC_LCBR UC(0x007B) +#define UC_PIPE UC(0x007C) +#define UC_RCBR UC(0x007D) +#define UC_TILD UC(0x007E) +#define UC_DEL UC(0x007F) + +#endif \ No newline at end of file -- cgit v1.2.3-24-g4f1b From 0275d444d77c9d85d2189b09d8813fb76dc4d566 Mon Sep 17 00:00:00 2001 From: purpleP Date: Thu, 19 May 2016 15:36:28 +0300 Subject: fixed small bug with AUDIO_ENABLED (#339) --- quantum/quantum.c | 43 ++++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 21 deletions(-) (limited to 'quantum') diff --git a/quantum/quantum.c b/quantum/quantum.c index 1e91ac04a..34c575af4 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -20,7 +20,7 @@ void leader_end(void) {} uint8_t starting_note = 0x0C; int offset = 7; - + #ifdef AUDIO_ENABLE bool music_activated = false; float music_scale[][2] = SONG(MUSIC_SCALE_SOUND); @@ -435,28 +435,29 @@ void matrix_scan_quantum() { matrix_scan_kb(); } +#ifdef AUDIO_ENABLE + bool is_music_on(void) { + return (music_activated != 0); + } -bool is_music_on(void) { - return (music_activated != 0); -} - -void music_toggle(void) { - if (!music_activated) { - music_on(); - } else { - music_off(); - } -} + void music_toggle(void) { + if (!music_activated) { + music_on(); + } else { + music_off(); + } + } -void music_on(void) { - music_activated = 1; - music_on_user(); -} + void music_on(void) { + music_activated = 1; + music_on_user(); + } -void music_off(void) { - music_activated = 0; - stop_all_notes(); -} + void music_off(void) { + music_activated = 0; + stop_all_notes(); + } +#endif __attribute__ ((weak)) -void music_on_user() {} \ No newline at end of file +void music_on_user() {} -- cgit v1.2.3-24-g4f1b From aaa758f1d3f97dda39879f2b055ad2da9680adfe Mon Sep 17 00:00:00 2001 From: Eric Tang Date: Mon, 23 May 2016 20:42:21 -0700 Subject: Optimize matrix scanning (#343) --- quantum/config_common.h | 125 ++++++++-------- quantum/matrix.c | 369 ++++++++++++++++++---------------------------- quantum/template/config.h | 17 ++- 3 files changed, 213 insertions(+), 298 deletions(-) (limited to 'quantum') diff --git a/quantum/config_common.h b/quantum/config_common.h index da53fce89..02f11d979 100644 --- a/quantum/config_common.h +++ b/quantum/config_common.h @@ -1,70 +1,74 @@ #ifndef CONFIG_DEFINITIONS_H #define CONFIG_DEFINITIONS_H -#define B0 0x20 -#define B1 0x21 -#define B2 0x22 -#define B3 0x23 -#define B4 0x24 -#define B5 0x25 -#define B6 0x26 -#define B7 0x27 -#define C0 0x30 -#define C1 0x31 -#define C2 0x32 -#define C3 0x33 -#define C4 0x34 -#define C5 0x35 -#define C6 0x36 -#define C7 0x37 -#define D0 0x40 -#define D1 0x41 -#define D2 0x42 -#define D3 0x43 -#define D4 0x44 -#define D5 0x45 -#define D6 0x46 -#define D7 0x47 -#define E0 0x50 -#define E1 0x51 -#define E2 0x52 -#define E3 0x53 -#define E4 0x54 -#define E5 0x55 -#define E6 0x56 -#define E7 0x57 -#define F0 0x60 -#define F1 0x61 -#define F2 0x62 -#define F3 0x63 -#define F4 0x64 -#define F5 0x65 -#define F6 0x66 -#define F7 0x67 - -#define COL2ROW 0x0 -#define ROW2COL 0x1 +/* diode directions */ +#define COL2ROW 0 +#define ROW2COL 1 +/* I/O pins */ +#define B0 { .input_addr = 3, .bit = 0 } +#define B1 { .input_addr = 3, .bit = 1 } +#define B2 { .input_addr = 3, .bit = 2 } +#define B3 { .input_addr = 3, .bit = 3 } +#define B4 { .input_addr = 3, .bit = 4 } +#define B5 { .input_addr = 3, .bit = 5 } +#define B6 { .input_addr = 3, .bit = 6 } +#define B7 { .input_addr = 3, .bit = 7 } +#define C0 { .input_addr = 6, .bit = 0 } +#define C1 { .input_addr = 6, .bit = 1 } +#define C2 { .input_addr = 6, .bit = 2 } +#define C3 { .input_addr = 6, .bit = 3 } +#define C4 { .input_addr = 6, .bit = 4 } +#define C5 { .input_addr = 6, .bit = 5 } +#define C6 { .input_addr = 6, .bit = 6 } +#define C7 { .input_addr = 6, .bit = 7 } +#define D0 { .input_addr = 9, .bit = 0 } +#define D1 { .input_addr = 9, .bit = 1 } +#define D2 { .input_addr = 9, .bit = 2 } +#define D3 { .input_addr = 9, .bit = 3 } +#define D4 { .input_addr = 9, .bit = 4 } +#define D5 { .input_addr = 9, .bit = 5 } +#define D6 { .input_addr = 9, .bit = 6 } +#define D7 { .input_addr = 9, .bit = 7 } +#define E0 { .input_addr = 0xC, .bit = 0 } +#define E1 { .input_addr = 0xC, .bit = 1 } +#define E2 { .input_addr = 0xC, .bit = 2 } +#define E3 { .input_addr = 0xC, .bit = 3 } +#define E4 { .input_addr = 0xC, .bit = 4 } +#define E5 { .input_addr = 0xC, .bit = 5 } +#define E6 { .input_addr = 0xC, .bit = 6 } +#define E7 { .input_addr = 0xC, .bit = 7 } +#define F0 { .input_addr = 0xF, .bit = 0 } +#define F1 { .input_addr = 0xF, .bit = 1 } +#define F2 { .input_addr = 0xF, .bit = 2 } +#define F3 { .input_addr = 0xF, .bit = 3 } +#define F4 { .input_addr = 0xF, .bit = 4 } +#define F5 { .input_addr = 0xF, .bit = 5 } +#define F6 { .input_addr = 0xF, .bit = 6 } +#define F7 { .input_addr = 0xF, .bit = 7 } +/* USART configuration */ #ifdef BLUETOOTH_ENABLE -#ifdef __AVR_ATmega32U4__ - #define SERIAL_UART_BAUD 9600 - #define SERIAL_UART_DATA UDR1 - #define SERIAL_UART_UBRR ((F_CPU/(16UL*SERIAL_UART_BAUD))-1) - #define SERIAL_UART_RXD_VECT USART1_RX_vect - #define SERIAL_UART_TXD_READY (UCSR1A&(1<>8); /* baud rate */ \ - UCSR1B = (1<> 8; \ + /* enable TX */ \ + UCSR1B = _BV(TXEN1); \ + /* 8-bit data */ \ + UCSR1C = _BV(UCSZ11) | _BV(UCSZ10); \ + sei(); \ + } while(0) +# else +# error "USART configuration is needed." #endif - // I'm fairly sure these aren't needed, but oh well - Jack /* @@ -113,4 +117,3 @@ #endif #endif - diff --git a/quantum/matrix.c b/quantum/matrix.c index cab39e117..22126aa7a 100644 --- a/quantum/matrix.c +++ b/quantum/matrix.c @@ -1,6 +1,6 @@ /* -Copyright 2012 Jun Wako -Generated by planckkeyboard.com (2014 Jack Humbert) +Copyright 2012 Jun Wako +Copyright 2014 Jack Humbert This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -15,300 +15,211 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ - -/* - * scan matrix - */ #include #include #include -#include +#include "wait.h" #include "print.h" #include "debug.h" #include "util.h" #include "matrix.h" -#ifndef DEBOUNCE -# define DEBOUNCE 10 +#ifdef MATRIX_HAS_GHOST +# error "The universal matrix.c file cannot be used for this keyboard." #endif -static uint8_t debouncing = DEBOUNCE; -/* matrix state(1:on, 0:off) */ -static matrix_row_t matrix[MATRIX_ROWS]; -static matrix_row_t matrix_debouncing[MATRIX_ROWS]; - -#if DIODE_DIRECTION == ROW2COL - static matrix_row_t matrix_reversed[MATRIX_COLS]; - static matrix_row_t matrix_reversed_debouncing[MATRIX_COLS]; +#ifndef DEBOUNCING_DELAY +# define DEBOUNCING_DELAY 5 #endif - -#if MATRIX_COLS > 16 - #define SHIFTER 1UL +static const io_pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; +static const io_pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS; +/* matrix state */ +#if DIODE_DIRECTION == COL2ROW +static matrix_row_t matrix[MATRIX_ROWS]; +static matrix_row_t debouncing_matrix[MATRIX_ROWS]; #else - #define SHIFTER 1 +static matrix_col_t matrix[MATRIX_COLS]; +static matrix_col_t debouncing_matrix[MATRIX_COLS]; #endif +static int8_t debouncing_delay = -1; +#if DIODE_DIRECTION == COL2ROW +static void toggle_row(uint8_t row); static matrix_row_t read_cols(void); -static void init_cols(void); -static void unselect_rows(void); -static void select_row(uint8_t row); +#else +static void toggle_col(uint8_t col); +static matrix_col_t read_rows(void); +#endif __attribute__ ((weak)) void matrix_init_quantum(void) { - } __attribute__ ((weak)) void matrix_scan_quantum(void) { - } -inline -uint8_t matrix_rows(void) -{ +uint8_t matrix_rows(void) { return MATRIX_ROWS; } -inline -uint8_t matrix_cols(void) -{ +uint8_t matrix_cols(void) { return MATRIX_COLS; } -void matrix_init(void) -{ - // To use PORTF disable JTAG with writing JTD bit twice within four cycles. - MCUCR |= (1<= 0; --r) { + /* DDRxn */ + _SFR_IO8(row_pins[r].input_addr + 1) |= _BV(row_pins[r].bit); + toggle_row(r); } - + for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { + /* PORTxn */ + _SFR_IO8(col_pins[c].input_addr + 2) |= _BV(col_pins[c].bit); + } +#else + for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { + /* DDRxn */ + _SFR_IO8(col_pins[c].input_addr + 1) |= _BV(col_pins[c].bit); + toggle_col(c); + } + for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { + /* PORTxn */ + _SFR_IO8(row_pins[r].input_addr + 2) |= _BV(row_pins[r].bit); + } +#endif matrix_init_quantum(); } - -uint8_t matrix_scan(void) -{ - #if DIODE_DIRECTION == COL2ROW - for (uint8_t i = 0; i < MATRIX_ROWS; i++) { - select_row(i); - _delay_us(30); // without this wait read unstable value. - matrix_row_t cols = read_cols(); - if (matrix_debouncing[i] != cols) { - matrix_debouncing[i] = cols; - if (debouncing) { - debug("bounce!: "); debug_hex(debouncing); debug("\n"); - } - debouncing = DEBOUNCE; +uint8_t matrix_scan(void) { + for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { + toggle_row(r); + matrix_row_t state = read_cols(); + if (debouncing_matrix[r] != state) { + debouncing_matrix[r] = state; + debouncing_delay = DEBOUNCING_DELAY; } - unselect_rows(); + toggle_row(r); } - - if (debouncing) { - if (--debouncing) { - _delay_ms(1); - } else { - for (uint8_t i = 0; i < MATRIX_ROWS; i++) { - matrix[i] = matrix_debouncing[i]; - } + if (debouncing_delay >= 0) { + dprintf("Debouncing delay remaining: %X\n", debouncing_delay); + --debouncing_delay; + if (debouncing_delay >= 0) { + wait_ms(1); } - } -#else - for (uint8_t i = 0; i < MATRIX_COLS; i++) { - select_row(i); - _delay_us(30); // without this wait read unstable value. - matrix_row_t rows = read_cols(); - if (matrix_reversed_debouncing[i] != rows) { - matrix_reversed_debouncing[i] = rows; - if (debouncing) { - debug("bounce!: "); debug_hex(debouncing); debug("\n"); + else { + for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { + matrix[r] = debouncing_matrix[r]; } - debouncing = DEBOUNCE; } - unselect_rows(); } - - if (debouncing) { - if (--debouncing) { - _delay_ms(1); - } else { - for (uint8_t i = 0; i < MATRIX_COLS; i++) { - matrix_reversed[i] = matrix_reversed_debouncing[i]; - } - } - } - for (uint8_t y = 0; y < MATRIX_ROWS; y++) { - matrix_row_t row = 0; - for (uint8_t x = 0; x < MATRIX_COLS; x++) { - row |= ((matrix_reversed[x] & (1<> y) << x; - } - matrix[y] = row; - } -#endif - matrix_scan_quantum(); - return 1; } -bool matrix_is_modified(void) -{ - if (debouncing) return false; - return true; +static void toggle_row(uint8_t row) { + /* PINxn */ + _SFR_IO8(row_pins[row].input_addr) = _BV(row_pins[row].bit); } -inline -bool matrix_is_on(uint8_t row, uint8_t col) -{ - return (matrix[row] & ((matrix_row_t)1= 0; --c) { + /* PINxn */ + if (!(_SFR_IO8(col_pins[c].input_addr) & _BV(col_pins[c].bit))) { + state |= (matrix_row_t)1 << c; + } + } + return state; } -inline -matrix_row_t matrix_get_row(uint8_t row) -{ +matrix_row_t matrix_get_row(uint8_t row) { return matrix[row]; } -void matrix_print(void) -{ - print("\nr/c 0123456789ABCDEF\n"); - for (uint8_t row = 0; row < MATRIX_ROWS; row++) { - phex(row); print(": "); - pbin_reverse16(matrix_get_row(row)); - print("\n"); +#else +uint8_t matrix_scan(void) { + for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { + toggle_col(c); + matrix_col_t state = read_rows(); + if (debouncing_matrix[c] != state) { + debouncing_matrix[c] = state; + debouncing_delay = DEBOUNCING_DELAY; + } + toggle_col(c); } -} - -uint8_t matrix_key_count(void) -{ - uint8_t count = 0; - for (uint8_t i = 0; i < MATRIX_ROWS; i++) { - count += bitpop16(matrix[i]); + if (debouncing_delay >= 0) { + dprintf("Debouncing delay remaining: %X\n", debouncing_delay); + --debouncing_delay; + if (debouncing_delay >= 0) { + wait_ms(1); + } + else { + for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { + matrix[c] = debouncing_matrix[c]; + } + } } - return count; + matrix_scan_quantum(); + return 1; } -static void init_cols(void) -{ - int B = 0, C = 0, D = 0, E = 0, F = 0; +static void toggle_col(uint8_t col) { + /* PINxn */ + _SFR_IO8(col_pins[col].input_addr) = _BV(col_pins[col].bit); +} -#if DIODE_DIRECTION == COL2ROW - for(int x = 0; x < MATRIX_COLS; x++) { - int col = COLS[x]; -#else - for(int x = 0; x < MATRIX_ROWS; x++) { - int col = ROWS[x]; -#endif - if ((col & 0xF0) == 0x20) { - B |= (1<<(col & 0x0F)); - } else if ((col & 0xF0) == 0x30) { - C |= (1<<(col & 0x0F)); - } else if ((col & 0xF0) == 0x40) { - D |= (1<<(col & 0x0F)); - } else if ((col & 0xF0) == 0x50) { - E |= (1<<(col & 0x0F)); - } else if ((col & 0xF0) == 0x60) { - F |= (1<<(col & 0x0F)); - } +static matrix_col_t read_rows(void) { + matrix_col_t state = 0; + for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { + /* PINxn */ + if (!(_SFR_IO8(row_pins[r].input_addr) & _BV(row_pins[r].bit))) { + state |= (matrix_col_t)1 << r; + } } - DDRB &= ~(B); PORTB |= (B); - DDRC &= ~(C); PORTC |= (C); - DDRD &= ~(D); PORTD |= (D); - DDRE &= ~(E); PORTE |= (E); - DDRF &= ~(F); PORTF |= (F); + return state; } -static matrix_row_t read_cols(void) -{ - matrix_row_t result = 0; +matrix_row_t matrix_get_row(uint8_t row) { + matrix_row_t state = 0; + matrix_col_t mask = (matrix_col_t)1 << row; + for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { + if (matrix[c] & mask) { + state |= (matrix_row_t)1 << c; + } + } + return state; +} -#if DIODE_DIRECTION == COL2ROW - for(int x = 0; x < MATRIX_COLS; x++) { - int col = COLS[x]; -#else - for(int x = 0; x < MATRIX_ROWS; x++) { - int col = ROWS[x]; #endif - if ((col & 0xF0) == 0x20) { - result |= (PINB&(1<<(col & 0x0F)) ? 0 : (SHIFTER<= 0) return false; + return true; } -static void unselect_rows(void) -{ - int B = 0, C = 0, D = 0, E = 0, F = 0; +bool matrix_is_on(uint8_t row, uint8_t col) { + return matrix_get_row(row) & (matrix_row_t)1 << col; +} -#if DIODE_DIRECTION == COL2ROW - for(int x = 0; x < MATRIX_ROWS; x++) { - int row = ROWS[x]; -#else - for(int x = 0; x < MATRIX_COLS; x++) { - int row = COLS[x]; -#endif - if ((row & 0xF0) == 0x20) { - B |= (1<<(row & 0x0F)); - } else if ((row & 0xF0) == 0x30) { - C |= (1<<(row & 0x0F)); - } else if ((row & 0xF0) == 0x40) { - D |= (1<<(row & 0x0F)); - } else if ((row & 0xF0) == 0x50) { - E |= (1<<(row & 0x0F)); - } else if ((row & 0xF0) == 0x60) { - F |= (1<<(row & 0x0F)); - } +void matrix_print(void) { + dprintln("Human-readable matrix state:"); + for (uint8_t r = 0; r < MATRIX_ROWS; r++) { + dprintf("State of row %X: %016b\n", r, bitrev16(matrix_get_row(r))); } - DDRB &= ~(B); PORTB |= (B); - DDRC &= ~(C); PORTC |= (C); - DDRD &= ~(D); PORTD |= (D); - DDRE &= ~(E); PORTE |= (E); - DDRF &= ~(F); PORTF |= (F); } -static void select_row(uint8_t row) -{ - -#if DIODE_DIRECTION == COL2ROW - int row_pin = ROWS[row]; -#else - int row_pin = COLS[row]; -#endif - - if ((row_pin & 0xF0) == 0x20) { - DDRB |= (1<<(row_pin & 0x0F)); - PORTB &= ~(1<<(row_pin & 0x0F)); - } else if ((row_pin & 0xF0) == 0x30) { - DDRC |= (1<<(row_pin & 0x0F)); - PORTC &= ~(1<<(row_pin & 0x0F)); - } else if ((row_pin & 0xF0) == 0x40) { - DDRD |= (1<<(row_pin & 0x0F)); - PORTD &= ~(1<<(row_pin & 0x0F)); - } else if ((row_pin & 0xF0) == 0x50) { - DDRE |= (1<<(row_pin & 0x0F)); - PORTE &= ~(1<<(row_pin & 0x0F)); - } else if ((row_pin & 0xF0) == 0x60) { - DDRF |= (1<<(row_pin & 0x0F)); - PORTF &= ~(1<<(row_pin & 0x0F)); - } -} \ No newline at end of file +uint8_t matrix_key_count(void) { + uint8_t count = 0; + for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { + count += bitpop16(matrix_get_row(r)); + } + return count; +} diff --git a/quantum/template/config.h b/quantum/template/config.h index e6fb7866c..cad3e3260 100644 --- a/quantum/template/config.h +++ b/quantum/template/config.h @@ -41,15 +41,16 @@ along with this program. If not, see . * DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode) * ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode) * -*/ -#define COLS (int []){ F1, F0, B0 } -#define ROWS (int []){ D0, D5 } +*/ +#define MATRIX_ROW_PINS { D0, D5 } +#define MATRIX_COL_PINS { F1, F0, B0 } +#define UNUSED_PINS /* COL2ROW or ROW2COL */ #define DIODE_DIRECTION COL2ROW /* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */ -#define DEBOUNCE 5 +#define DEBOUNCING_DELAY 5 /* define if matrix has ghost (lacks anti-ghosting diodes) */ //#define MATRIX_HAS_GHOST @@ -62,17 +63,17 @@ along with this program. If not, see . /* Locking resynchronize hack */ #define LOCKING_RESYNC_ENABLE -/* +/* * Force NKRO * - * Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved + * Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved * state in the bootmagic EEPROM settings. (Note that NKRO must be enabled in the * makefile for this to work.) * * If forced on, NKRO can be disabled via magic key (default = LShift+RShift+N) * until the next keyboard reset. * - * NKRO may prevent your keystrokes from being detected in the BIOS, but it is + * NKRO may prevent your keystrokes from being detected in the BIOS, but it is * fully operational during normal computer usage. * * For a less heavy-handed approach, enable NKRO via magic key (LShift+RShift+N) @@ -90,7 +91,7 @@ along with this program. If not, see . * the keyboard. They are best used in combination with the HID Listen program, * found here: https://www.pjrc.com/teensy/hid_listen.html * - * The options below allow the magic key functionality to be changed. This is + * The options below allow the magic key functionality to be changed. This is * useful if your keyboard/keypad is missing keys and you want magic key support. * */ -- cgit v1.2.3-24-g4f1b From 1ae6011cef2230826a9e6db6c5b638677bc640b7 Mon Sep 17 00:00:00 2001 From: Eric Tang Date: Tue, 24 May 2016 08:44:40 -0700 Subject: Clean up #343's code (#348) --- quantum/matrix.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'quantum') diff --git a/quantum/matrix.c b/quantum/matrix.c index 22126aa7a..d5fd7def8 100644 --- a/quantum/matrix.c +++ b/quantum/matrix.c @@ -37,10 +37,8 @@ static const io_pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS; /* matrix state */ #if DIODE_DIRECTION == COL2ROW static matrix_row_t matrix[MATRIX_ROWS]; -static matrix_row_t debouncing_matrix[MATRIX_ROWS]; #else static matrix_col_t matrix[MATRIX_COLS]; -static matrix_col_t debouncing_matrix[MATRIX_COLS]; #endif static int8_t debouncing_delay = -1; @@ -99,6 +97,7 @@ void matrix_init(void) { #if DIODE_DIRECTION == COL2ROW uint8_t matrix_scan(void) { + static matrix_row_t debouncing_matrix[MATRIX_ROWS]; for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { toggle_row(r); matrix_row_t state = read_cols(); @@ -146,6 +145,7 @@ matrix_row_t matrix_get_row(uint8_t row) { #else uint8_t matrix_scan(void) { + static matrix_col_t debouncing_matrix[MATRIX_COLS]; for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { toggle_col(c); matrix_col_t state = read_rows(); -- cgit v1.2.3-24-g4f1b From 287eb7ad148abc8fe3fb014218d71e205fd9131d Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Tue, 24 May 2016 11:56:53 -0400 Subject: Converted audio play functions to *_user (#349) * Updated personal layouts * tweaked personal * Nightly - Audio Cleanup Refactored the LUTs. Abstracted some of the registers out of audio to use more functional names. Split audio into audio and audio_pwm. WIP * nightly - collapsed code * Added check for note playing to LEDs * Usability tweaks * TWEAE * nightly added extra kcs to keymap common * turned on Plank audio * Added backlight breathing to atomic * reverted accidental merge * Added music and audio toggles to Quantum.c * Redid the audio callbacks * Adjusted default planck layout to use the user tone naming * tabs to spaces * Rewrote the ALL recipe to allow for faster parallel make * tabs to spaces * Renamed custom event functions to be 'startup_user' and 'shutdown_user'. Also moved the prototypes around. * Tweaked pvc atomic layout to work with the pvc planck. * updates midi scale calling --- quantum/audio/audio.c | 17 ------------ quantum/audio/audio.h | 6 +---- quantum/keymap_common.c | 3 ++- quantum/quantum.c | 69 ++++++++++++++++++++++++++++++++----------------- quantum/quantum.h | 4 +++ 5 files changed, 52 insertions(+), 47 deletions(-) (limited to 'quantum') diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index 32f64417e..3ca249fdf 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -475,20 +475,3 @@ void increase_tempo(uint8_t tempo_change) { note_tempo -= tempo_change; } } - - -//------------------------------------------------------------------------------ -// Override these functions in your keymap file to play different tunes on -// startup and bootloader jump -__attribute__ ((weak)) -void play_startup_tone() {} - -__attribute__ ((weak)) -void play_goodbye_tone() {} - -__attribute__ ((weak)) -void audio_on_user() {} - -__attribute__ ((weak)) -void play_music_scale() {} -//------------------------------------------------------------------------------ diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index b46f587bb..00d45f7ac 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -5,6 +5,7 @@ #include "musical_notes.h" #include "song_list.h" #include "voices.h" +#include "quantum.h" #ifndef AUDIO_H #define AUDIO_H @@ -87,9 +88,4 @@ void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat, float n_rest) bool is_playing_notes(void); -void play_goodbye_tone(void); -void play_startup_tone(void); -void audio_on_user(void); -void play_music_scale(void); - #endif \ No newline at end of file diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c index 1d9ab2e05..ba7269388 100644 --- a/quantum/keymap_common.c +++ b/quantum/keymap_common.c @@ -26,6 +26,7 @@ along with this program. If not, see . #include "backlight.h" #include "bootloader.h" #include "eeconfig.h" +#include "quantum.h" #ifdef MIDI_ENABLE #include "keymap_midi.h" @@ -190,7 +191,7 @@ static action_t keycode_to_action(uint16_t keycode) clear_keyboard(); #ifdef AUDIO_ENABLE stop_all_notes(); - play_goodbye_tone(); + shutdown_user(); #endif _delay_ms(250); #ifdef ATREUS_ASTAR diff --git a/quantum/quantum.c b/quantum/quantum.c index 34c575af4..eb64a99a4 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -23,17 +23,16 @@ int offset = 7; #ifdef AUDIO_ENABLE bool music_activated = false; - float music_scale[][2] = SONG(MUSIC_SCALE_SOUND); - // music sequencer - static bool music_sequence_recording = false; - static bool music_sequence_playing = false; - static float music_sequence[16] = {0}; - static uint8_t music_sequence_count = 0; - static uint8_t music_sequence_position = 0; +// music sequencer +static bool music_sequence_recording = false; +static bool music_sequence_playing = false; +static float music_sequence[16] = {0}; +static uint8_t music_sequence_count = 0; +static uint8_t music_sequence_position = 0; - static uint16_t music_sequence_timer = 0; - static uint16_t music_sequence_interval = 100; +static uint16_t music_sequence_timer = 0; +static uint16_t music_sequence_interval = 100; #endif @@ -133,7 +132,7 @@ bool process_record_quantum(keyrecord_t *record) { #ifdef MIDI_ENABLE if (keycode == MI_ON && record->event.pressed) { midi_activated = true; - play_music_scale(); + music_scale_user(); return false; } @@ -230,37 +229,37 @@ bool process_record_quantum(keyrecord_t *record) { } if (keycode == MU_ON && record->event.pressed) { - music_on(); - return false; + music_on(); + return false; } if (keycode == MU_OFF && record->event.pressed) { - music_off(); - return false; + music_off(); + return false; } if (keycode == MU_TOG && record->event.pressed) { if (music_activated) { - music_off(); + music_off(); } else { - music_on(); + music_on(); } return false; } if (keycode == MUV_IN && record->event.pressed) { - voice_iterate(); - play_music_scale(); - return false; + voice_iterate(); + music_scale_user(); + return false; } if (keycode == MUV_DE && record->event.pressed) { - voice_deiterate(); - play_music_scale(); - return false; + voice_deiterate(); + music_scale_user(); + return false; } if (music_activated) { @@ -272,12 +271,14 @@ bool process_record_quantum(keyrecord_t *record) { music_sequence_count = 0; return false; } + if (keycode == KC_LALT && record->event.pressed) { // Stop recording/playing stop_all_notes(); music_sequence_recording = false; music_sequence_playing = false; return false; } + if (keycode == KC_LGUI && record->event.pressed) { // Start playing stop_all_notes(); music_sequence_recording = false; @@ -289,12 +290,13 @@ bool process_record_quantum(keyrecord_t *record) { if (keycode == KC_UP) { if (record->event.pressed) - music_sequence_interval-=10; + music_sequence_interval-=10; return false; } + if (keycode == KC_DOWN) { if (record->event.pressed) - music_sequence_interval+=10; + music_sequence_interval+=10; return false; } @@ -459,5 +461,24 @@ void matrix_scan_quantum() { } #endif + +//------------------------------------------------------------------------------ +// Override these functions in your keymap file to play different tunes on +// different events such as startup and bootloader jump + +__attribute__ ((weak)) +void startup_user() {} + +__attribute__ ((weak)) +void shutdown_user() {} + __attribute__ ((weak)) void music_on_user() {} + +__attribute__ ((weak)) +void audio_on_user() {} + +__attribute__ ((weak)) +void music_scale_user() {} + +//------------------------------------------------------------------------------ \ No newline at end of file diff --git a/quantum/quantum.h b/quantum/quantum.h index d4da77289..69a0d8126 100644 --- a/quantum/quantum.h +++ b/quantum/quantum.h @@ -67,6 +67,10 @@ void music_toggle(void); void music_on(void); void music_off(void); +void startup_user(void); +void shutdown_user(void); +void audio_on_user(void); void music_on_user(void); +void music_scale_user(void); #endif \ No newline at end of file -- cgit v1.2.3-24-g4f1b From 1237025963484d70bbe5185a790bec6544653ccc Mon Sep 17 00:00:00 2001 From: Erez Zukerman Date: Tue, 24 May 2016 23:27:59 -0400 Subject: [Erez & Jack] Packages Space Cadet shifts into keycodes --- quantum/keymap_common.h | 2 ++ quantum/quantum.c | 44 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 45 insertions(+), 1 deletion(-) (limited to 'quantum') diff --git a/quantum/keymap_common.h b/quantum/keymap_common.h index 91d5c09c1..fafc93f7c 100644 --- a/quantum/keymap_common.h +++ b/quantum/keymap_common.h @@ -240,6 +240,8 @@ extern const uint16_t fn_actions[]; #define BL_TOGG 0x5082 #define BL_STEP 0x5083 +#define KC_LSPO 0x5084 // Left shift, open parens when tapped +#define KC_RSPC 0x5085 // Right shift, close parens when tapped // GOTO layer - 16 layers max // when: // ON_PRESS = 1 diff --git a/quantum/quantum.c b/quantum/quantum.c index eb64a99a4..753dde5c6 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -21,6 +21,7 @@ void leader_end(void) {} uint8_t starting_note = 0x0C; int offset = 7; + #ifdef AUDIO_ENABLE bool music_activated = false; @@ -59,6 +60,8 @@ uint8_t chord_key_down = 0; static uint8_t input_mode; #endif +static bool shift_interrupted[] = {0, 0, 0}; + bool keys_chord(uint8_t keys[]) { uint8_t keys_size = sizeof(keys)/sizeof(keys[0]); bool pass = true; @@ -415,6 +418,45 @@ bool process_record_quantum(keyrecord_t *record) { #endif + switch(keycode) { + case KC_LSPO: { + if (record->event.pressed) { + shift_interrupted[0] = false; + register_mods(MOD_BIT(KC_LSFT)); + } + else { + if (!shift_interrupted[0]) { + register_code(KC_9); + unregister_code(KC_9); + } + unregister_mods(MOD_BIT(KC_LSFT)); + } + return false; + break; + } + + case KC_RSPC: { + if (record->event.pressed) { + shift_interrupted[1] = false; + register_mods(MOD_BIT(KC_RSFT)); + } + else { + if (!shift_interrupted[1]) { + register_code(KC_0); + unregister_code(KC_0); + } + unregister_mods(MOD_BIT(KC_RSFT)); + } + return false; + break; + } + default: { + shift_interrupted[0] = true; + shift_interrupted[1] = true; + break; + } + } + return process_action_kb(record); } @@ -481,4 +523,4 @@ void audio_on_user() {} __attribute__ ((weak)) void music_scale_user() {} -//------------------------------------------------------------------------------ \ No newline at end of file +//------------------------------------------------------------------------------ -- cgit v1.2.3-24-g4f1b From 8bc69afc633d3e199e3ac0a5bf39e4d255f2ce4a Mon Sep 17 00:00:00 2001 From: Erez Zukerman Date: Tue, 24 May 2016 23:48:46 -0400 Subject: [Erez & Jack] Optimizes shift_interrupted array --- quantum/quantum.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'quantum') diff --git a/quantum/quantum.c b/quantum/quantum.c index 753dde5c6..c53fb19b4 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -60,7 +60,7 @@ uint8_t chord_key_down = 0; static uint8_t input_mode; #endif -static bool shift_interrupted[] = {0, 0, 0}; +static bool shift_interrupted[2] = {0, 0}; bool keys_chord(uint8_t keys[]) { uint8_t keys_size = sizeof(keys)/sizeof(keys[0]); -- cgit v1.2.3-24-g4f1b From 9d6debd9b23ffb045f63bc77dd44cafe2c7ce851 Mon Sep 17 00:00:00 2001 From: Nathan Sharfi Date: Wed, 25 May 2016 17:25:04 -0700 Subject: Add double quote for everyone; update Zweihander --- quantum/keymap_common.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'quantum') diff --git a/quantum/keymap_common.h b/quantum/keymap_common.h index fafc93f7c..db14e7d8a 100644 --- a/quantum/keymap_common.h +++ b/quantum/keymap_common.h @@ -119,6 +119,8 @@ extern const uint16_t fn_actions[]; #define KC_PLUS LSFT(KC_EQL) // + +#define KC_DQUO LSFT(KC_QUOT) // " +#define KC_DOUBLE_QUOTE KC_DQUO #define KC_LCBR LSFT(KC_LBRC) // { #define KC_LEFT_CURLY_BRACE KC_LCBR -- cgit v1.2.3-24-g4f1b From 209ee3cd052b22b4cc32aecbc4b03cb8fb229a23 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Thu, 26 May 2016 17:14:01 -0400 Subject: removes duplicate double quote and odd whitespace --- quantum/keymap_common.h | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'quantum') diff --git a/quantum/keymap_common.h b/quantum/keymap_common.h index db14e7d8a..c72c0bc29 100644 --- a/quantum/keymap_common.h +++ b/quantum/keymap_common.h @@ -88,10 +88,8 @@ extern const uint16_t fn_actions[]; #define KC_AT LSFT(KC_2) // @ - #define KC_HASH LSFT(KC_3) // # - #define KC_DLR LSFT(KC_4) // $ #define KC_DOLLAR KC_DLR @@ -113,15 +111,11 @@ extern const uint16_t fn_actions[]; #define KC_RPRN LSFT(KC_0) // ) #define KC_RIGHT_PAREN KC_RPRN - #define KC_UNDS LSFT(KC_MINS) // _ #define KC_UNDERSCORE KC_UNDS #define KC_PLUS LSFT(KC_EQL) // + -#define KC_DQUO LSFT(KC_QUOT) // " -#define KC_DOUBLE_QUOTE KC_DQUO - #define KC_LCBR LSFT(KC_LBRC) // { #define KC_LEFT_CURLY_BRACE KC_LCBR @@ -141,16 +135,14 @@ extern const uint16_t fn_actions[]; #define KC_LT LSFT(KC_COMM) // < - #define KC_GT LSFT(KC_DOT) // > - #define KC_QUES LSFT(KC_SLSH) // ? #define KC_QUESTION KC_QUES - #define KC_DQT LSFT(KC_QUOT) // " #define KC_DOUBLE_QUOTE KC_DQT +#define KC_DQUO KC_DQT #define KC_DELT KC_DELETE // Del key (four letter code) -- cgit v1.2.3-24-g4f1b From de57799530d3184722532f93d156364067d8fcd5 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Sat, 28 May 2016 11:56:06 -0400 Subject: brings alps64 up-to-date (needs testing) --- quantum/matrix.c | 6 ++++-- quantum/quantum.h | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'quantum') diff --git a/quantum/matrix.c b/quantum/matrix.c index d5fd7def8..412662a79 100644 --- a/quantum/matrix.c +++ b/quantum/matrix.c @@ -68,8 +68,10 @@ uint8_t matrix_cols(void) { void matrix_init(void) { /* frees PORTF by setting the JTD bit twice within four cycles */ - MCUCR |= _BV(JTD); - MCUCR |= _BV(JTD); + #ifdef __AVR_ATmega32U4__ + MCUCR |= _BV(JTD); + MCUCR |= _BV(JTD); + #endif /* initializes the I/O pins */ #if DIODE_DIRECTION == COL2ROW for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { diff --git a/quantum/quantum.h b/quantum/quantum.h index 69a0d8126..71533f48b 100644 --- a/quantum/quantum.h +++ b/quantum/quantum.h @@ -23,6 +23,7 @@ #include "eeconfig.h" #include #include +#include extern uint32_t default_layer_state; -- cgit v1.2.3-24-g4f1b From 38987d4c1589d2d457459f42e179be24b712be30 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Sat, 28 May 2016 12:05:17 -0400 Subject: updates quantum template to prevent backlight conflicts --- quantum/template/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'quantum') diff --git a/quantum/template/Makefile b/quantum/template/Makefile index 1a535ef2c..f101eb7a6 100644 --- a/quantum/template/Makefile +++ b/quantum/template/Makefile @@ -123,7 +123,7 @@ KEYBOARD_LOCK_ENABLE = yes # Allow locking of keyboard via magic key SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend # if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work NKRO_ENABLE = no # USB Nkey Rollover -BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality +BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality on B7 by default MIDI_ENABLE = no # MIDI controls UNICODE_ENABLE = no # Unicode BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID -- cgit v1.2.3-24-g4f1b From 17977a7e24ddab6ca101341b33c8fe7ad13e68f5 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Sat, 28 May 2016 15:22:30 -0400 Subject: process_record implementation (non-breaking for process_action ATM) --- quantum/quantum.c | 13 +++++++++++++ quantum/quantum.h | 3 +++ 2 files changed, 16 insertions(+) (limited to 'quantum') diff --git a/quantum/quantum.c b/quantum/quantum.c index c53fb19b4..d9aaafd61 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -12,6 +12,16 @@ bool process_action_kb(keyrecord_t *record) { return true; } +__attribute__ ((weak)) +bool process_record_kb(uint16_t keycode, keyrecord_t *record) { + return process_record_user(keycode, record); +} + +__attribute__ ((weak)) +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + return true; +} + __attribute__ ((weak)) void leader_start(void) {} @@ -124,6 +134,9 @@ bool process_record_quantum(keyrecord_t *record) { keycode = keymap_key_to_keycode(layer_switch_get_layer(key), key); #endif + if (!process_record_kb(keycode, record)) + return false; + // This is how you use actions here // if (keycode == KC_LEAD) { // action_t action; diff --git a/quantum/quantum.h b/quantum/quantum.h index 71533f48b..3ce940895 100644 --- a/quantum/quantum.h +++ b/quantum/quantum.h @@ -62,6 +62,9 @@ extern uint32_t default_layer_state; void matrix_init_kb(void); void matrix_scan_kb(void); bool process_action_kb(keyrecord_t *record); +bool process_record_kb(uint16_t keycode, keyrecord_t *record); +bool process_record_user(uint16_t keycode, keyrecord_t *record); + bool is_music_on(void); void music_toggle(void); -- cgit v1.2.3-24-g4f1b From a53bc24c4d5a6b1f31060e43789a12af6e39b572 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Sat, 28 May 2016 15:33:08 -0400 Subject: makes .SILENT (less verbose) by default - override with VERBOSE=1 also took out some @echo newlines to make things a bit cleaner --- quantum/quantum.mk | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'quantum') diff --git a/quantum/quantum.mk b/quantum/quantum.mk index c099d6793..00d3e8114 100644 --- a/quantum/quantum.mk +++ b/quantum/quantum.mk @@ -1,5 +1,9 @@ QUANTUM_DIR = quantum +ifndef VERBOSE +.SILENT: +endif + # # project specific files SRC += $(QUANTUM_DIR)/quantum.c \ $(QUANTUM_DIR)/keymap_common.c \ -- cgit v1.2.3-24-g4f1b From 1c9f33c06a6ef18c9c21e5841180af5ae554c34b Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Wed, 1 Jun 2016 22:49:55 -0400 Subject: adds send_string functionality (string macros) --- quantum/quantum.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ quantum/quantum.h | 2 ++ 2 files changed, 56 insertions(+) (limited to 'quantum') diff --git a/quantum/quantum.c b/quantum/quantum.c index d9aaafd61..6480e33c6 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -473,6 +473,60 @@ bool process_record_quantum(keyrecord_t *record) { return process_action_kb(record); } +bool shift_us_qwerty[0x80] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0 - 31 + 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, // 32 - 63 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, // 64 - 95 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0 // 96 - 127 +}; + +uint8_t ascii_us_qwerty[0x80] = { + 0, 0, 0, 0, 0, 0, 0, 0, KC_BSPC, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KC_ESC, 0, 0, 0, 0, // 0 - 31 + KC_SPC, KC_1, KC_QUOT, KC_3, KC_4, KC_5, KC_7, KC_QUOT, KC_9, KC_0, KC_8, KC_EQL, KC_COMM, KC_MINS, KC_DOT, // 32 - 46 + KC_SLSH, KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_SCLN, KC_SCLN, KC_COMM, KC_EQL, // 47 - 61 + KC_DOT, KC_SLSH, KC_2, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G, KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, // 62 - 78 + KC_O, KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W, KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_6, // 79 - 94 + KC_MINS, KC_GRV, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G, KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O, // 95 - 111 + KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W, KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_GRV, KC_DEL // 112 - 127 +}; + +// This is how you'd add OS colemak support + +// bool shift_us_colemak[0x80] = { +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0 - 31 +// 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, // 32 - 63 +// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, // 64 - 95 +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0 // 96 - 127 +// }; + +// #include "keymap_colemak.h" + +// uint8_t ascii_us_colemak[0x80] = { +// 0, 0, 0, 0, 0, 0, 0, 0, KC_BSPC, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KC_ESC, 0, 0, 0, 0, // 0 - 31 +// KC_SPC, KC_1, KC_QUOT, KC_3, KC_4, KC_5, KC_7, KC_QUOT, KC_9, KC_0, KC_8, KC_EQL, KC_COMM, KC_MINS, KC_DOT, // 32 - 46 +// KC_SLSH, KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, CM_SCLN, CM_SCLN, KC_COMM, KC_EQL, // 47 - 61 +// KC_DOT, KC_SLSH, KC_2, CM_A, CM_B, CM_C, CM_D, CM_E, CM_F, CM_G, CM_H, CM_I, CM_J, CM_K, CM_L, CM_M, CM_N, // 62 - 78 +// CM_O, CM_P, CM_Q, CM_R, CM_S, CM_T, CM_U, CM_V, CM_W, CM_X, CM_Y, CM_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_6, // 79 - 94 +// KC_MINS, KC_GRV, CM_A, CM_B, CM_C, CM_D, CM_E, CM_F, CM_G, CM_H, CM_I, CM_J, CM_K, CM_L, CM_M, CM_N, CM_O, // 95 - 111 +// CM_P, CM_Q, CM_R, CM_S, CM_T, CM_U, CM_V, CM_W, CM_X, CM_Y, CM_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_GRV, KC_DEL // 112 - 127 +// }; + +void send_string(char str[]) { + for (int i = 0; str[i] != 0; i++) { + uint8_t keycode = ascii_us_qwerty[str[i]]; + if (shift_us_qwerty[str[i]]) { + register_code(KC_LSFT); + register_code(keycode); + unregister_code(keycode); + unregister_code(KC_LSFT); + } else { + register_code(keycode); + unregister_code(keycode); + } + } +} + + void matrix_init_quantum() { matrix_init_kb(); } diff --git a/quantum/quantum.h b/quantum/quantum.h index 3ce940895..786bcb238 100644 --- a/quantum/quantum.h +++ b/quantum/quantum.h @@ -59,6 +59,8 @@ extern uint32_t default_layer_state; #define LEADER_DICTIONARY() if (leading && timer_elapsed(leader_time) > LEADER_TIMEOUT) #endif +void send_string(char str[]); + void matrix_init_kb(void); void matrix_scan_kb(void); bool process_action_kb(keyrecord_t *record); -- cgit v1.2.3-24-g4f1b From 4635b4453335b61df11008fa907eef221db5912b Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Wed, 1 Jun 2016 23:00:55 -0400 Subject: new line/tab in send_string --- quantum/quantum.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'quantum') diff --git a/quantum/quantum.c b/quantum/quantum.c index 6480e33c6..426cfa12b 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -481,7 +481,7 @@ bool shift_us_qwerty[0x80] = { }; uint8_t ascii_us_qwerty[0x80] = { - 0, 0, 0, 0, 0, 0, 0, 0, KC_BSPC, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KC_ESC, 0, 0, 0, 0, // 0 - 31 + 0, 0, 0, 0, 0, 0, 0, 0, KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KC_ESC, 0, 0, 0, 0, // 0 - 31 KC_SPC, KC_1, KC_QUOT, KC_3, KC_4, KC_5, KC_7, KC_QUOT, KC_9, KC_0, KC_8, KC_EQL, KC_COMM, KC_MINS, KC_DOT, // 32 - 46 KC_SLSH, KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_SCLN, KC_SCLN, KC_COMM, KC_EQL, // 47 - 61 KC_DOT, KC_SLSH, KC_2, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G, KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, // 62 - 78 -- cgit v1.2.3-24-g4f1b From 794aed37a0da5a277a07e7fa86263e0852fa9f6d Mon Sep 17 00:00:00 2001 From: Eric Tang Date: Fri, 3 Jun 2016 12:48:40 -0700 Subject: Improve string sending (#376) --- quantum/quantum.c | 149 ++++++++++++++++++++++++++++++++++++------------------ quantum/quantum.h | 7 ++- 2 files changed, 104 insertions(+), 52 deletions(-) (limited to 'quantum') diff --git a/quantum/quantum.c b/quantum/quantum.c index 426cfa12b..bc63fb614 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -287,14 +287,14 @@ bool process_record_quantum(keyrecord_t *record) { music_sequence_count = 0; return false; } - + if (keycode == KC_LALT && record->event.pressed) { // Stop recording/playing stop_all_notes(); music_sequence_recording = false; music_sequence_playing = false; return false; } - + if (keycode == KC_LGUI && record->event.pressed) { // Start playing stop_all_notes(); music_sequence_recording = false; @@ -309,7 +309,7 @@ bool process_record_quantum(keyrecord_t *record) { music_sequence_interval-=10; return false; } - + if (keycode == KC_DOWN) { if (record->event.pressed) music_sequence_interval+=10; @@ -473,57 +473,106 @@ bool process_record_quantum(keyrecord_t *record) { return process_action_kb(record); } -bool shift_us_qwerty[0x80] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0 - 31 - 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, // 32 - 63 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, // 64 - 95 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0 // 96 - 127 +const bool ascii_to_qwerty_shift_lut[0x80] PROGMEM = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 0, 0, 0, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 1, 0 }; -uint8_t ascii_us_qwerty[0x80] = { - 0, 0, 0, 0, 0, 0, 0, 0, KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KC_ESC, 0, 0, 0, 0, // 0 - 31 - KC_SPC, KC_1, KC_QUOT, KC_3, KC_4, KC_5, KC_7, KC_QUOT, KC_9, KC_0, KC_8, KC_EQL, KC_COMM, KC_MINS, KC_DOT, // 32 - 46 - KC_SLSH, KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_SCLN, KC_SCLN, KC_COMM, KC_EQL, // 47 - 61 - KC_DOT, KC_SLSH, KC_2, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G, KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, // 62 - 78 - KC_O, KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W, KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_6, // 79 - 94 - KC_MINS, KC_GRV, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G, KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O, // 95 - 111 - KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W, KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_GRV, KC_DEL // 112 - 127 +const uint8_t ascii_to_qwerty_keycode_lut[0x80] PROGMEM = { + 0, 0, 0, 0, 0, 0, 0, 0, + KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, KC_ESC, 0, 0, 0, 0, + KC_SPC, KC_1, KC_QUOT, KC_3, KC_4, KC_5, KC_7, KC_QUOT, + KC_9, KC_0, KC_8, KC_EQL, KC_COMM, KC_MINS, KC_DOT, KC_SLSH, + KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, + KC_8, KC_9, KC_SCLN, KC_SCLN, KC_COMM, KC_EQL, KC_DOT, KC_SLSH, + KC_2, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G, + KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O, + KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W, + KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_6, KC_MINS, + KC_GRV, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G, + KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O, + KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W, + KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_GRV, KC_DEL }; -// This is how you'd add OS colemak support - -// bool shift_us_colemak[0x80] = { -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0 - 31 -// 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, // 32 - 63 -// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, // 64 - 95 -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0 // 96 - 127 -// }; - -// #include "keymap_colemak.h" - -// uint8_t ascii_us_colemak[0x80] = { -// 0, 0, 0, 0, 0, 0, 0, 0, KC_BSPC, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KC_ESC, 0, 0, 0, 0, // 0 - 31 -// KC_SPC, KC_1, KC_QUOT, KC_3, KC_4, KC_5, KC_7, KC_QUOT, KC_9, KC_0, KC_8, KC_EQL, KC_COMM, KC_MINS, KC_DOT, // 32 - 46 -// KC_SLSH, KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, CM_SCLN, CM_SCLN, KC_COMM, KC_EQL, // 47 - 61 -// KC_DOT, KC_SLSH, KC_2, CM_A, CM_B, CM_C, CM_D, CM_E, CM_F, CM_G, CM_H, CM_I, CM_J, CM_K, CM_L, CM_M, CM_N, // 62 - 78 -// CM_O, CM_P, CM_Q, CM_R, CM_S, CM_T, CM_U, CM_V, CM_W, CM_X, CM_Y, CM_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_6, // 79 - 94 -// KC_MINS, KC_GRV, CM_A, CM_B, CM_C, CM_D, CM_E, CM_F, CM_G, CM_H, CM_I, CM_J, CM_K, CM_L, CM_M, CM_N, CM_O, // 95 - 111 -// CM_P, CM_Q, CM_R, CM_S, CM_T, CM_U, CM_V, CM_W, CM_X, CM_Y, CM_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_GRV, KC_DEL // 112 - 127 -// }; - -void send_string(char str[]) { - for (int i = 0; str[i] != 0; i++) { - uint8_t keycode = ascii_us_qwerty[str[i]]; - if (shift_us_qwerty[str[i]]) { - register_code(KC_LSFT); - register_code(keycode); - unregister_code(keycode); - unregister_code(KC_LSFT); - } else { - register_code(keycode); - unregister_code(keycode); +/* for users whose OSes are set to Colemak */ +#if 0 +#include "keymap_colemak.h" + +const bool ascii_to_colemak_shift_lut[0x80] PROGMEM = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 0, 0, 0, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 1, 0 +}; + +const uint8_t ascii_to_colemak_keycode_lut[0x80] PROGMEM = { + 0, 0, 0, 0, 0, 0, 0, 0, + KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, KC_ESC, 0, 0, 0, 0, + KC_SPC, KC_1, KC_QUOT, KC_3, KC_4, KC_5, KC_7, KC_QUOT, + KC_9, KC_0, KC_8, KC_EQL, KC_COMM, KC_MINS, KC_DOT, KC_SLSH, + KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, + KC_8, KC_9, CM_SCLN, CM_SCLN, KC_COMM, KC_EQL, KC_DOT, KC_SLSH, + KC_2, CM_A, CM_B, CM_C, CM_D, CM_E, CM_F, CM_G, + CM_H, CM_I, CM_J, CM_K, CM_L, CM_M, CM_N, CM_O, + CM_P, CM_Q, CM_R, CM_S, CM_T, CM_U, CM_V, CM_W, + CM_X, CM_Y, CM_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_6, KC_MINS, + KC_GRV, CM_A, CM_B, CM_C, CM_D, CM_E, CM_F, CM_G, + CM_H, CM_I, CM_J, CM_K, CM_L, CM_M, CM_N, CM_O, + CM_P, CM_Q, CM_R, CM_S, CM_T, CM_U, CM_V, CM_W, + CM_X, CM_Y, CM_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_GRV, KC_DEL +}; + +#endif + +void send_string(const char *str) { + while (1) { + uint8_t keycode; + uint8_t ascii_code = pgm_read_byte(str); + if (!ascii_code) break; + keycode = pgm_read_byte(&ascii_to_qwerty_keycode_lut[ascii_code]); + if (pgm_read_byte(&ascii_to_qwerty_shift_lut[ascii_code])) { + register_code(KC_LSFT); + register_code(keycode); + unregister_code(keycode); + unregister_code(KC_LSFT); + } + else { + register_code(keycode); + unregister_code(keycode); + } + ++str; } - } } @@ -572,7 +621,7 @@ void matrix_scan_quantum() { #endif //------------------------------------------------------------------------------ -// Override these functions in your keymap file to play different tunes on +// Override these functions in your keymap file to play different tunes on // different events such as startup and bootloader jump __attribute__ ((weak)) diff --git a/quantum/quantum.h b/quantum/quantum.h index 786bcb238..69277b9e3 100644 --- a/quantum/quantum.h +++ b/quantum/quantum.h @@ -1,6 +1,7 @@ #ifndef QUANTUM_H #define QUANTUM_H +#include #include "matrix.h" #include "keymap_common.h" #ifdef BACKLIGHT_ENABLE @@ -25,6 +26,8 @@ #include #include +#define SEND_STRING(str) send_string(PSTR(str)) + extern uint32_t default_layer_state; #ifndef NO_ACTION_LAYER @@ -59,7 +62,7 @@ extern uint32_t default_layer_state; #define LEADER_DICTIONARY() if (leading && timer_elapsed(leader_time) > LEADER_TIMEOUT) #endif -void send_string(char str[]); +void send_string(const char *str); void matrix_init_kb(void); void matrix_scan_kb(void); @@ -79,4 +82,4 @@ void audio_on_user(void); void music_on_user(void); void music_scale_user(void); -#endif \ No newline at end of file +#endif -- cgit v1.2.3-24-g4f1b From d9e4dad0a828a8a904f44dda090a4d6d08fe2948 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Sat, 11 Jun 2016 13:31:31 -0400 Subject: Makefile redo & other features (#395) * .build containment implemented * no destructive variable setting - builds in either folder * make from 3 places * cleans before each build * make from root with keyboard=keyboard, keymap=keymap * make from keyboard/keyboard with keymap=keymap * make from keymaps/keymap * only implemented on planck * adds color diag to avr-gcc * makefiles for all plancks, clean-up * quick build-all makefile for plancks * reformatting of make output (colors) * color toggle, tmk path corrections * correct if statement for color * move config.h to main makefile, updates preonic, atomic * format update, all keyboards targets * makefile optional for build all target, alps and arrow_pad updated * alps updated * make planck default, trying out travis recipe for all-keyboards * all-keymaps target, different travis recipe * updates alps64 * updates keyboards to new format * updates clue* projects * all projects updated, specialise EZ .hex, let .hex through * updates travis * automatically find root, keyboard, keymap * silent echo, cleaned-up mass make output * updates all keyboards' .hex files except EZ * Rename Bantam44.c to bantam44.c * Rename Bantam44.h to bantam44.h * nananana * adds six key keyboard * does same to ez as rest * updates send_string example * brings ergodox_ez up to date * updates template/new project script * adds sixkeyboard * adds readme for sixkeyboard * adds sixkeyboard to travis * filenames, gitignore mess * define clock prescaler stuff manually * make quick, size test example * documentation and dfu-no-build --- quantum/quantum.mk | 58 ------------------------------- quantum/template/Makefile | 51 ++------------------------- quantum/template/README.md | 2 +- quantum/template/keymaps/default.c | 30 ---------------- quantum/template/keymaps/default/keymap.c | 30 ++++++++++++++++ 5 files changed, 34 insertions(+), 137 deletions(-) delete mode 100644 quantum/quantum.mk delete mode 100644 quantum/template/keymaps/default.c create mode 100644 quantum/template/keymaps/default/keymap.c (limited to 'quantum') diff --git a/quantum/quantum.mk b/quantum/quantum.mk deleted file mode 100644 index 00d3e8114..000000000 --- a/quantum/quantum.mk +++ /dev/null @@ -1,58 +0,0 @@ -QUANTUM_DIR = quantum - -ifndef VERBOSE -.SILENT: -endif - -# # project specific files -SRC += $(QUANTUM_DIR)/quantum.c \ - $(QUANTUM_DIR)/keymap_common.c \ - $(QUANTUM_DIR)/led.c - -# ifdef KEYMAP_FILE -# ifneq (,$(shell grep USING_MIDI '$(KEYMAP_FILE)')) -# MIDI_ENABLE=yes -# $(info * Overriding MIDI_ENABLE setting - $(KEYMAP_FILE) requires it) -# endif -# ifneq (,$(shell grep USING_UNICODE '$(KEYMAP_FILE)')) -# UNICODE_ENABLE=yes -# $(info * Overriding UNICODE_ENABLE setting - $(KEYMAP_FILE) requires it) -# endif -# ifneq (,$(shell grep USING_BACKLIGHT '$(KEYMAP_FILE)')) -# BACKLIGHT_ENABLE=yes -# $(info * Overriding BACKLIGHT_ENABLE setting - $(KEYMAP_FILE) requires it) -# endif -# endif - -ifndef CUSTOM_MATRIX - SRC += $(QUANTUM_DIR)/matrix.c -endif - -#ifeq ($(strip $(MIDI_ENABLE)), yes) -# SRC += $(QUANTUM_DIR)/keymap_midi.c -#endif - -ifeq ($(strip $(AUDIO_ENABLE)), yes) - SRC += $(QUANTUM_DIR)/audio/audio.c - SRC += $(QUANTUM_DIR)/audio/voices.c - SRC += $(QUANTUM_DIR)/audio/luts.c -endif - -ifeq ($(strip $(RGBLIGHT_ENABLE)), yes) - SRC += $(QUANTUM_DIR)/light_ws2812.c - SRC += $(QUANTUM_DIR)/rgblight.c - OPT_DEFS += -DRGBLIGHT_ENABLE -endif - -# Optimize size but this may cause error "relocation truncated to fit" -#EXTRALDFLAGS = -Wl,--relax - -# Search Path -VPATH += $(TOP_DIR)/$(QUANTUM_DIR) -VPATH += $(TOP_DIR)/$(QUANTUM_DIR)/keymap_extras -VPATH += $(TOP_DIR)/$(QUANTUM_DIR)/audio - -include $(TMK_DIR)/protocol/lufa.mk - -include $(TMK_DIR)/common.mk -include $(TMK_DIR)/rules.mk diff --git a/quantum/template/Makefile b/quantum/template/Makefile index f101eb7a6..8772b0920 100644 --- a/quantum/template/Makefile +++ b/quantum/template/Makefile @@ -38,28 +38,6 @@ # To rebuild project do "make clean" then "make all". #---------------------------------------------------------------------------- -# Target file name (without extension). -TARGET = %KEYBOARD% - - -# Directory common source filess exist -TOP_DIR = ../.. -TMK_DIR = ../../tmk_core - -# Directory keyboard dependent files exist -TARGET_DIR = . - -# # project specific files -SRC = %KEYBOARD%.c - -ifdef KEYMAP - SRC := keymaps/$(KEYMAP).c $(SRC) -else - SRC := keymaps/default.c $(SRC) -endif - -CONFIG_H = config.h - # MCU name #MCU = at90usb1287 MCU = atmega32u4 @@ -113,12 +91,11 @@ OPT_DEFS += -DBOOTLOADER_SIZE=512 # Build Options # change yes to no to disable # -BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000) +BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000) MOUSEKEY_ENABLE = yes # Mouse keys(+4700) EXTRAKEY_ENABLE = yes # Audio control and System control(+450) CONSOLE_ENABLE = yes # Console for debug(+400) COMMAND_ENABLE = yes # Commands for debug and configuration -KEYBOARD_LOCK_ENABLE = yes # Allow locking of keyboard via magic key # Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend # if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work @@ -129,30 +106,8 @@ UNICODE_ENABLE = no # Unicode BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID AUDIO_ENABLE = no # Audio output on port C6 - -ifdef KEYMAP - -ifeq ("$(wildcard keymaps/$(KEYMAP).c)","") -ifneq ("$(wildcard keymaps/$(KEYMAP)/makefile.mk)","") - include keymaps/$(KEYMAP)/makefile.mk -endif -endif - -else - -ifneq ("$(wildcard keymaps/default/makefile.mk)","") - include keymaps/default/makefile.mk +ifndef QUANTUM_DIR + include ../../Makefile endif -endif - -# Optimize size but this may cause error "relocation truncated to fit" -#EXTRALDFLAGS = -Wl,--relax - -# Search Path -VPATH += $(TARGET_DIR) -VPATH += $(TOP_DIR) -VPATH += $(TMK_DIR) - -include $(TOP_DIR)/quantum/quantum.mk diff --git a/quantum/template/README.md b/quantum/template/README.md index 39f9f59d1..baaeef473 100644 --- a/quantum/template/README.md +++ b/quantum/template/README.md @@ -3,7 +3,7 @@ ## Quantum MK Firmware -For the full Quantum feature list, see [the parent README.md](/README.md). +For the full Quantum feature list, see [the parent README.md](/doc/README.md). ## Building diff --git a/quantum/template/keymaps/default.c b/quantum/template/keymaps/default.c deleted file mode 100644 index 4121fd860..000000000 --- a/quantum/template/keymaps/default.c +++ /dev/null @@ -1,30 +0,0 @@ -// This is the canonical layout file for the Quantum project. If you want to add another keyboard, -// this is the style you want to emulate. - -#include "%KEYBOARD%.h" - -const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { -[0] = KEYMAP( /* Base */ - KC_A, KC_1, KC_H, \ - KC_TAB, KC_SPC \ -), -}; - -const uint16_t PROGMEM fn_actions[] = { - -}; - -const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) -{ - // MACRODOWN only works in this function - switch(id) { - case 0: - if (record->event.pressed) { - register_code(KC_RSFT); - } else { - unregister_code(KC_RSFT); - } - break; - } - return MACRO_NONE; -}; diff --git a/quantum/template/keymaps/default/keymap.c b/quantum/template/keymaps/default/keymap.c new file mode 100644 index 000000000..4121fd860 --- /dev/null +++ b/quantum/template/keymaps/default/keymap.c @@ -0,0 +1,30 @@ +// This is the canonical layout file for the Quantum project. If you want to add another keyboard, +// this is the style you want to emulate. + +#include "%KEYBOARD%.h" + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { +[0] = KEYMAP( /* Base */ + KC_A, KC_1, KC_H, \ + KC_TAB, KC_SPC \ +), +}; + +const uint16_t PROGMEM fn_actions[] = { + +}; + +const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) +{ + // MACRODOWN only works in this function + switch(id) { + case 0: + if (record->event.pressed) { + register_code(KC_RSFT); + } else { + unregister_code(KC_RSFT); + } + break; + } + return MACRO_NONE; +}; -- cgit v1.2.3-24-g4f1b From b70248fa2144d297504eedbc80a76dfdc40d9f1f Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Fri, 17 Jun 2016 21:42:59 -0400 Subject: addresses #369 --- quantum/quantum.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) (limited to 'quantum') diff --git a/quantum/quantum.c b/quantum/quantum.c index bc63fb614..0a900aac2 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -70,6 +70,15 @@ uint8_t chord_key_down = 0; static uint8_t input_mode; #endif +// Shift / paren setup + +#ifndef LSPO_KEY + #define LSPO_KEY KC_9 +#endif +#ifndef RSPC_KEY + #define RSPC_KEY KC_0 +#endif + static bool shift_interrupted[2] = {0, 0}; bool keys_chord(uint8_t keys[]) { @@ -431,18 +440,20 @@ bool process_record_quantum(keyrecord_t *record) { #endif + // Shift / paren setup + switch(keycode) { case KC_LSPO: { if (record->event.pressed) { shift_interrupted[0] = false; - register_mods(MOD_BIT(KC_LSFT)); + register_mods(MOD_LSFT); } else { if (!shift_interrupted[0]) { - register_code(KC_9); - unregister_code(KC_9); + register_code(LSPO_KEY); + unregister_code(LSPO_KEY); } - unregister_mods(MOD_BIT(KC_LSFT)); + unregister_mods(MOD_LSFT); } return false; break; @@ -451,14 +462,14 @@ bool process_record_quantum(keyrecord_t *record) { case KC_RSPC: { if (record->event.pressed) { shift_interrupted[1] = false; - register_mods(MOD_BIT(KC_RSFT)); + register_mods(MOD_RSFT); } else { if (!shift_interrupted[1]) { - register_code(KC_0); - unregister_code(KC_0); + register_code(RSPC_KEY); + unregister_code(RSPC_KEY); } - unregister_mods(MOD_BIT(KC_RSFT)); + unregister_mods(MOD_RSFT); } return false; break; -- cgit v1.2.3-24-g4f1b From 008c8d54a0a1a1e908d372d0fe9edb45a2d491e5 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Fri, 17 Jun 2016 22:09:59 -0400 Subject: adds power_up to quantum's matrix file --- quantum/matrix.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'quantum') diff --git a/quantum/matrix.c b/quantum/matrix.c index 412662a79..4f1564ac8 100644 --- a/quantum/matrix.c +++ b/quantum/matrix.c @@ -66,6 +66,30 @@ uint8_t matrix_cols(void) { return MATRIX_COLS; } +void matrix_power_up(void) { +#if DIODE_DIRECTION == COL2ROW + for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { + /* DDRxn */ + _SFR_IO8(row_pins[r].input_addr + 1) |= _BV(row_pins[r].bit); + toggle_row(r); + } + for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { + /* PORTxn */ + _SFR_IO8(col_pins[c].input_addr + 2) |= _BV(col_pins[c].bit); + } +#else + for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { + /* DDRxn */ + _SFR_IO8(col_pins[c].input_addr + 1) |= _BV(col_pins[c].bit); + toggle_col(c); + } + for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { + /* PORTxn */ + _SFR_IO8(row_pins[r].input_addr + 2) |= _BV(row_pins[r].bit); + } +#endif +} + void matrix_init(void) { /* frees PORTF by setting the JTD bit twice within four cycles */ #ifdef __AVR_ATmega32U4__ -- cgit v1.2.3-24-g4f1b From db32864ce7029d758f57729cc2f75e051a28d0a2 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Sat, 18 Jun 2016 14:30:24 -0400 Subject: Cleans up quantum/keymap situation, removes extra lufa folders (#416) * sorts out keycodes * move midi around * remove mbed * replaces keymap with qmk/keymap_common * fixes keymap.h * keymap, config, quantum rearrange * removes unneeded lufa stuff --- quantum/audio/audio.c | 2 +- quantum/audio/audio_pwm.c | 2 +- quantum/keycode_config.c | 74 +++++++ quantum/keycode_config.h | 21 ++ quantum/keymap.c | 163 +++++++++++++++ quantum/keymap.h | 315 +++++++++++++++++++++++++++++ quantum/keymap_common.c | 323 ------------------------------ quantum/keymap_common.h | 292 --------------------------- quantum/keymap_extras/keymap_bepo.h | 2 +- quantum/keymap_extras/keymap_colemak.h | 2 +- quantum/keymap_extras/keymap_dvorak.h | 2 +- quantum/keymap_extras/keymap_fr_ch.h | 2 +- quantum/keymap_extras/keymap_french.h | 2 +- quantum/keymap_extras/keymap_french_osx.h | 2 +- quantum/keymap_extras/keymap_german.h | 2 +- quantum/keymap_extras/keymap_german_ch.h | 2 +- quantum/keymap_extras/keymap_german_osx.h | 2 +- quantum/keymap_extras/keymap_neo2.h | 2 +- quantum/keymap_extras/keymap_nordic.h | 2 +- quantum/keymap_extras/keymap_plover.h | 2 +- quantum/keymap_extras/keymap_spanish.h | 2 +- quantum/keymap_extras/keymap_uk.h | 2 +- quantum/keymap_midi.c | 2 +- quantum/quantum.c | 183 +++++++++++------ quantum/quantum.h | 13 +- quantum/template/template.h | 2 +- 26 files changed, 724 insertions(+), 696 deletions(-) create mode 100644 quantum/keycode_config.c create mode 100644 quantum/keycode_config.h create mode 100644 quantum/keymap.c create mode 100644 quantum/keymap.h delete mode 100644 quantum/keymap_common.c delete mode 100644 quantum/keymap_common.h (limited to 'quantum') diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index 3ca249fdf..ead5fbf3e 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -6,7 +6,7 @@ #include #include "print.h" #include "audio.h" -#include "keymap_common.h" +#include "keymap.h" #include "eeconfig.h" diff --git a/quantum/audio/audio_pwm.c b/quantum/audio/audio_pwm.c index 328a253a7..f820eec1b 100644 --- a/quantum/audio/audio_pwm.c +++ b/quantum/audio/audio_pwm.c @@ -6,7 +6,7 @@ #include #include "print.h" #include "audio.h" -#include "keymap_common.h" +#include "keymap.h" #include "eeconfig.h" diff --git a/quantum/keycode_config.c b/quantum/keycode_config.c new file mode 100644 index 000000000..6d90781a1 --- /dev/null +++ b/quantum/keycode_config.c @@ -0,0 +1,74 @@ +#include "keycode_config.h" + +extern keymap_config_t keymap_config; + +uint16_t keycode_config(uint16_t keycode) { + + switch (keycode) { + case KC_CAPSLOCK: + case KC_LOCKING_CAPS: + if (keymap_config.swap_control_capslock || keymap_config.capslock_to_control) { + return KC_LCTL; + } + return keycode; + case KC_LCTL: + if (keymap_config.swap_control_capslock) { + return KC_CAPSLOCK; + } + return KC_LCTL; + case KC_LALT: + if (keymap_config.swap_lalt_lgui) { + if (keymap_config.no_gui) { + return KC_NO; + } + return KC_LGUI; + } + return KC_LALT; + case KC_LGUI: + if (keymap_config.swap_lalt_lgui) { + return KC_LALT; + } + if (keymap_config.no_gui) { + return KC_NO; + } + return KC_LGUI; + case KC_RALT: + if (keymap_config.swap_ralt_rgui) { + if (keymap_config.no_gui) { + return KC_NO; + } + return KC_RGUI; + } + return KC_RALT; + case KC_RGUI: + if (keymap_config.swap_ralt_rgui) { + return KC_RALT; + } + if (keymap_config.no_gui) { + return KC_NO; + } + return KC_RGUI; + case KC_GRAVE: + if (keymap_config.swap_grave_esc) { + return KC_ESC; + } + return KC_GRAVE; + case KC_ESC: + if (keymap_config.swap_grave_esc) { + return KC_GRAVE; + } + return KC_ESC; + case KC_BSLASH: + if (keymap_config.swap_backslash_backspace) { + return KC_BSPACE; + } + return KC_BSLASH; + case KC_BSPACE: + if (keymap_config.swap_backslash_backspace) { + return KC_BSLASH; + } + return KC_BSPACE; + default: + return keycode; + } +} \ No newline at end of file diff --git a/quantum/keycode_config.h b/quantum/keycode_config.h new file mode 100644 index 000000000..c41c08706 --- /dev/null +++ b/quantum/keycode_config.h @@ -0,0 +1,21 @@ +#include "eeconfig.h" +#include "keycode.h" + +uint16_t keycode_config(uint16_t keycode); + +/* NOTE: Not portable. Bit field order depends on implementation */ +typedef union { + uint16_t raw; + struct { + bool swap_control_capslock:1; + bool capslock_to_control:1; + bool swap_lalt_lgui:1; + bool swap_ralt_rgui:1; + bool no_gui:1; + bool swap_grave_esc:1; + bool swap_backslash_backspace:1; + bool nkro:1; + }; +} keymap_config_t; + +keymap_config_t keymap_config; \ No newline at end of file diff --git a/quantum/keymap.c b/quantum/keymap.c new file mode 100644 index 000000000..203a82d95 --- /dev/null +++ b/quantum/keymap.c @@ -0,0 +1,163 @@ +/* +Copyright 2012,2013 Jun Wako + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include "keymap.h" +#include "report.h" +#include "keycode.h" +#include "action_layer.h" +#include +#include "action.h" +#include "action_macro.h" +#include "debug.h" +#include "backlight.h" +#include "quantum.h" + +#ifdef MIDI_ENABLE + #include "keymap_midi.h" +#endif + +extern keymap_config_t keymap_config; + +#include +#include + +/* converts key to action */ +action_t action_for_key(uint8_t layer, keypos_t key) +{ + // 16bit keycodes - important + uint16_t keycode = keymap_key_to_keycode(layer, key); + + // keycode remapping + keycode = keycode_config(keycode); + + action_t action; + uint8_t action_layer, when, mod; + + switch (keycode) { + case KC_FN0 ... KC_FN31: + action.code = pgm_read_word(&fn_actions[FN_INDEX(keycode)]); + break; + case KC_A ... KC_EXSEL: + case KC_LCTRL ... KC_RGUI: + action.code = ACTION_KEY(keycode); + break; + case KC_SYSTEM_POWER ... KC_SYSTEM_WAKE: + action.code = ACTION_USAGE_SYSTEM(KEYCODE2SYSTEM(keycode)); + break; + case KC_AUDIO_MUTE ... KC_WWW_FAVORITES: + action.code = ACTION_USAGE_CONSUMER(KEYCODE2CONSUMER(keycode)); + break; + case KC_MS_UP ... KC_MS_ACCEL2: + action.code = ACTION_MOUSEKEY(keycode); + break; + case KC_TRNS: + action.code = ACTION_TRANSPARENT; + break; + case QK_MODS ... QK_MODS_MAX: ; + // Has a modifier + // Split it up + action.code = ACTION_MODS_KEY(keycode >> 8, keycode & 0xFF); // adds modifier to key + break; + case QK_FUNCTION ... QK_FUNCTION_MAX: ; + // Is a shortcut for function action_layer, pull last 12bits + // This means we have 4,096 FN macros at our disposal + action.code = pgm_read_word(&fn_actions[(int)keycode & 0xFFF]); + break; + case QK_MACRO ... QK_MACRO_MAX: + action.code = ACTION_MACRO(keycode & 0xFF); + break; + case QK_LAYER_TAP ... QK_LAYER_TAP_MAX: + action.code = ACTION_LAYER_TAP_KEY((keycode >> 0x8) & 0xF, keycode & 0xFF); + break; + case QK_TO ... QK_TO_MAX: ; + // Layer set "GOTO" + when = (keycode >> 0x4) & 0x3; + action_layer = keycode & 0xF; + action.code = ACTION_LAYER_SET(action_layer, when); + break; + case QK_MOMENTARY ... QK_MOMENTARY_MAX: ; + // Momentary action_layer + action_layer = keycode & 0xFF; + action.code = ACTION_LAYER_MOMENTARY(action_layer); + break; + case QK_DEF_LAYER ... QK_DEF_LAYER_MAX: ; + // Set default action_layer + action_layer = keycode & 0xFF; + action.code = ACTION_DEFAULT_LAYER_SET(action_layer); + break; + case QK_TOGGLE_LAYER ... QK_TOGGLE_LAYER_MAX: ; + // Set toggle + action_layer = keycode & 0xFF; + action.code = ACTION_LAYER_TOGGLE(action_layer); + break; + case QK_ONE_SHOT_LAYER ... QK_ONE_SHOT_LAYER_MAX: ; + // OSL(action_layer) - One-shot action_layer + action_layer = keycode & 0xFF; + action.code = ACTION_LAYER_ONESHOT(action_layer); + break; + case QK_ONE_SHOT_MOD ... QK_ONE_SHOT_MOD_MAX: ; + // OSM(mod) - One-shot mod + mod = keycode & 0xFF; + action.code = ACTION_MODS_ONESHOT(mod); + break; + case QK_MOD_TAP ... QK_MOD_TAP_MAX: + action.code = ACTION_MODS_TAP_KEY((keycode >> 0x8) & 0xF, keycode & 0xFF); + break; + #ifdef BACKLIGHT_ENABLE + case BL_0 ... BL_15: + action.code = ACTION_BACKLIGHT_LEVEL(keycode - BL_0); + break; + case BL_DEC: + action.code = ACTION_BACKLIGHT_DECREASE(); + break; + case BL_INC: + action.code = ACTION_BACKLIGHT_INCREASE(); + break; + case BL_TOGG: + action.code = ACTION_BACKLIGHT_TOGGLE(); + break; + case BL_STEP: + action.code = ACTION_BACKLIGHT_STEP(); + break; + #endif + default: + action.code = ACTION_NO; + break; + } + return action; +} + + +/* Macro */ +__attribute__ ((weak)) +const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) +{ + return MACRO_NONE; +} + +/* Function */ +__attribute__ ((weak)) +void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) +{ +} + +/* translates key to keycode */ +uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key) +{ + // Read entire word (16bits) + return pgm_read_word(&keymaps[(layer)][(key.row)][(key.col)]); +} diff --git a/quantum/keymap.h b/quantum/keymap.h new file mode 100644 index 000000000..979ab2da1 --- /dev/null +++ b/quantum/keymap.h @@ -0,0 +1,315 @@ +/* +Copyright 2012,2013 Jun Wako + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#ifndef KEYMAP_H +#define KEYMAP_H + +#include +#include +#include "action.h" +#include +#include "keycode.h" +#include "action_macro.h" +#include "report.h" +#include "host.h" +// #include "print.h" +#include "debug.h" +#include "keycode_config.h" + +/* translates key to keycode */ +uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key); + +/* translates Fn keycode to action */ +action_t keymap_fn_to_action(uint16_t keycode); + +extern const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS]; +extern const uint16_t fn_actions[]; + +enum quantum_keycodes { + // Ranges used in shortucuts - not to be used directly + QK_TMK = 0x0000, + QK_TMK_MAX = 0x00FF, + QK_MODS = 0x0100, + QK_LCTL = 0x0100, + QK_LSFT = 0x0200, + QK_LALT = 0x0400, + QK_LGUI = 0x0800, + QK_RCTL = 0x1100, + QK_RSFT = 0x1200, + QK_RALT = 0x1400, + QK_RGUI = 0x1800, + QK_MODS_MAX = 0x1FFF, + QK_FUNCTION = 0x2000, + QK_FUNCTION_MAX = 0x2FFF, + QK_MACRO = 0x3000, + QK_MACRO_MAX = 0x3FFF, + QK_LAYER_TAP = 0x4000, + QK_LAYER_TAP_MAX = 0x4FFF, + QK_TO = 0x5000, + QK_TO_MAX = 0x50FF, + QK_MOMENTARY = 0x5100, + QK_MOMENTARY_MAX = 0x51FF, + QK_DEF_LAYER = 0x5200, + QK_DEF_LAYER_MAX = 0x52FF, + QK_TOGGLE_LAYER = 0x5300, + QK_TOGGLE_LAYER_MAX = 0x53FF, + QK_ONE_SHOT_LAYER = 0x5400, + QK_ONE_SHOT_LAYER_MAX = 0x54FF, + QK_ONE_SHOT_MOD = 0x5500, + QK_ONE_SHOT_MOD_MAX = 0x55FF, +#ifndef DISABLE_CHORDING + QK_CHORDING = 0x5600, + QK_CHORDING_MAX = 0x56FF, +#endif + QK_MOD_TAP = 0x6000, + QK_MOD_TAP_MAX = 0x6FFF, +#ifdef UNICODE_ENABLE + QK_UNICODE = 0x8000, + QK_UNICODE_MAX = 0xFFFF, +#endif + + // Loose keycodes - to be used directly + + RESET = 0x7000, + DEBUG, + MAGIC_SWAP_CONTROL_CAPSLOCK, + MAGIC_CAPSLOCK_TO_CONTROL, + MAGIC_SWAP_LALT_LGUI, + MAGIC_SWAP_RALT_RGUI, + MAGIC_NO_GUI, + MAGIC_SWAP_GRAVE_ESC, + MAGIC_SWAP_BACKSLASH_BACKSPACE, + MAGIC_HOST_NKRO, + MAGIC_SWAP_ALT_GUI, + MAGIC_UNSWAP_CONTROL_CAPSLOCK, + MAGIC_UNCAPSLOCK_TO_CONTROL, + MAGIC_UNSWAP_LALT_LGUI, + MAGIC_UNSWAP_RALT_RGUI, + MAGIC_UNNO_GUI, + MAGIC_UNSWAP_GRAVE_ESC, + MAGIC_UNSWAP_BACKSLASH_BACKSPACE, + MAGIC_UNHOST_NKRO, + MAGIC_UNSWAP_ALT_GUI, + + // Leader key +#ifndef DISABLE_LEADER + KC_LEAD, +#endif + + // Audio on/off/toggle + AU_ON, + AU_OFF, + AU_TOG, + + // Music mode on/off/toggle + MU_ON, + MU_OFF, + MU_TOG, + + // Music voice iterate + MUV_IN, + MUV_DE, + + // Midi mode on/off + MI_ON, + MI_OFF, + + // Backlight functionality + BL_0, + BL_1, + BL_2, + BL_3, + BL_4, + BL_5, + BL_6, + BL_7, + BL_8, + BL_9, + BL_10, + BL_11, + BL_12, + BL_13, + BL_14, + BL_15, + BL_DEC, + BL_INC, + BL_TOGG, + BL_STEP, + + // Left shift, open paren + KC_LSPO, + + // Right shift, close paren + KC_RSPC, +}; + +// Ability to use mods in layouts +#define LCTL(kc) (kc | QK_LCTL) +#define LSFT(kc) (kc | QK_LSFT) +#define LALT(kc) (kc | QK_LALT) +#define LGUI(kc) (kc | QK_LGUI) +#define RCTL(kc) (kc | QK_RCTL) +#define RSFT(kc) (kc | QK_RSFT) +#define RALT(kc) (kc | QK_RALT) +#define RGUI(kc) (kc | QK_RGUI) + +#define HYPR(kc) (kc | QK_LCTL | QK_LSFT | QK_LALT | QK_LGUI) +#define MEH(kc) (kc | QK_LCTL | QK_LSFT | QK_LALT) +#define LCAG(kc) (kc | QK_LCTL | QK_LALT | QK_LGUI) + +#define MOD_HYPR 0xf +#define MOD_MEH 0x7 + + +// Aliases for shifted symbols +// Each key has a 4-letter code, and some have longer aliases too. +// While the long aliases are descriptive, the 4-letter codes +// make for nicer grid layouts (everything lines up), and are +// the preferred style for Quantum. +#define KC_TILD LSFT(KC_GRV) // ~ +#define KC_TILDE KC_TILD + +#define KC_EXLM LSFT(KC_1) // ! +#define KC_EXCLAIM KC_EXLM + +#define KC_AT LSFT(KC_2) // @ + +#define KC_HASH LSFT(KC_3) // # + +#define KC_DLR LSFT(KC_4) // $ +#define KC_DOLLAR KC_DLR + +#define KC_PERC LSFT(KC_5) // % +#define KC_PERCENT KC_PERC + +#define KC_CIRC LSFT(KC_6) // ^ +#define KC_CIRCUMFLEX KC_CIRC + +#define KC_AMPR LSFT(KC_7) // & +#define KC_AMPERSAND KC_AMPR + +#define KC_ASTR LSFT(KC_8) // * +#define KC_ASTERISK KC_ASTR + +#define KC_LPRN LSFT(KC_9) // ( +#define KC_LEFT_PAREN KC_LPRN + +#define KC_RPRN LSFT(KC_0) // ) +#define KC_RIGHT_PAREN KC_RPRN + +#define KC_UNDS LSFT(KC_MINS) // _ +#define KC_UNDERSCORE KC_UNDS + +#define KC_PLUS LSFT(KC_EQL) // + + +#define KC_LCBR LSFT(KC_LBRC) // { +#define KC_LEFT_CURLY_BRACE KC_LCBR + +#define KC_RCBR LSFT(KC_RBRC) // } +#define KC_RIGHT_CURLY_BRACE KC_RCBR + +#define KC_LABK LSFT(KC_COMM) // < +#define KC_LEFT_ANGLE_BRACKET KC_LABK + +#define KC_RABK LSFT(KC_DOT) // > +#define KC_RIGHT_ANGLE_BRACKET KC_RABK + +#define KC_COLN LSFT(KC_SCLN) // : +#define KC_COLON KC_COLN + +#define KC_PIPE LSFT(KC_BSLS) // | + +#define KC_LT LSFT(KC_COMM) // < + +#define KC_GT LSFT(KC_DOT) // > + +#define KC_QUES LSFT(KC_SLSH) // ? +#define KC_QUESTION KC_QUES + +#define KC_DQT LSFT(KC_QUOT) // " +#define KC_DOUBLE_QUOTE KC_DQT +#define KC_DQUO KC_DQT + +#define KC_DELT KC_DELETE // Del key (four letter code) + +// Alias for function layers than expand past FN31 +#define FUNC(kc) (kc | QK_FUNCTION) + +// Aliases +#define S(kc) LSFT(kc) +#define F(kc) FUNC(kc) + +#define M(kc) (kc | QK_MACRO) + +#define MACRODOWN(...) (record->event.pressed ? MACRO(__VA_ARGS__) : MACRO_NONE) + +// L-ayer, T-ap - 256 keycode max, 16 layer max +#define LT(layer, kc) (kc | QK_LAYER_TAP | ((layer & 0xF) << 8)) + +#define AG_SWAP MAGIC_SWAP_ALT_GUI +#define AG_NORM MAGIC_UNSWAP_ALT_GUI + +#define BL_ON BL_9 +#define BL_OFF BL_0 + +// GOTO layer - 16 layers max +// when: +// ON_PRESS = 1 +// ON_RELEASE = 2 +// Unless you have a good reason not to do so, prefer ON_PRESS (1) as your default. +#define TO(layer, when) (layer | QK_TO | (when << 0x4)) + +// Momentary switch layer - 256 layer max +#define MO(layer) (layer | QK_MOMENTARY) + +// Set default layer - 256 layer max +#define DF(layer) (layer | QK_DEF_LAYER) + +// Toggle to layer - 256 layer max +#define TG(layer) (layer | QK_TOGGLE_LAYER) + +// One-shot layer - 256 layer max +#define OSL(layer) (layer | QK_ONE_SHOT_LAYER) + +// One-shot mod +#define OSM(layer) (layer | QK_ONE_SHOT_MOD) + +// M-od, T-ap - 256 keycode max +#define MT(mod, kc) (kc | QK_MOD_TAP | ((mod & 0xF) << 8)) +#define CTL_T(kc) MT(MOD_LCTL, kc) +#define SFT_T(kc) MT(MOD_LSFT, kc) +#define ALT_T(kc) MT(MOD_LALT, kc) +#define GUI_T(kc) MT(MOD_LGUI, kc) +#define C_S_T(kc) MT(MOD_LCTL | MOD_LSFT, kc) // Control + Shift e.g. for gnome-terminal +#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 +#define LCAG_T(kc) MT(MOD_LCTL | MOD_LALT | MOD_LGUI, kc) // Left control alt and gui +#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/ + +// Dedicated keycode versions for Hyper and Meh, if you want to use them as standalone keys rather than mod-tap +#define KC_HYPR HYPR(KC_NO) +#define KC_MEH MEH(KC_NO) + +#ifdef UNICODE_ENABLE + // For sending unicode codes. + // You may not send codes over 7FFF -- this supports most of UTF8. + // To have a key that sends out Œ, go UC(0x0152) + #define UNICODE(n) (n | QK_UNICODE) + #define UC(n) UNICODE(n) +#endif + + +#endif diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c deleted file mode 100644 index ba7269388..000000000 --- a/quantum/keymap_common.c +++ /dev/null @@ -1,323 +0,0 @@ -/* -Copyright 2012,2013 Jun Wako - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -#include "keymap_common.h" -#include "report.h" -#include "keycode.h" -#include "action_layer.h" -#include -#include "action.h" -#include "action_macro.h" -#include "debug.h" -#include "backlight.h" -#include "bootloader.h" -#include "eeconfig.h" -#include "quantum.h" - -#ifdef MIDI_ENABLE - #include "keymap_midi.h" -#endif - -extern keymap_config_t keymap_config; - -#include -#include -#ifdef AUDIO_ENABLE - #include "audio.h" -#endif /* AUDIO_ENABLE */ - -static action_t keycode_to_action(uint16_t keycode); - -/* converts key to action */ -action_t action_for_key(uint8_t layer, keypos_t key) -{ - // 16bit keycodes - important - uint16_t keycode = keymap_key_to_keycode(layer, key); - - switch (keycode) { - case KC_FN0 ... KC_FN31: - return keymap_fn_to_action(keycode); - case KC_CAPSLOCK: - case KC_LOCKING_CAPS: - if (keymap_config.swap_control_capslock || keymap_config.capslock_to_control) { - return keycode_to_action(KC_LCTL); - } - return keycode_to_action(keycode); - case KC_LCTL: - if (keymap_config.swap_control_capslock) { - return keycode_to_action(KC_CAPSLOCK); - } - return keycode_to_action(KC_LCTL); - case KC_LALT: - if (keymap_config.swap_lalt_lgui) { - if (keymap_config.no_gui) { - return keycode_to_action(ACTION_NO); - } - return keycode_to_action(KC_LGUI); - } - return keycode_to_action(KC_LALT); - case KC_LGUI: - if (keymap_config.swap_lalt_lgui) { - return keycode_to_action(KC_LALT); - } - if (keymap_config.no_gui) { - return keycode_to_action(ACTION_NO); - } - return keycode_to_action(KC_LGUI); - case KC_RALT: - if (keymap_config.swap_ralt_rgui) { - if (keymap_config.no_gui) { - return keycode_to_action(ACTION_NO); - } - return keycode_to_action(KC_RGUI); - } - return keycode_to_action(KC_RALT); - case KC_RGUI: - if (keymap_config.swap_ralt_rgui) { - return keycode_to_action(KC_RALT); - } - if (keymap_config.no_gui) { - return keycode_to_action(ACTION_NO); - } - return keycode_to_action(KC_RGUI); - case KC_GRAVE: - if (keymap_config.swap_grave_esc) { - return keycode_to_action(KC_ESC); - } - return keycode_to_action(KC_GRAVE); - case KC_ESC: - if (keymap_config.swap_grave_esc) { - return keycode_to_action(KC_GRAVE); - } - return keycode_to_action(KC_ESC); - case KC_BSLASH: - if (keymap_config.swap_backslash_backspace) { - return keycode_to_action(KC_BSPACE); - } - return keycode_to_action(KC_BSLASH); - case KC_BSPACE: - if (keymap_config.swap_backslash_backspace) { - return keycode_to_action(KC_BSLASH); - } - return keycode_to_action(KC_BSPACE); - default: - return keycode_to_action(keycode); - } -} - - -/* Macro */ -__attribute__ ((weak)) -const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) -{ - return MACRO_NONE; -} - -/* Function */ -__attribute__ ((weak)) -void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) -{ -} - -/* translates keycode to action */ -static action_t keycode_to_action(uint16_t keycode) -{ - action_t action; - switch (keycode) { - case KC_A ... KC_EXSEL: - case KC_LCTRL ... KC_RGUI: - action.code = ACTION_KEY(keycode); - break; - case KC_SYSTEM_POWER ... KC_SYSTEM_WAKE: - action.code = ACTION_USAGE_SYSTEM(KEYCODE2SYSTEM(keycode)); - break; - case KC_AUDIO_MUTE ... KC_WWW_FAVORITES: - action.code = ACTION_USAGE_CONSUMER(KEYCODE2CONSUMER(keycode)); - break; - case KC_MS_UP ... KC_MS_ACCEL2: - action.code = ACTION_MOUSEKEY(keycode); - break; - case KC_TRNS: - action.code = ACTION_TRANSPARENT; - break; - case LCTL(0) ... 0x1FFF: ; - // Has a modifier - // Split it up - action.code = ACTION_MODS_KEY(keycode >> 8, keycode & 0xFF); // adds modifier to key - break; - case FUNC(0) ... FUNC(0xFFF): ; - // Is a shortcut for function layer, pull last 12bits - // This means we have 4,096 FN macros at our disposal - return keymap_func_to_action(keycode & 0xFFF); - break; - case M(0) ... M(0xFF): - action.code = ACTION_MACRO(keycode & 0xFF); - break; - case LT(0, 0) ... LT(0xFF, 0xF): - action.code = ACTION_LAYER_TAP_KEY((keycode >> 0x8) & 0xF, keycode & 0xFF); - break; - #ifdef BACKLIGHT_ENABLE - case BL_0 ... BL_15: - action.code = ACTION_BACKLIGHT_LEVEL(keycode & 0x000F); - break; - case BL_DEC: - action.code = ACTION_BACKLIGHT_DECREASE(); - break; - case BL_INC: - action.code = ACTION_BACKLIGHT_INCREASE(); - break; - case BL_TOGG: - action.code = ACTION_BACKLIGHT_TOGGLE(); - break; - case BL_STEP: - action.code = ACTION_BACKLIGHT_STEP(); - break; - #endif - case RESET: ; // RESET is 0x5000, which is why this is here - clear_keyboard(); - #ifdef AUDIO_ENABLE - stop_all_notes(); - shutdown_user(); - #endif - _delay_ms(250); - #ifdef ATREUS_ASTAR - *(uint16_t *)0x0800 = 0x7777; // these two are a-star-specific - #endif - bootloader_jump(); - break; - case DEBUG: ; // DEBUG is 0x5001 - print("\nDEBUG: enabled.\n"); - debug_enable = true; - break; - case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_UNSWAP_ALT_GUI: - // MAGIC actions (BOOTMAGIC without the boot) - if (!eeconfig_is_enabled()) { - eeconfig_init(); - } - /* keymap config */ - keymap_config.raw = eeconfig_read_keymap(); - if (keycode == MAGIC_SWAP_CONTROL_CAPSLOCK) { - keymap_config.swap_control_capslock = 1; - } else if (keycode == MAGIC_CAPSLOCK_TO_CONTROL) { - keymap_config.capslock_to_control = 1; - } else if (keycode == MAGIC_SWAP_LALT_LGUI) { - keymap_config.swap_lalt_lgui = 1; - } else if (keycode == MAGIC_SWAP_RALT_RGUI) { - keymap_config.swap_ralt_rgui = 1; - } else if (keycode == MAGIC_NO_GUI) { - keymap_config.no_gui = 1; - } else if (keycode == MAGIC_SWAP_GRAVE_ESC) { - keymap_config.swap_grave_esc = 1; - } else if (keycode == MAGIC_SWAP_BACKSLASH_BACKSPACE) { - keymap_config.swap_backslash_backspace = 1; - } else if (keycode == MAGIC_HOST_NKRO) { - keymap_config.nkro = 1; - } else if (keycode == MAGIC_SWAP_ALT_GUI) { - keymap_config.swap_lalt_lgui = 1; - keymap_config.swap_ralt_rgui = 1; - } - /* UNs */ - else if (keycode == MAGIC_UNSWAP_CONTROL_CAPSLOCK) { - keymap_config.swap_control_capslock = 0; - } else if (keycode == MAGIC_UNCAPSLOCK_TO_CONTROL) { - keymap_config.capslock_to_control = 0; - } else if (keycode == MAGIC_UNSWAP_LALT_LGUI) { - keymap_config.swap_lalt_lgui = 0; - } else if (keycode == MAGIC_UNSWAP_RALT_RGUI) { - keymap_config.swap_ralt_rgui = 0; - } else if (keycode == MAGIC_UNNO_GUI) { - keymap_config.no_gui = 0; - } else if (keycode == MAGIC_UNSWAP_GRAVE_ESC) { - keymap_config.swap_grave_esc = 0; - } else if (keycode == MAGIC_UNSWAP_BACKSLASH_BACKSPACE) { - keymap_config.swap_backslash_backspace = 0; - } else if (keycode == MAGIC_UNHOST_NKRO) { - keymap_config.nkro = 0; - } else if (keycode == MAGIC_UNSWAP_ALT_GUI) { - keymap_config.swap_lalt_lgui = 0; - keymap_config.swap_ralt_rgui = 0; - } - eeconfig_update_keymap(keymap_config.raw); - break; - case TO(0, 1) ... OSM(0xFF): ; - // Layer movement shortcuts - // See .h to see constraints/usage - int type = (keycode >> 0x8) & 0xF; - if (type == 0x1) { - // Layer set "GOTO" - int when = (keycode >> 0x4) & 0x3; - int layer = keycode & 0xF; - action.code = ACTION_LAYER_SET(layer, when); - } else if (type == 0x2) { - // Momentary layer - int layer = keycode & 0xFF; - action.code = ACTION_LAYER_MOMENTARY(layer); - } else if (type == 0x3) { - // Set default layer - int layer = keycode & 0xFF; - action.code = ACTION_DEFAULT_LAYER_SET(layer); - } else if (type == 0x4) { - // Set default layer - int layer = keycode & 0xFF; - action.code = ACTION_LAYER_TOGGLE(layer); - } else if (type == 0x5) { - // OSL(layer) - One-shot layer - int layer = keycode & 0xFF; - action.code = ACTION_LAYER_ONESHOT(layer); - } else if (type == 0x6) { - // OSM(mod) - One-shot mod - int mod = keycode & 0xFF; - action.code = ACTION_MODS_ONESHOT(mod); - } - break; - case MT(0, 0) ... MT(0xF, 0xFF): - action.code = ACTION_MODS_TAP_KEY((keycode >> 0x8) & 0xF, keycode & 0xFF); - break; - default: - action.code = ACTION_NO; - break; - } - return action; -} - - -/* translates key to keycode */ -uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key) -{ - // Read entire word (16bits) - return pgm_read_word(&keymaps[(layer)][(key.row)][(key.col)]); -} - -/* translates Fn keycode to action */ -action_t keymap_fn_to_action(uint16_t keycode) -{ - return (action_t){ .code = pgm_read_word(&fn_actions[FN_INDEX(keycode)]) }; -} - -action_t keymap_func_to_action(uint16_t keycode) -{ - // For FUNC without 8bit limit - return (action_t){ .code = pgm_read_word(&fn_actions[(int)keycode]) }; -} - -void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3) { - if (IS_LAYER_ON(layer1) && IS_LAYER_ON(layer2)) { - layer_on(layer3); - } else { - layer_off(layer3); - } -} diff --git a/quantum/keymap_common.h b/quantum/keymap_common.h deleted file mode 100644 index c72c0bc29..000000000 --- a/quantum/keymap_common.h +++ /dev/null @@ -1,292 +0,0 @@ -/* -Copyright 2012,2013 Jun Wako - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -#ifndef KEYMAP_H -#define KEYMAP_H - -#include -#include -#include "action.h" -#include -#include "keycode.h" -#include "keymap.h" -#include "action_macro.h" -#include "report.h" -#include "host.h" -// #include "print.h" -#include "debug.h" - -/* NOTE: Not portable. Bit field order depends on implementation */ -typedef union { - uint16_t raw; - struct { - bool swap_control_capslock:1; - bool capslock_to_control:1; - bool swap_lalt_lgui:1; - bool swap_ralt_rgui:1; - bool no_gui:1; - bool swap_grave_esc:1; - bool swap_backslash_backspace:1; - bool nkro:1; - }; -} keymap_config_t; - - -/* translates key to keycode */ -uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key); - -/* translates Fn keycode to action */ -action_t keymap_fn_to_action(uint16_t keycode); - -/* translates Fn keycode to action */ -action_t keymap_func_to_action(uint16_t keycode); - -extern const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS]; -extern const uint16_t fn_actions[]; - -// Ability to use mods in layouts -#define LCTL(kc) kc | 0x0100 -#define LSFT(kc) kc | 0x0200 -#define LALT(kc) kc | 0x0400 -#define LGUI(kc) kc | 0x0800 -#define HYPR(kc) kc | 0x0F00 -#define MEH(kc) kc | 0x0700 -#define LCAG(kc) kc | 0x0D00 // Modifier Ctrl Alt and GUI - -#define MOD_HYPR 0xf -#define MOD_MEH 0x7 - -#define RCTL(kc) kc | 0x1100 -#define RSFT(kc) kc | 0x1200 -#define RALT(kc) kc | 0x1400 -#define RGUI(kc) kc | 0x1800 - -// Aliases for shifted symbols -// Each key has a 4-letter code, and some have longer aliases too. -// While the long aliases are descriptive, the 4-letter codes -// make for nicer grid layouts (everything lines up), and are -// the preferred style for Quantum. -#define KC_TILD LSFT(KC_GRV) // ~ -#define KC_TILDE KC_TILD - -#define KC_EXLM LSFT(KC_1) // ! -#define KC_EXCLAIM KC_EXLM - -#define KC_AT LSFT(KC_2) // @ - -#define KC_HASH LSFT(KC_3) // # - -#define KC_DLR LSFT(KC_4) // $ -#define KC_DOLLAR KC_DLR - -#define KC_PERC LSFT(KC_5) // % -#define KC_PERCENT KC_PERC - -#define KC_CIRC LSFT(KC_6) // ^ -#define KC_CIRCUMFLEX KC_CIRC - -#define KC_AMPR LSFT(KC_7) // & -#define KC_AMPERSAND KC_AMPR - -#define KC_ASTR LSFT(KC_8) // * -#define KC_ASTERISK KC_ASTR - -#define KC_LPRN LSFT(KC_9) // ( -#define KC_LEFT_PAREN KC_LPRN - -#define KC_RPRN LSFT(KC_0) // ) -#define KC_RIGHT_PAREN KC_RPRN - -#define KC_UNDS LSFT(KC_MINS) // _ -#define KC_UNDERSCORE KC_UNDS - -#define KC_PLUS LSFT(KC_EQL) // + - -#define KC_LCBR LSFT(KC_LBRC) // { -#define KC_LEFT_CURLY_BRACE KC_LCBR - -#define KC_RCBR LSFT(KC_RBRC) // } -#define KC_RIGHT_CURLY_BRACE KC_RCBR - -#define KC_LABK LSFT(KC_COMM) // < -#define KC_LEFT_ANGLE_BRACKET KC_LABK - -#define KC_RABK LSFT(KC_DOT) // > -#define KC_RIGHT_ANGLE_BRACKET KC_RABK - -#define KC_COLN LSFT(KC_SCLN) // : -#define KC_COLON KC_COLN - -#define KC_PIPE LSFT(KC_BSLS) // | - -#define KC_LT LSFT(KC_COMM) // < - -#define KC_GT LSFT(KC_DOT) // > - -#define KC_QUES LSFT(KC_SLSH) // ? -#define KC_QUESTION KC_QUES - -#define KC_DQT LSFT(KC_QUOT) // " -#define KC_DOUBLE_QUOTE KC_DQT -#define KC_DQUO KC_DQT - -#define KC_DELT KC_DELETE // Del key (four letter code) - -// Alias for function layers than expand past FN31 -#define FUNC(kc) kc | 0x2000 - -// Aliases -#define S(kc) LSFT(kc) -#define F(kc) FUNC(kc) - -#define M(kc) (kc | 0x3000) - -#define MACRODOWN(...) (record->event.pressed ? MACRO(__VA_ARGS__) : MACRO_NONE) - -// 0x3100+ is free - -// L-ayer, T-ap - 256 keycode max, 16 layer max -#define LT(layer, kc) (kc | 0x4000 | ((layer & 0xF) << 8)) - -#define RESET 0x5000 -#define DEBUG 0x5001 - -// MAGIC keycodes -#define MAGIC_SWAP_CONTROL_CAPSLOCK 0x5002 -#define MAGIC_UNSWAP_CONTROL_CAPSLOCK 0x5003 -#define MAGIC_CAPSLOCK_TO_CONTROL 0x5004 -#define MAGIC_UNCAPSLOCK_TO_CONTROL 0x5005 -#define MAGIC_SWAP_LALT_LGUI 0x5006 -#define MAGIC_UNSWAP_LALT_LGUI 0x5007 -#define MAGIC_SWAP_RALT_RGUI 0x5008 -#define MAGIC_UNSWAP_RALT_RGUI 0x5009 -#define MAGIC_NO_GUI 0x500a -#define MAGIC_UNNO_GUI 0x500b -#define MAGIC_SWAP_GRAVE_ESC 0x500c -#define MAGIC_UNSWAP_GRAVE_ESC 0x500d -#define MAGIC_SWAP_BACKSLASH_BACKSPACE 0x500e -#define MAGIC_UNSWAP_BACKSLASH_BACKSPACE 0x500f -#define MAGIC_HOST_NKRO 0x5010 -#define MAGIC_UNHOST_NKRO 0x5011 -#define MAGIC_SWAP_ALT_GUI 0x5012 -#define MAGIC_UNSWAP_ALT_GUI 0x5013 - -#define AG_SWAP MAGIC_SWAP_ALT_GUI -#define AG_NORM MAGIC_UNSWAP_ALT_GUI - -#define KC_LEAD 0x5014 - -// Audio on/off -#define AU_ON 0x5020 -#define AU_OFF 0x5021 -#define AU_TOG 0x5022 - -// Music mode on/off -#define MU_ON 0x5023 -#define MU_OFF 0x5024 -#define MU_TOG 0x5025 - -// Music voice iterate -#define MUV_IN 0x5026 -#define MUV_DE 0x5027 - -// Midi mode on/off -#define MI_ON 0x5028 -#define MI_OFF 0x5029 - -// These affect the backlight (if your keyboard has one). -// We don't need to comment them out if your keyboard doesn't have a backlight, -// since they don't take up any space. -#define BL_ON 0x5079 -#define BL_OFF 0x5070 -#define BL_0 0x5070 -#define BL_1 0x5071 -#define BL_2 0x5072 -#define BL_3 0x5073 -#define BL_4 0x5074 -#define BL_5 0x5075 -#define BL_6 0x5076 -#define BL_7 0x5077 -#define BL_8 0x5078 -#define BL_9 0x5079 -#define BL_10 0x507A -#define BL_11 0x507B -#define BL_12 0x507C -#define BL_13 0x507D -#define BL_14 0x507E -#define BL_15 0x507F -#define BL_DEC 0x5080 -#define BL_INC 0x5081 -#define BL_TOGG 0x5082 -#define BL_STEP 0x5083 - -#define KC_LSPO 0x5084 // Left shift, open parens when tapped -#define KC_RSPC 0x5085 // Right shift, close parens when tapped -// GOTO layer - 16 layers max -// when: -// ON_PRESS = 1 -// ON_RELEASE = 2 -// Unless you have a good reason not to do so, prefer ON_PRESS (1) as your default. -#define TO(layer, when) (layer | 0x5100 | (when << 0x4)) - -// Momentary switch layer - 256 layer max -#define MO(layer) (layer | 0x5200) - -// Set default layer - 256 layer max -#define DF(layer) (layer | 0x5300) - -// Toggle to layer - 256 layer max -#define TG(layer) (layer | 0x5400) - -// One-shot layer - 256 layer max -#define OSL(layer) (layer | 0x5500) - -// One-shot mod -#define OSM(layer) (layer | 0x5600) - -// chording is currently at 0x57xx - -// M-od, T-ap - 256 keycode max -#define MT(mod, kc) (kc | 0x7000 | ((mod & 0xF) << 8)) -#define CTL_T(kc) MT(0x1, kc) -#define SFT_T(kc) MT(0x2, kc) -#define ALT_T(kc) MT(0x4, kc) -#define GUI_T(kc) MT(0x8, kc) -#define C_S_T(kc) MT(0x3, kc) // Control + Shift e.g. for gnome-terminal -#define MEH_T(kc) MT(0x7, kc) // Meh is a less hyper version of the Hyper key -- doesn't include Win or Cmd, so just alt+shift+ctrl -#define LCAG_T(kc) MT(0xD, kc) // Left control alt and gui -#define ALL_T(kc) MT(0xF, kc) // see http://brettterpstra.com/2012/12/08/a-useful-caps-lock-key/ - -// Dedicated keycode versions for Hyper and Meh, if you want to use them as standalone keys rather than mod-tap -#define KC_HYPR HYPR(KC_NO) -#define KC_MEH MEH(KC_NO) - -#ifdef UNICODE_ENABLE - // For sending unicode codes. - // You may not send codes over 7FFF -- this supports most of UTF8. - // To have a key that sends out Œ, go UC(0x0152) - #define UNICODE(n) (n | 0x8000) - #define UC(n) UNICODE(n) -#endif - -// For tri-layer -void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3); -#define IS_LAYER_ON(layer) (layer_state & (1UL << (layer))) -#define IS_LAYER_OFF(layer) (~layer_state & (1UL << (layer))) - - -#endif diff --git a/quantum/keymap_extras/keymap_bepo.h b/quantum/keymap_extras/keymap_bepo.h index 1ab2d63dd..4c3096054 100644 --- a/quantum/keymap_extras/keymap_bepo.h +++ b/quantum/keymap_extras/keymap_bepo.h @@ -2,7 +2,7 @@ #ifndef KEYMAP_BEPO_H #define KEYMAP_BEPO_H -#include "keymap_common.h" +#include "keymap.h" // Alt gr #ifndef ALTGR diff --git a/quantum/keymap_extras/keymap_colemak.h b/quantum/keymap_extras/keymap_colemak.h index 8a418c615..b8d615748 100644 --- a/quantum/keymap_extras/keymap_colemak.h +++ b/quantum/keymap_extras/keymap_colemak.h @@ -1,7 +1,7 @@ #ifndef KEYMAP_COLEMAK_H #define KEYMAP_COLEMAK_H -#include "keymap_common.h" +#include "keymap.h" // For software implementation of colemak #define CM_Q KC_Q #define CM_W KC_W diff --git a/quantum/keymap_extras/keymap_dvorak.h b/quantum/keymap_extras/keymap_dvorak.h index 93e355bf9..e855056e8 100644 --- a/quantum/keymap_extras/keymap_dvorak.h +++ b/quantum/keymap_extras/keymap_dvorak.h @@ -1,7 +1,7 @@ #ifndef KEYMAP_DVORAK_H #define KEYMAP_DVORAK_H -#include "keymap_common.h" +#include "keymap.h" // Normal characters #define DV_GRV KC_GRV diff --git a/quantum/keymap_extras/keymap_fr_ch.h b/quantum/keymap_extras/keymap_fr_ch.h index d3884c19a..3fd971357 100644 --- a/quantum/keymap_extras/keymap_fr_ch.h +++ b/quantum/keymap_extras/keymap_fr_ch.h @@ -1,7 +1,7 @@ #ifndef KEYMAP_FR_CH #define KEYMAP_FR_CH -#include "keymap_common.h" +#include "keymap.h" // Alt gr #define ALGR(kc) kc | 0x1400 diff --git a/quantum/keymap_extras/keymap_french.h b/quantum/keymap_extras/keymap_french.h index e03a121a2..2a44c80b1 100644 --- a/quantum/keymap_extras/keymap_french.h +++ b/quantum/keymap_extras/keymap_french.h @@ -1,7 +1,7 @@ #ifndef KEYMAP_FRENCH_H #define KEYMAP_FRENCH_H -#include "keymap_common.h" +#include "keymap.h" // Alt gr #define ALGR(kc) kc | 0x1400 diff --git a/quantum/keymap_extras/keymap_french_osx.h b/quantum/keymap_extras/keymap_french_osx.h index eb31bfb4d..004d73ee2 100644 --- a/quantum/keymap_extras/keymap_french_osx.h +++ b/quantum/keymap_extras/keymap_french_osx.h @@ -1,7 +1,7 @@ #ifndef KEYMAP_FRENCH_OSX_H #define KEYMAP_FRENCH_OSX_H -#include "keymap_common.h" +#include "keymap.h" // Normal characters #define FR_AT KC_GRV diff --git a/quantum/keymap_extras/keymap_german.h b/quantum/keymap_extras/keymap_german.h index dbad26f8a..3f9ae8bad 100644 --- a/quantum/keymap_extras/keymap_german.h +++ b/quantum/keymap_extras/keymap_german.h @@ -1,7 +1,7 @@ #ifndef KEYMAP_GERMAN #define KEYMAP_GERMAN -#include "keymap_common.h" +#include "keymap.h" // Alt gr #define ALGR(kc) kc | 0x1400 diff --git a/quantum/keymap_extras/keymap_german_ch.h b/quantum/keymap_extras/keymap_german_ch.h index 0874abf7d..6a782bcd7 100644 --- a/quantum/keymap_extras/keymap_german_ch.h +++ b/quantum/keymap_extras/keymap_german_ch.h @@ -1,7 +1,7 @@ #ifndef KEYMAP_SWISS_GERMAN #define KEYMAP_SWISS_GERMAN -#include "keymap_common.h" +#include "keymap.h" // Alt gr #define ALGR(kc) kc | 0x1400 diff --git a/quantum/keymap_extras/keymap_german_osx.h b/quantum/keymap_extras/keymap_german_osx.h index ee725bad5..b2040a278 100644 --- a/quantum/keymap_extras/keymap_german_osx.h +++ b/quantum/keymap_extras/keymap_german_osx.h @@ -4,7 +4,7 @@ #ifdef KEYMAP_GERMAN #warning redefining german keys #endif -#include "keymap_common.h" +#include "keymap.h" // Alt gr diff --git a/quantum/keymap_extras/keymap_neo2.h b/quantum/keymap_extras/keymap_neo2.h index a35ba55a5..b54cb74b9 100644 --- a/quantum/keymap_extras/keymap_neo2.h +++ b/quantum/keymap_extras/keymap_neo2.h @@ -1,7 +1,7 @@ #ifndef KEYMAP_NEO2 #define KEYMAP_NEO2 -#include "keymap_common.h" +#include "keymap.h" #include "keymap_extras/keymap_german.h" #define NEO_A KC_D diff --git a/quantum/keymap_extras/keymap_nordic.h b/quantum/keymap_extras/keymap_nordic.h index 7ef41fb79..3acb8b698 100644 --- a/quantum/keymap_extras/keymap_nordic.h +++ b/quantum/keymap_extras/keymap_nordic.h @@ -1,7 +1,7 @@ #ifndef KEYMAP_NORDIC_H #define KEYMAP_NORDIC_H -#include "keymap_common.h" +#include "keymap.h" // Alt gr #define ALGR(kc) kc | 0x1400 diff --git a/quantum/keymap_extras/keymap_plover.h b/quantum/keymap_extras/keymap_plover.h index 98e57ab7b..9b88f7d84 100644 --- a/quantum/keymap_extras/keymap_plover.h +++ b/quantum/keymap_extras/keymap_plover.h @@ -1,7 +1,7 @@ #ifndef KEYMAP_PLOVER_H #define KEYMAP_PLOVER_H -#include "keymap_common.h" +#include "keymap.h" #define PV_NUM KC_1 #define PV_LS KC_Q diff --git a/quantum/keymap_extras/keymap_spanish.h b/quantum/keymap_extras/keymap_spanish.h index 7f980afbc..512d8a374 100644 --- a/quantum/keymap_extras/keymap_spanish.h +++ b/quantum/keymap_extras/keymap_spanish.h @@ -1,7 +1,7 @@ #ifndef KEYMAP_SPANISH_H #define KEYMAP_SPANISH_H -#include "keymap_common.h" +#include "keymap.h" // Alt gr #define ALGR(kc) kc | 0x1400 diff --git a/quantum/keymap_extras/keymap_uk.h b/quantum/keymap_extras/keymap_uk.h index 5b4bd3c0d..5c5d95179 100644 --- a/quantum/keymap_extras/keymap_uk.h +++ b/quantum/keymap_extras/keymap_uk.h @@ -1,7 +1,7 @@ #ifndef KEYMAP_UK_H #define KEYMAP_UK_H -#include "keymap_common.h" +#include "keymap.h" // Alt gr #define ALGR(kc) kc | 0x1400 diff --git a/quantum/keymap_midi.c b/quantum/keymap_midi.c index ac45d2589..46049b987 100644 --- a/quantum/keymap_midi.c +++ b/quantum/keymap_midi.c @@ -15,7 +15,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -#include "keymap_common.h" +#include "keymap.h" #include "keymap_midi.h" uint8_t starting_note = 0x0C; diff --git a/quantum/quantum.c b/quantum/quantum.c index 0a900aac2..a310608e0 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -1,5 +1,4 @@ #include "quantum.h" -#include "timer.h" __attribute__ ((weak)) void matrix_init_kb(void) {} @@ -35,15 +34,15 @@ int offset = 7; #ifdef AUDIO_ENABLE bool music_activated = false; -// music sequencer -static bool music_sequence_recording = false; -static bool music_sequence_playing = false; -static float music_sequence[16] = {0}; -static uint8_t music_sequence_count = 0; -static uint8_t music_sequence_position = 0; + // music sequencer + static bool music_sequence_recording = false; + static bool music_sequence_playing = false; + static float music_sequence[16] = {0}; + static uint8_t music_sequence_count = 0; + static uint8_t music_sequence_position = 0; -static uint16_t music_sequence_timer = 0; -static uint16_t music_sequence_interval = 100; + static uint16_t music_sequence_timer = 0; + static uint16_t music_sequence_interval = 100; #endif @@ -172,10 +171,6 @@ bool process_record_quantum(keyrecord_t *record) { if (record->event.pressed) { starting_note++; // Change key midi_send_cc(&midi_device, 0, 0x7B, 0); - // midi_send_cc(&midi_device, 1, 0x7B, 0); - // midi_send_cc(&midi_device, 2, 0x7B, 0); - // midi_send_cc(&midi_device, 3, 0x7B, 0); - // midi_send_cc(&midi_device, 4, 0x7B, 0); } return false; } @@ -183,29 +178,17 @@ bool process_record_quantum(keyrecord_t *record) { if (record->event.pressed) { starting_note--; // Change key midi_send_cc(&midi_device, 0, 0x7B, 0); - // midi_send_cc(&midi_device, 1, 0x7B, 0); - // midi_send_cc(&midi_device, 2, 0x7B, 0); - // midi_send_cc(&midi_device, 3, 0x7B, 0); - // midi_send_cc(&midi_device, 4, 0x7B, 0); } return false; } if (record->event.key.col == (MATRIX_COLS - 3) && record->event.key.row == (MATRIX_ROWS - 1) && record->event.pressed) { offset++; // Change scale midi_send_cc(&midi_device, 0, 0x7B, 0); - // midi_send_cc(&midi_device, 1, 0x7B, 0); - // midi_send_cc(&midi_device, 2, 0x7B, 0); - // midi_send_cc(&midi_device, 3, 0x7B, 0); - // midi_send_cc(&midi_device, 4, 0x7B, 0); return false; } if (record->event.key.col == (MATRIX_COLS - 4) && record->event.key.row == (MATRIX_ROWS - 1) && record->event.pressed) { offset--; // Change scale midi_send_cc(&midi_device, 0, 0x7B, 0); - // midi_send_cc(&midi_device, 1, 0x7B, 0); - // midi_send_cc(&midi_device, 2, 0x7B, 0); - // midi_send_cc(&midi_device, 3, 0x7B, 0); - // midi_send_cc(&midi_device, 4, 0x7B, 0); return false; } // basic @@ -365,7 +348,7 @@ bool process_record_quantum(keyrecord_t *record) { #define DISABLE_CHORDING #ifndef DISABLE_CHORDING - if (keycode >= 0x5700 && keycode <= 0x57FF) { + if (keycode >= QK_CHORDING && keycode <= QK_CHORDING_MAX) { if (record->event.pressed) { if (!chording) { chording = true; @@ -403,7 +386,7 @@ bool process_record_quantum(keyrecord_t *record) { #ifdef UNICODE_ENABLE - if (keycode > UNICODE(0) && record->event.pressed) { + if (keycode > QK_UNICODE && record->event.pressed) { uint16_t unicode = keycode & 0x7FFF; switch(input_mode) { case UC_OSX: @@ -443,42 +426,117 @@ bool process_record_quantum(keyrecord_t *record) { // Shift / paren setup switch(keycode) { + case RESET: + if (record->event.pressed) { + clear_keyboard(); + #ifdef AUDIO_ENABLE + stop_all_notes(); + shutdown_user(); + #endif + _delay_ms(250); + #ifdef ATREUS_ASTAR + *(uint16_t *)0x0800 = 0x7777; // these two are a-star-specific + #endif + bootloader_jump(); + return false; + } + break; + case DEBUG: + if (record->event.pressed) { + print("\nDEBUG: enabled.\n"); + debug_enable = true; + return false; + } + break; + case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_UNSWAP_ALT_GUI: + if (record->event.pressed) { + // MAGIC actions (BOOTMAGIC without the boot) + if (!eeconfig_is_enabled()) { + eeconfig_init(); + } + /* keymap config */ + keymap_config.raw = eeconfig_read_keymap(); + if (keycode == MAGIC_SWAP_CONTROL_CAPSLOCK) { + keymap_config.swap_control_capslock = 1; + } else if (keycode == MAGIC_CAPSLOCK_TO_CONTROL) { + keymap_config.capslock_to_control = 1; + } else if (keycode == MAGIC_SWAP_LALT_LGUI) { + keymap_config.swap_lalt_lgui = 1; + } else if (keycode == MAGIC_SWAP_RALT_RGUI) { + keymap_config.swap_ralt_rgui = 1; + } else if (keycode == MAGIC_NO_GUI) { + keymap_config.no_gui = 1; + } else if (keycode == MAGIC_SWAP_GRAVE_ESC) { + keymap_config.swap_grave_esc = 1; + } else if (keycode == MAGIC_SWAP_BACKSLASH_BACKSPACE) { + keymap_config.swap_backslash_backspace = 1; + } else if (keycode == MAGIC_HOST_NKRO) { + keymap_config.nkro = 1; + } else if (keycode == MAGIC_SWAP_ALT_GUI) { + keymap_config.swap_lalt_lgui = 1; + keymap_config.swap_ralt_rgui = 1; + } + /* UNs */ + else if (keycode == MAGIC_UNSWAP_CONTROL_CAPSLOCK) { + keymap_config.swap_control_capslock = 0; + } else if (keycode == MAGIC_UNCAPSLOCK_TO_CONTROL) { + keymap_config.capslock_to_control = 0; + } else if (keycode == MAGIC_UNSWAP_LALT_LGUI) { + keymap_config.swap_lalt_lgui = 0; + } else if (keycode == MAGIC_UNSWAP_RALT_RGUI) { + keymap_config.swap_ralt_rgui = 0; + } else if (keycode == MAGIC_UNNO_GUI) { + keymap_config.no_gui = 0; + } else if (keycode == MAGIC_UNSWAP_GRAVE_ESC) { + keymap_config.swap_grave_esc = 0; + } else if (keycode == MAGIC_UNSWAP_BACKSLASH_BACKSPACE) { + keymap_config.swap_backslash_backspace = 0; + } else if (keycode == MAGIC_UNHOST_NKRO) { + keymap_config.nkro = 0; + } else if (keycode == MAGIC_UNSWAP_ALT_GUI) { + keymap_config.swap_lalt_lgui = 0; + keymap_config.swap_ralt_rgui = 0; + } + eeconfig_update_keymap(keymap_config.raw); + return false; + } + break; case KC_LSPO: { - if (record->event.pressed) { - shift_interrupted[0] = false; - register_mods(MOD_LSFT); - } - else { - if (!shift_interrupted[0]) { - register_code(LSPO_KEY); - unregister_code(LSPO_KEY); - } - unregister_mods(MOD_LSFT); - } - return false; - break; - } + if (record->event.pressed) { + shift_interrupted[0] = false; + register_mods(MOD_LSFT); + } + else { + if (!shift_interrupted[0]) { + register_code(LSPO_KEY); + unregister_code(LSPO_KEY); + } + unregister_mods(MOD_LSFT); + } + return false; + break; + } case KC_RSPC: { - if (record->event.pressed) { - shift_interrupted[1] = false; - register_mods(MOD_RSFT); - } - else { - if (!shift_interrupted[1]) { - register_code(RSPC_KEY); - unregister_code(RSPC_KEY); - } - unregister_mods(MOD_RSFT); - } - return false; - break; - } + if (record->event.pressed) { + shift_interrupted[1] = false; + register_mods(MOD_RSFT); + } + else { + if (!shift_interrupted[1]) { + register_code(RSPC_KEY); + unregister_code(RSPC_KEY); + } + unregister_mods(MOD_RSFT); + } + return false; + break; + } default: { - shift_interrupted[0] = true; - shift_interrupted[1] = true; - break; - } + shift_interrupted[0] = true; + shift_interrupted[1] = true; + break; + } } return process_action_kb(record); @@ -586,6 +644,13 @@ void send_string(const char *str) { } } +void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3) { + if (IS_LAYER_ON(layer1) && IS_LAYER_ON(layer2)) { + layer_on(layer3); + } else { + layer_off(layer3); + } +} void matrix_init_quantum() { matrix_init_kb(); diff --git a/quantum/quantum.h b/quantum/quantum.h index 69277b9e3..e15003805 100644 --- a/quantum/quantum.h +++ b/quantum/quantum.h @@ -3,7 +3,7 @@ #include #include "matrix.h" -#include "keymap_common.h" +#include "keymap.h" #ifdef BACKLIGHT_ENABLE #include "backlight.h" #endif @@ -25,8 +25,8 @@ #include #include #include - -#define SEND_STRING(str) send_string(PSTR(str)) +#include "bootloader.h" +#include "timer.h" extern uint32_t default_layer_state; @@ -62,15 +62,20 @@ extern uint32_t default_layer_state; #define LEADER_DICTIONARY() if (leading && timer_elapsed(leader_time) > LEADER_TIMEOUT) #endif +#define SEND_STRING(str) send_string(PSTR(str)) void send_string(const char *str); +// For tri-layer +void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3); +#define IS_LAYER_ON(layer) (layer_state & (1UL << (layer))) +#define IS_LAYER_OFF(layer) (~layer_state & (1UL << (layer))) + void matrix_init_kb(void); void matrix_scan_kb(void); bool process_action_kb(keyrecord_t *record); bool process_record_kb(uint16_t keycode, keyrecord_t *record); bool process_record_user(uint16_t keycode, keyrecord_t *record); - bool is_music_on(void); void music_toggle(void); void music_on(void); diff --git a/quantum/template/template.h b/quantum/template/template.h index 8537e3b4b..b8e7a0456 100644 --- a/quantum/template/template.h +++ b/quantum/template/template.h @@ -2,7 +2,7 @@ #define %KEYBOARD_UPPERCASE%_H #include "matrix.h" -#include "keymap_common.h" +#include "keymap.h" #ifdef BACKLIGHT_ENABLE #include "backlight.h" #endif -- cgit v1.2.3-24-g4f1b From 76076db72545bbb649f11394a12721f61579527f Mon Sep 17 00:00:00 2001 From: Jack & Erez Date: Mon, 20 Jun 2016 22:36:36 -0400 Subject: [Jack & Erez] Fixes Space Cadet right shift --- quantum/keymap.h | 2 +- quantum/quantum.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'quantum') diff --git a/quantum/keymap.h b/quantum/keymap.h index 979ab2da1..43efab7f3 100644 --- a/quantum/keymap.h +++ b/quantum/keymap.h @@ -154,7 +154,7 @@ enum quantum_keycodes { KC_LSPO, // Right shift, close paren - KC_RSPC, + KC_RSPC }; // Ability to use mods in layouts diff --git a/quantum/quantum.c b/quantum/quantum.c index a310608e0..49ac20d61 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -504,14 +504,14 @@ bool process_record_quantum(keyrecord_t *record) { case KC_LSPO: { if (record->event.pressed) { shift_interrupted[0] = false; - register_mods(MOD_LSFT); + register_mods(MOD_BIT(KC_LSFT)); } else { if (!shift_interrupted[0]) { register_code(LSPO_KEY); unregister_code(LSPO_KEY); } - unregister_mods(MOD_LSFT); + unregister_mods(MOD_BIT(KC_LSFT)); } return false; break; @@ -520,14 +520,14 @@ bool process_record_quantum(keyrecord_t *record) { case KC_RSPC: { if (record->event.pressed) { shift_interrupted[1] = false; - register_mods(MOD_RSFT); + register_mods(MOD_BIT(KC_RSFT)); } else { if (!shift_interrupted[1]) { register_code(RSPC_KEY); unregister_code(RSPC_KEY); } - unregister_mods(MOD_RSFT); + unregister_mods(MOD_BIT(KC_RSFT)); } return false; break; -- cgit v1.2.3-24-g4f1b From a8375fa15a6ca9285eb15ae89bcda898349e06f8 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Tue, 21 Jun 2016 10:21:43 -0400 Subject: updates all config.h and Makefiles to correct references, text --- quantum/template/Makefile | 40 +--------------------------------------- 1 file changed, 1 insertion(+), 39 deletions(-) (limited to 'quantum') diff --git a/quantum/template/Makefile b/quantum/template/Makefile index 8772b0920..87e4c2d2b 100644 --- a/quantum/template/Makefile +++ b/quantum/template/Makefile @@ -1,42 +1,4 @@ -#---------------------------------------------------------------------------- -# On command line: -# -# make all = Make software. -# -# make clean = Clean out built project files. -# -# make coff = Convert ELF to AVR COFF. -# -# make extcoff = Convert ELF to AVR Extended COFF. -# -# make program = Download the hex file to the device. -# Please customize your programmer settings(PROGRAM_CMD) -# -# make teensy = Download the hex file to the device, using teensy_loader_cli. -# (must have teensy_loader_cli installed). -# -# make dfu = Download the hex file to the device, using dfu-programmer (must -# have dfu-programmer installed). -# -# make flip = Download the hex file to the device, using Atmel FLIP (must -# have Atmel FLIP installed). -# -# make dfu-ee = Download the eeprom file to the device, using dfu-programmer -# (must have dfu-programmer installed). -# -# make flip-ee = Download the eeprom file to the device, using Atmel FLIP -# (must have Atmel FLIP installed). -# -# make debug = Start either simulavr or avarice as specified for debugging, -# with avr-gdb or avr-insight as the front end for debugging. -# -# make filename.s = Just compile filename.c into the assembler code only. -# -# make filename.i = Create a preprocessed source file for use in submitting -# bug reports to the GCC project. -# -# To rebuild project do "make clean" then "make all". -#---------------------------------------------------------------------------- + # MCU name #MCU = at90usb1287 -- cgit v1.2.3-24-g4f1b From 80c87054193b9243670aeb85adefbe1aa6c0fda0 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Tue, 21 Jun 2016 12:53:21 -0400 Subject: reduces rgblight warnings, integrates completely (#428) --- quantum/rgblight.c | 8 ++++---- quantum/rgblight.h | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'quantum') diff --git a/quantum/rgblight.c b/quantum/rgblight.c index 8c9ad7736..c29ffedc3 100644 --- a/quantum/rgblight.c +++ b/quantum/rgblight.c @@ -42,7 +42,7 @@ void sethsv(uint16_t hue, uint8_t sat, uint8_t val, struct cRGB *led1) { The DIM_CURVE is used only on brightness/value and on saturation (inverted). This looks the most natural. */ - uint8_t r, g, b; + uint8_t r = 0, g = 0, b = 0; val = pgm_read_byte(&DIM_CURVE[val]); sat = 255 - pgm_read_byte(&DIM_CURVE[255 - sat]); @@ -154,7 +154,7 @@ void rgblight_init(void) { } void rgblight_increase(void) { - uint8_t mode; + uint8_t mode = 0; if (rgblight_config.mode < RGBLIGHT_MODES) { mode = rgblight_config.mode + 1; } @@ -162,7 +162,7 @@ void rgblight_increase(void) { } void rgblight_decrease(void) { - uint8_t mode; + uint8_t mode = 0; if (rgblight_config.mode > 1) { //mode will never < 1, if mode is less than 1, eeprom need to be initialized. mode = rgblight_config.mode-1; } @@ -170,7 +170,7 @@ void rgblight_decrease(void) { } void rgblight_step(void) { - uint8_t mode; + uint8_t mode = 0; mode = rgblight_config.mode + 1; if (mode > RGBLIGHT_MODES) { mode = 1; diff --git a/quantum/rgblight.h b/quantum/rgblight.h index 37e207578..64f92523e 100644 --- a/quantum/rgblight.h +++ b/quantum/rgblight.h @@ -64,7 +64,6 @@ void rgblight_decrease_val(void); void rgblight_sethsv(uint16_t hue, uint8_t sat, uint8_t val); void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b); -#define EECONFIG_RGBLIGHT (uint8_t *)7 uint32_t eeconfig_read_rgblight(void); void eeconfig_update_rgblight(uint32_t val); void eeconfig_update_rgblight_default(void); -- cgit v1.2.3-24-g4f1b From 1a0bac8bccf0e156d2f3c5f14a7214f9677b6370 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Tue, 21 Jun 2016 17:42:29 -0400 Subject: Warning reductions (#430) Warning reductions --- quantum/keymap.h | 8 ++++---- quantum/keymap_extras/keymap_german_osx.h | 3 --- quantum/led.c | 6 ++++++ 3 files changed, 10 insertions(+), 7 deletions(-) (limited to 'quantum') diff --git a/quantum/keymap.h b/quantum/keymap.h index 43efab7f3..6ac3d2ace 100644 --- a/quantum/keymap.h +++ b/quantum/keymap.h @@ -294,10 +294,10 @@ enum quantum_keycodes { #define SFT_T(kc) MT(MOD_LSFT, kc) #define ALT_T(kc) MT(MOD_LALT, kc) #define GUI_T(kc) MT(MOD_LGUI, kc) -#define C_S_T(kc) MT(MOD_LCTL | MOD_LSFT, kc) // Control + Shift e.g. for gnome-terminal -#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 -#define LCAG_T(kc) MT(MOD_LCTL | MOD_LALT | MOD_LGUI, kc) // Left control alt and gui -#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/ +#define C_S_T(kc) MT((MOD_LCTL | MOD_LSFT), kc) // Control + Shift e.g. for gnome-terminal +#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 +#define LCAG_T(kc) MT((MOD_LCTL | MOD_LALT | MOD_LGUI), kc) // Left control alt and gui +#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/ // Dedicated keycode versions for Hyper and Meh, if you want to use them as standalone keys rather than mod-tap #define KC_HYPR HYPR(KC_NO) diff --git a/quantum/keymap_extras/keymap_german_osx.h b/quantum/keymap_extras/keymap_german_osx.h index b2040a278..f63f06618 100644 --- a/quantum/keymap_extras/keymap_german_osx.h +++ b/quantum/keymap_extras/keymap_german_osx.h @@ -1,9 +1,6 @@ #ifndef KEYMAP_GERMAN_OSX #define KEYMAP_GERMAN_OSX -#ifdef KEYMAP_GERMAN - #warning redefining german keys -#endif #include "keymap.h" // Alt gr diff --git a/quantum/led.c b/quantum/led.c index 208e348f3..2634ab2f6 100644 --- a/quantum/led.c +++ b/quantum/led.c @@ -24,6 +24,12 @@ void led_set_kb(uint8_t usb_led) { } +__attribute__ ((weak)) +void led_init_ports(void) +{ + +} + __attribute__ ((weak)) void led_set(uint8_t usb_led) { -- cgit v1.2.3-24-g4f1b From e329729d3a11b5798f4e2b9f65ac9bc2dcc84a9e Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Tue, 21 Jun 2016 18:32:28 -0400 Subject: adds fuse settings for atmega32u4, fixes keymap_extras includes --- quantum/keymap_extras/keymap_neo2.h | 2 +- quantum/keymap_extras/keymap_norwegian.c | 41 -------------------------------- quantum/keymap_extras/keymap_norwegian.h | 41 ++++++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 42 deletions(-) delete mode 100644 quantum/keymap_extras/keymap_norwegian.c create mode 100644 quantum/keymap_extras/keymap_norwegian.h (limited to 'quantum') diff --git a/quantum/keymap_extras/keymap_neo2.h b/quantum/keymap_extras/keymap_neo2.h index b54cb74b9..80439af34 100644 --- a/quantum/keymap_extras/keymap_neo2.h +++ b/quantum/keymap_extras/keymap_neo2.h @@ -2,7 +2,7 @@ #define KEYMAP_NEO2 #include "keymap.h" -#include "keymap_extras/keymap_german.h" +#include "keymap_german.h" #define NEO_A KC_D #define NEO_B KC_N diff --git a/quantum/keymap_extras/keymap_norwegian.c b/quantum/keymap_extras/keymap_norwegian.c deleted file mode 100644 index 018bfeae5..000000000 --- a/quantum/keymap_extras/keymap_norwegian.c +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef KEYMAP_NORWEGIAN_H -#define KEYMAP_NORWEGIAN_H - -#include "keymap_nordic.h" - -// There are slight differrences in the keyboards in the nordic contries - -// Norwegian redifinitions from the nordic keyset -#undef NO_ACUT -#define NO_ACUT ALGR(NO_BSLS) // ´ -#undef NO_AE -#define NO_AE KC_QUOT // æ -#undef NO_BSLS -#define NO_BSLS KC_EQL // '\' -#undef NO_CIRC -#define NO_CIRC LSFT(C_RBRC) // ^ -#undef NO_GRV -#define NO_GRV LSFT(NO_BSLS) // -#undef NO_OSLH -#define NO_OSLH KC_SCLN // ø -#undef NO_PIPE -#define NO_PIPE KC_GRV // | - -// Additional norwegian keys not defined in the nordic keyset -#define NO_AA KC_LBRC // å -#define NO_ASTR LSFT(KC_BSLS) // * - -// Norwegian unique MAC characters -#define NO_ACUT_MAC KC_EQL // = -#define NO_APOS_MAC KC_NUBS // ' -#define NO_AT_MAC KC_BSLS // @ -#define NO_BSLS_MAC ALGR(LSFT(KC_7)) // '\' -#define NO_DLR_MAC LSFT(KC_4) // $ -#define NO_GRV_MAC ALGR(NO_BSLS) // ` -#define NO_GRTR_MAC LSFT(KC_GRV) // > -#define NO_LCBR_MAC ALGR(LSFT(KC_8)) // } -#define NO_LESS_MAC KC_GRV // > -#define NO_PIPE_MAC ALGR(KC_7) // | -#define NO_RCBR_MAC ALGR(LSFT(KC_9)) // } - -#endif diff --git a/quantum/keymap_extras/keymap_norwegian.h b/quantum/keymap_extras/keymap_norwegian.h new file mode 100644 index 000000000..018bfeae5 --- /dev/null +++ b/quantum/keymap_extras/keymap_norwegian.h @@ -0,0 +1,41 @@ +#ifndef KEYMAP_NORWEGIAN_H +#define KEYMAP_NORWEGIAN_H + +#include "keymap_nordic.h" + +// There are slight differrences in the keyboards in the nordic contries + +// Norwegian redifinitions from the nordic keyset +#undef NO_ACUT +#define NO_ACUT ALGR(NO_BSLS) // ´ +#undef NO_AE +#define NO_AE KC_QUOT // æ +#undef NO_BSLS +#define NO_BSLS KC_EQL // '\' +#undef NO_CIRC +#define NO_CIRC LSFT(C_RBRC) // ^ +#undef NO_GRV +#define NO_GRV LSFT(NO_BSLS) // +#undef NO_OSLH +#define NO_OSLH KC_SCLN // ø +#undef NO_PIPE +#define NO_PIPE KC_GRV // | + +// Additional norwegian keys not defined in the nordic keyset +#define NO_AA KC_LBRC // å +#define NO_ASTR LSFT(KC_BSLS) // * + +// Norwegian unique MAC characters +#define NO_ACUT_MAC KC_EQL // = +#define NO_APOS_MAC KC_NUBS // ' +#define NO_AT_MAC KC_BSLS // @ +#define NO_BSLS_MAC ALGR(LSFT(KC_7)) // '\' +#define NO_DLR_MAC LSFT(KC_4) // $ +#define NO_GRV_MAC ALGR(NO_BSLS) // ` +#define NO_GRTR_MAC LSFT(KC_GRV) // > +#define NO_LCBR_MAC ALGR(LSFT(KC_8)) // } +#define NO_LESS_MAC KC_GRV // > +#define NO_PIPE_MAC ALGR(KC_7) // | +#define NO_RCBR_MAC ALGR(LSFT(KC_9)) // } + +#endif -- cgit v1.2.3-24-g4f1b From 649b33d7783cf3021928534b7ae127e0a89e8807 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Tue, 21 Jun 2016 22:39:54 -0400 Subject: Renames keyboard folder to keyboards, adds couple of tmk's fixes (#432) * fixes from tmk's repo * rename keyboard to keyboards --- quantum/template/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'quantum') diff --git a/quantum/template/README.md b/quantum/template/README.md index baaeef473..d6b0ac936 100644 --- a/quantum/template/README.md +++ b/quantum/template/README.md @@ -7,7 +7,7 @@ For the full Quantum feature list, see [the parent README.md](/doc/README.md). ## Building -Download or clone the whole firmware and navigate to the keyboard/%KEYBOARD% folder. Once your dev env is setup, you'll be able to type `make` to generate your .hex - you can then use the Teensy Loader to program your .hex file. +Download or clone the whole firmware and navigate to the keyboards/%KEYBOARD% folder. Once your dev env is setup, you'll be able to type `make` to generate your .hex - you can then use the Teensy Loader to program your .hex file. Depending on which keymap you would like to use, you will have to compile slightly differently. -- cgit v1.2.3-24-g4f1b From 98f0807359cfa78d25442b91ff4c5bbfc5679661 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Tue, 21 Jun 2016 22:55:54 -0400 Subject: increase leader seq size to 5 --- quantum/quantum.c | 4 +++- quantum/quantum.h | 10 ++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) (limited to 'quantum') diff --git a/quantum/quantum.c b/quantum/quantum.c index 49ac20d61..006464e5a 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -54,7 +54,7 @@ int offset = 7; bool leading = false; uint16_t leader_time = 0; -uint16_t leader_sequence[3] = {0, 0, 0}; +uint16_t leader_sequence[5] = {0, 0, 0, 0, 0}; uint8_t leader_sequence_size = 0; // Chording stuff @@ -335,6 +335,8 @@ bool process_record_quantum(keyrecord_t *record) { leader_sequence[0] = 0; leader_sequence[1] = 0; leader_sequence[2] = 0; + leader_sequence[3] = 0; + leader_sequence[4] = 0; return false; } if (leading && timer_elapsed(leader_time) < LEADER_TIMEOUT) { diff --git a/quantum/quantum.h b/quantum/quantum.h index e15003805..1f78f3717 100644 --- a/quantum/quantum.h +++ b/quantum/quantum.h @@ -54,11 +54,13 @@ extern uint32_t default_layer_state; #ifndef LEADER_TIMEOUT #define LEADER_TIMEOUT 200 #endif - #define SEQ_ONE_KEY(key) if (leader_sequence[0] == (key) && leader_sequence[1] == 0 && leader_sequence[2] == 0) - #define SEQ_TWO_KEYS(key1, key2) if (leader_sequence[0] == (key1) && leader_sequence[1] == (key2) && leader_sequence[2] == 0) - #define SEQ_THREE_KEYS(key1, key2, key3) if (leader_sequence[0] == (key1) && leader_sequence[1] == (key2) && leader_sequence[2] == (key3)) + #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) + #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) + #define SEQ_THREE_KEYS(key1, key2, key3) if (leader_sequence[0] == (key1) && leader_sequence[1] == (key2) && leader_sequence[2] == (key3) && leader_sequence[3] == 0 && leader_sequence[4] == 0) + #define SEQ_FOUR_KEYS(key1, key2, key3, key4) if (leader_sequence[0] == (key1) && leader_sequence[1] == (key2) && leader_sequence[2] == (key3) && leader_sequence[3] == (key4) && leader_sequence[4] == 0) + #define SEQ_FIVE_KEYS(key1, key2, key3, key4, key5) if (leader_sequence[0] == (key1) && leader_sequence[1] == (key2) && leader_sequence[2] == (key3) && leader_sequence[3] == (key4) && leader_sequence[4] == (key5)) - #define LEADER_EXTERNS() extern bool leading; extern uint16_t leader_time; extern uint16_t leader_sequence[3]; extern uint8_t leader_sequence_size + #define LEADER_EXTERNS() extern bool leading; extern uint16_t leader_time; extern uint16_t leader_sequence[5]; extern uint8_t leader_sequence_size #define LEADER_DICTIONARY() if (leading && timer_elapsed(leader_time) > LEADER_TIMEOUT) #endif -- cgit v1.2.3-24-g4f1b From 13bb6b4b7fdd2b3e419d0f89c93fb980b00eeb9b Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Thu, 23 Jun 2016 22:18:20 -0400 Subject: Backlight abstraction and other changes (#439) * redoes matrix pins, abstracts backlight code for B5,6,7 * slimming down keyboard stuff, backlight breathing implemented * don't call backlight init when no pin * cleans up user/kb/quantum calls, keyboard files * fix pvc atomic * replaces CHANNEL with correct var in breathing * removes .hexs, updates readmes, updates template * cleans-up clueboards, readmes to lowercase * updates readme --- quantum/config_common.h | 80 +++---- quantum/keymap.h | 12 +- quantum/led.c | 54 ----- quantum/matrix.c | 48 ++-- quantum/quantum.c | 346 +++++++++++++++++++++++++++++ quantum/quantum.h | 30 +++ quantum/template/Makefile | 24 +- quantum/template/README.md | 24 -- quantum/template/config.h | 6 +- quantum/template/keymaps/default/Makefile | 21 ++ quantum/template/keymaps/default/config.h | 8 + quantum/template/keymaps/default/keymap.c | 20 +- quantum/template/keymaps/default/readme.md | 1 + quantum/template/readme.md | 28 +++ quantum/template/template.c | 84 +------ quantum/template/template.h | 13 +- quantum/tools/README.md | 6 - quantum/tools/readme.md | 6 + 18 files changed, 559 insertions(+), 252 deletions(-) delete mode 100644 quantum/led.c delete mode 100644 quantum/template/README.md create mode 100644 quantum/template/keymaps/default/Makefile create mode 100644 quantum/template/keymaps/default/config.h create mode 100644 quantum/template/keymaps/default/readme.md create mode 100644 quantum/template/readme.md delete mode 100644 quantum/tools/README.md create mode 100644 quantum/tools/readme.md (limited to 'quantum') diff --git a/quantum/config_common.h b/quantum/config_common.h index 02f11d979..09a4fe701 100644 --- a/quantum/config_common.h +++ b/quantum/config_common.h @@ -5,46 +5,46 @@ #define COL2ROW 0 #define ROW2COL 1 /* I/O pins */ -#define B0 { .input_addr = 3, .bit = 0 } -#define B1 { .input_addr = 3, .bit = 1 } -#define B2 { .input_addr = 3, .bit = 2 } -#define B3 { .input_addr = 3, .bit = 3 } -#define B4 { .input_addr = 3, .bit = 4 } -#define B5 { .input_addr = 3, .bit = 5 } -#define B6 { .input_addr = 3, .bit = 6 } -#define B7 { .input_addr = 3, .bit = 7 } -#define C0 { .input_addr = 6, .bit = 0 } -#define C1 { .input_addr = 6, .bit = 1 } -#define C2 { .input_addr = 6, .bit = 2 } -#define C3 { .input_addr = 6, .bit = 3 } -#define C4 { .input_addr = 6, .bit = 4 } -#define C5 { .input_addr = 6, .bit = 5 } -#define C6 { .input_addr = 6, .bit = 6 } -#define C7 { .input_addr = 6, .bit = 7 } -#define D0 { .input_addr = 9, .bit = 0 } -#define D1 { .input_addr = 9, .bit = 1 } -#define D2 { .input_addr = 9, .bit = 2 } -#define D3 { .input_addr = 9, .bit = 3 } -#define D4 { .input_addr = 9, .bit = 4 } -#define D5 { .input_addr = 9, .bit = 5 } -#define D6 { .input_addr = 9, .bit = 6 } -#define D7 { .input_addr = 9, .bit = 7 } -#define E0 { .input_addr = 0xC, .bit = 0 } -#define E1 { .input_addr = 0xC, .bit = 1 } -#define E2 { .input_addr = 0xC, .bit = 2 } -#define E3 { .input_addr = 0xC, .bit = 3 } -#define E4 { .input_addr = 0xC, .bit = 4 } -#define E5 { .input_addr = 0xC, .bit = 5 } -#define E6 { .input_addr = 0xC, .bit = 6 } -#define E7 { .input_addr = 0xC, .bit = 7 } -#define F0 { .input_addr = 0xF, .bit = 0 } -#define F1 { .input_addr = 0xF, .bit = 1 } -#define F2 { .input_addr = 0xF, .bit = 2 } -#define F3 { .input_addr = 0xF, .bit = 3 } -#define F4 { .input_addr = 0xF, .bit = 4 } -#define F5 { .input_addr = 0xF, .bit = 5 } -#define F6 { .input_addr = 0xF, .bit = 6 } -#define F7 { .input_addr = 0xF, .bit = 7 } +#define B0 0x30 +#define B1 0x31 +#define B2 0x32 +#define B3 0x33 +#define B4 0x34 +#define B5 0x35 +#define B6 0x36 +#define B7 0x37 +#define C0 0x60 +#define C1 0x61 +#define C2 0x62 +#define C3 0x63 +#define C4 0x64 +#define C5 0x65 +#define C6 0x66 +#define C7 0x67 +#define D0 0x90 +#define D1 0x91 +#define D2 0x92 +#define D3 0x93 +#define D4 0x94 +#define D5 0x95 +#define D6 0x96 +#define D7 0x97 +#define E0 0xC0 +#define E1 0xC1 +#define E2 0xC2 +#define E3 0xC3 +#define E4 0xC4 +#define E5 0xC5 +#define E6 0xC6 +#define E7 0xC7 +#define F0 0xF0 +#define F1 0xF1 +#define F2 0xF2 +#define F3 0xF3 +#define F4 0xF4 +#define F5 0xF5 +#define F6 0xF6 +#define F7 0xF7 /* USART configuration */ #ifdef BLUETOOTH_ENABLE diff --git a/quantum/keymap.h b/quantum/keymap.h index 6ac3d2ace..41fa394ab 100644 --- a/quantum/keymap.h +++ b/quantum/keymap.h @@ -125,8 +125,8 @@ enum quantum_keycodes { MUV_DE, // Midi mode on/off - MI_ON, - MI_OFF, + MIDI_ON, + MIDI_OFF, // Backlight functionality BL_0, @@ -154,7 +154,10 @@ enum quantum_keycodes { KC_LSPO, // Right shift, close paren - KC_RSPC + KC_RSPC, + + // always leave at the end + SAFE_RANGE }; // Ability to use mods in layouts @@ -266,6 +269,9 @@ enum quantum_keycodes { #define BL_ON BL_9 #define BL_OFF BL_0 +#define MI_ON MIDI_ON +#define MI_OFF MIDI_OFF + // GOTO layer - 16 layers max // when: // ON_PRESS = 1 diff --git a/quantum/led.c b/quantum/led.c deleted file mode 100644 index 2634ab2f6..000000000 --- a/quantum/led.c +++ /dev/null @@ -1,54 +0,0 @@ -/* -Copyright 2012 Jun Wako - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -#include -#include "stdint.h" -#include "led.h" - -__attribute__ ((weak)) -void led_set_kb(uint8_t usb_led) { - -} - -__attribute__ ((weak)) -void led_init_ports(void) -{ - -} - -__attribute__ ((weak)) -void led_set(uint8_t usb_led) -{ - - // Example LED Code - // - // // Using PE6 Caps Lock LED - // if (usb_led & (1<. # define DEBOUNCING_DELAY 5 #endif -static const io_pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; -static const io_pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS; +static const uint8_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; +static const uint8_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS; /* matrix state */ #if DIODE_DIRECTION == COL2ROW static matrix_row_t matrix[MATRIX_ROWS]; @@ -52,10 +52,30 @@ static matrix_col_t read_rows(void); __attribute__ ((weak)) void matrix_init_quantum(void) { + matrix_init_kb(); } __attribute__ ((weak)) void matrix_scan_quantum(void) { + matrix_scan_kb(); +} + +__attribute__ ((weak)) +void matrix_init_kb(void) { + matrix_init_user(); +} + +__attribute__ ((weak)) +void matrix_scan_kb(void) { + matrix_scan_user(); +} + +__attribute__ ((weak)) +void matrix_init_user(void) { +} + +__attribute__ ((weak)) +void matrix_scan_user(void) { } uint8_t matrix_rows(void) { @@ -70,22 +90,22 @@ void matrix_power_up(void) { #if DIODE_DIRECTION == COL2ROW for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { /* DDRxn */ - _SFR_IO8(row_pins[r].input_addr + 1) |= _BV(row_pins[r].bit); + _SFR_IO8((row_pins[r] >> 4) + 1) |= _BV(row_pins[r] & 0xF); toggle_row(r); } for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { /* PORTxn */ - _SFR_IO8(col_pins[c].input_addr + 2) |= _BV(col_pins[c].bit); + _SFR_IO8((col_pins[c] >> 4) + 2) |= _BV(col_pins[c] & 0xF); } #else for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { /* DDRxn */ - _SFR_IO8(col_pins[c].input_addr + 1) |= _BV(col_pins[c].bit); + _SFR_IO8((col_pins[c] >> 4) + 1) |= _BV(col_pins[c] & 0xF); toggle_col(c); } for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { /* PORTxn */ - _SFR_IO8(row_pins[r].input_addr + 2) |= _BV(row_pins[r].bit); + _SFR_IO8((row_pins[r] >> 4) + 2) |= _BV(row_pins[r] & 0xF); } #endif } @@ -100,22 +120,22 @@ void matrix_init(void) { #if DIODE_DIRECTION == COL2ROW for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { /* DDRxn */ - _SFR_IO8(row_pins[r].input_addr + 1) |= _BV(row_pins[r].bit); + _SFR_IO8((row_pins[r] >> 4) + 1) |= _BV(row_pins[r] & 0xF); toggle_row(r); } for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { /* PORTxn */ - _SFR_IO8(col_pins[c].input_addr + 2) |= _BV(col_pins[c].bit); + _SFR_IO8((col_pins[c] >> 4) + 2) |= _BV(col_pins[c] & 0xF); } #else for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { /* DDRxn */ - _SFR_IO8(col_pins[c].input_addr + 1) |= _BV(col_pins[c].bit); + _SFR_IO8((col_pins[c] >> 4) + 1) |= _BV(col_pins[c] & 0xF); toggle_col(c); } for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { /* PORTxn */ - _SFR_IO8(row_pins[r].input_addr + 2) |= _BV(row_pins[r].bit); + _SFR_IO8((row_pins[r] >> 4) + 2) |= _BV(row_pins[r] & 0xF); } #endif matrix_init_quantum(); @@ -151,14 +171,14 @@ uint8_t matrix_scan(void) { static void toggle_row(uint8_t row) { /* PINxn */ - _SFR_IO8(row_pins[row].input_addr) = _BV(row_pins[row].bit); + _SFR_IO8((row_pins[row] >> 4)) = _BV(row_pins[row] & 0xF); } static matrix_row_t read_cols(void) { matrix_row_t state = 0; for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { /* PINxn */ - if (!(_SFR_IO8(col_pins[c].input_addr) & _BV(col_pins[c].bit))) { + if (!(_SFR_IO8((col_pins[c] >> 4)) & _BV(col_pins[c] & 0xF))) { state |= (matrix_row_t)1 << c; } } @@ -199,14 +219,14 @@ uint8_t matrix_scan(void) { static void toggle_col(uint8_t col) { /* PINxn */ - _SFR_IO8(col_pins[col].input_addr) = _BV(col_pins[col].bit); + _SFR_IO8((col_pins[col] >> 4)) = _BV(col_pins[col] & 0xF); } static matrix_col_t read_rows(void) { matrix_col_t state = 0; for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { /* PINxn */ - if (!(_SFR_IO8(row_pins[r].input_addr) & _BV(row_pins[r].bit))) { + if (!(_SFR_IO8((row_pins[r] >> 4)) & _BV(row_pins[r] & 0xF))) { state |= (matrix_col_t)1 << r; } } diff --git a/quantum/quantum.c b/quantum/quantum.c index 006464e5a..3f2edfc92 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -655,6 +655,9 @@ void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3) { } void matrix_init_quantum() { + #ifdef BACKLIGHT_ENABLE + backlight_init_ports(); + #endif matrix_init_kb(); } @@ -673,6 +676,7 @@ void matrix_scan_quantum() { matrix_scan_kb(); } + #ifdef AUDIO_ENABLE bool is_music_on(void) { return (music_activated != 0); @@ -698,6 +702,348 @@ void matrix_scan_quantum() { #endif + +#if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_PIN) + +static const uint8_t backlight_pin = BACKLIGHT_PIN; + +#if BACKLIGHT_PIN == B7 +# define COM1x1 COM1C1 +# define OCR1x OCR1C +#elif BACKLIGHT_PIN == B6 +# define COM1x1 COM1B1 +# define OCR1x OCR1B +#elif BACKLIGHT_PIN == B5 +# define COM1x1 COM1A1 +# define OCR1x OCR1A +#else +# error "Backlight pin not supported - use B5, B6, or B7" +#endif + +__attribute__ ((weak)) +void backlight_init_ports(void) +{ + + // Setup backlight pin as output and output low. + // DDRx |= n + _SFR_IO8((backlight_pin >> 4) + 1) |= _BV(backlight_pin & 0xF); + // PORTx &= ~n + _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF); + + // Use full 16-bit resolution. + ICR1 = 0xFFFF; + + // I could write a wall of text here to explain... but TL;DW + // Go read the ATmega32u4 datasheet. + // And this: http://blog.saikoled.com/post/43165849837/secret-konami-cheat-code-to-high-resolution-pwm-on + + // Pin PB7 = OCR1C (Timer 1, Channel C) + // Compare Output Mode = Clear on compare match, Channel C = COM1C1=1 COM1C0=0 + // (i.e. start high, go low when counter matches.) + // WGM Mode 14 (Fast PWM) = WGM13=1 WGM12=1 WGM11=1 WGM10=0 + // Clock Select = clk/1 (no prescaling) = CS12=0 CS11=0 CS10=1 + + TCCR1A = _BV(COM1x1) | _BV(WGM11); // = 0b00001010; + TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // = 0b00011001; + + backlight_init(); + #ifdef BACKLIGHT_BREATHING + breathing_defaults(); + #endif +} + +__attribute__ ((weak)) +void backlight_set(uint8_t level) +{ + // Prevent backlight blink on lowest level + // PORTx &= ~n + _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF); + + if ( level == 0 ) { + // Turn off PWM control on backlight pin, revert to output low. + TCCR1A &= ~(_BV(COM1x1)); + OCR1x = 0x0; + } else if ( level == BACKLIGHT_LEVELS ) { + // Turn on PWM control of backlight pin + TCCR1A |= _BV(COM1x1); + // Set the brightness + OCR1x = 0xFFFF; + } else { + // Turn on PWM control of backlight pin + TCCR1A |= _BV(COM1x1); + // Set the brightness + OCR1x = 0xFFFF >> ((BACKLIGHT_LEVELS - level) * ((BACKLIGHT_LEVELS + 1) / 2)); + } + + #ifdef BACKLIGHT_BREATHING + breathing_intensity_default(); + #endif +} + + +#ifdef BACKLIGHT_BREATHING + +#define BREATHING_NO_HALT 0 +#define BREATHING_HALT_OFF 1 +#define BREATHING_HALT_ON 2 + +static uint8_t breath_intensity; +static uint8_t breath_speed; +static uint16_t breathing_index; +static uint8_t breathing_halt; + +void breathing_enable(void) +{ + if (get_backlight_level() == 0) + { + breathing_index = 0; + } + else + { + // Set breathing_index to be at the midpoint (brightest point) + breathing_index = 0x20 << breath_speed; + } + + breathing_halt = BREATHING_NO_HALT; + + // Enable breathing interrupt + TIMSK1 |= _BV(OCIE1A); +} + +void breathing_pulse(void) +{ + if (get_backlight_level() == 0) + { + breathing_index = 0; + } + else + { + // Set breathing_index to be at the midpoint + 1 (brightest point) + breathing_index = 0x21 << breath_speed; + } + + breathing_halt = BREATHING_HALT_ON; + + // Enable breathing interrupt + TIMSK1 |= _BV(OCIE1A); +} + +void breathing_disable(void) +{ + // Disable breathing interrupt + TIMSK1 &= ~_BV(OCIE1A); + backlight_set(get_backlight_level()); +} + +void breathing_self_disable(void) +{ + if (get_backlight_level() == 0) + { + breathing_halt = BREATHING_HALT_OFF; + } + else + { + breathing_halt = BREATHING_HALT_ON; + } + + //backlight_set(get_backlight_level()); +} + +void breathing_toggle(void) +{ + if (!is_breathing()) + { + if (get_backlight_level() == 0) + { + breathing_index = 0; + } + else + { + // Set breathing_index to be at the midpoint + 1 (brightest point) + breathing_index = 0x21 << breath_speed; + } + + breathing_halt = BREATHING_NO_HALT; + } + + // Toggle breathing interrupt + TIMSK1 ^= _BV(OCIE1A); + + // Restore backlight level + if (!is_breathing()) + { + backlight_set(get_backlight_level()); + } +} + +bool is_breathing(void) +{ + return (TIMSK1 && _BV(OCIE1A)); +} + +void breathing_intensity_default(void) +{ + //breath_intensity = (uint8_t)((uint16_t)100 * (uint16_t)get_backlight_level() / (uint16_t)BACKLIGHT_LEVELS); + breath_intensity = ((BACKLIGHT_LEVELS - get_backlight_level()) * ((BACKLIGHT_LEVELS + 1) / 2)); +} + +void breathing_intensity_set(uint8_t value) +{ + breath_intensity = value; +} + +void breathing_speed_default(void) +{ + breath_speed = 4; +} + +void breathing_speed_set(uint8_t value) +{ + bool is_breathing_now = is_breathing(); + uint8_t old_breath_speed = breath_speed; + + if (is_breathing_now) + { + // Disable breathing interrupt + TIMSK1 &= ~_BV(OCIE1A); + } + + breath_speed = value; + + if (is_breathing_now) + { + // Adjust index to account for new speed + breathing_index = (( (uint8_t)( (breathing_index) >> old_breath_speed ) ) & 0x3F) << breath_speed; + + // Enable breathing interrupt + TIMSK1 |= _BV(OCIE1A); + } + +} + +void breathing_speed_inc(uint8_t value) +{ + if ((uint16_t)(breath_speed - value) > 10 ) + { + breathing_speed_set(0); + } + else + { + breathing_speed_set(breath_speed - value); + } +} + +void breathing_speed_dec(uint8_t value) +{ + if ((uint16_t)(breath_speed + value) > 10 ) + { + breathing_speed_set(10); + } + else + { + breathing_speed_set(breath_speed + value); + } +} + +void breathing_defaults(void) +{ + breathing_intensity_default(); + breathing_speed_default(); + breathing_halt = BREATHING_NO_HALT; +} + +/* Breathing Sleep LED brighness(PWM On period) table + * (64[steps] * 4[duration]) / 64[PWM periods/s] = 4 second breath cycle + * + * http://www.wolframalpha.com/input/?i=%28sin%28+x%2F64*pi%29**8+*+255%2C+x%3D0+to+63 + * (0..63).each {|x| p ((sin(x/64.0*PI)**8)*255).to_i } + */ +static const uint8_t breathing_table[64] PROGMEM = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 6, 10, + 15, 23, 32, 44, 58, 74, 93, 113, 135, 157, 179, 199, 218, 233, 245, 252, +255, 252, 245, 233, 218, 199, 179, 157, 135, 113, 93, 74, 58, 44, 32, 23, + 15, 10, 6, 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +ISR(TIMER1_COMPA_vect) +{ + // OCR1x = (pgm_read_byte(&breathing_table[ ( (uint8_t)( (breathing_index++) >> breath_speed ) ) & 0x3F ] )) * breath_intensity; + + + uint8_t local_index = ( (uint8_t)( (breathing_index++) >> breath_speed ) ) & 0x3F; + + if (((breathing_halt == BREATHING_HALT_ON) && (local_index == 0x20)) || ((breathing_halt == BREATHING_HALT_OFF) && (local_index == 0x3F))) + { + // Disable breathing interrupt + TIMSK1 &= ~_BV(OCIE1A); + } + + OCR1x = (uint16_t)(((uint16_t)pgm_read_byte(&breathing_table[local_index]) * 257)) >> breath_intensity; + +} + + + +#endif // breathing + +#else // backlight + +__attribute__ ((weak)) +void backlight_init_ports(void) +{ + +} + +__attribute__ ((weak)) +void backlight_set(uint8_t level) +{ + +} + +#endif // backlight + + + +__attribute__ ((weak)) +void led_set_user(uint8_t usb_led) { + +} + +__attribute__ ((weak)) +void led_set_kb(uint8_t usb_led) { + led_set_user(usb_led); +} + +__attribute__ ((weak)) +void led_init_ports(void) +{ + +} + +__attribute__ ((weak)) +void led_set(uint8_t usb_led) +{ + + // Example LED Code + // + // // Using PE6 Caps Lock LED + // if (usb_led & (1< #include "bootloader.h" #include "timer.h" +#include "config_common.h" +#include +#include "led.h" +#include "action_util.h" extern uint32_t default_layer_state; @@ -74,6 +78,8 @@ void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3); void matrix_init_kb(void); void matrix_scan_kb(void); +void matrix_init_user(void); +void matrix_scan_user(void); bool process_action_kb(keyrecord_t *record); bool process_record_kb(uint16_t keycode, keyrecord_t *record); bool process_record_user(uint16_t keycode, keyrecord_t *record); @@ -89,4 +95,28 @@ void audio_on_user(void); void music_on_user(void); void music_scale_user(void); +#ifdef BACKLIGHT_ENABLE +void backlight_init_ports(void); + +#ifdef BACKLIGHT_BREATHING +void breathing_enable(void); +void breathing_pulse(void); +void breathing_disable(void); +void breathing_self_disable(void); +void breathing_toggle(void); +bool is_breathing(void); + +void breathing_defaults(void); +void breathing_intensity_default(void); +void breathing_speed_default(void); +void breathing_speed_set(uint8_t value); +void breathing_speed_inc(uint8_t value); +void breathing_speed_dec(uint8_t value); +#endif + +#endif + +void led_set_user(uint8_t usb_led); +void led_set_kb(uint8_t usb_led); + #endif diff --git a/quantum/template/Makefile b/quantum/template/Makefile index 87e4c2d2b..3f6d133c9 100644 --- a/quantum/template/Makefile +++ b/quantum/template/Makefile @@ -53,20 +53,20 @@ OPT_DEFS += -DBOOTLOADER_SIZE=512 # Build Options # change yes to no to disable # -BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000) -MOUSEKEY_ENABLE = yes # Mouse keys(+4700) -EXTRAKEY_ENABLE = yes # Audio control and System control(+450) -CONSOLE_ENABLE = yes # Console for debug(+400) -COMMAND_ENABLE = yes # Commands for debug and configuration +BOOTMAGIC_ENABLE ?= no # Virtual DIP switch configuration(+1000) +MOUSEKEY_ENABLE ?= yes # Mouse keys(+4700) +EXTRAKEY_ENABLE ?= yes # Audio control and System control(+450) +CONSOLE_ENABLE ?= yes # Console for debug(+400) +COMMAND_ENABLE ?= yes # Commands for debug and configuration # Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE -SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend +SLEEP_LED_ENABLE ?= no # Breathing sleep LED during USB suspend # if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work -NKRO_ENABLE = no # USB Nkey Rollover -BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality on B7 by default -MIDI_ENABLE = no # MIDI controls -UNICODE_ENABLE = no # Unicode -BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID -AUDIO_ENABLE = no # Audio output on port C6 +NKRO_ENABLE ?= no # USB Nkey Rollover +BACKLIGHT_ENABLE ?= no # Enable keyboard backlight functionality on B7 by default +MIDI_ENABLE ?= no # MIDI controls +UNICODE_ENABLE ?= no # Unicode +BLUETOOTH_ENABLE ?= no # Enable Bluetooth with the Adafruit EZ-Key HID +AUDIO_ENABLE ?= no # Audio output on port C6 ifndef QUANTUM_DIR include ../../Makefile diff --git a/quantum/template/README.md b/quantum/template/README.md deleted file mode 100644 index d6b0ac936..000000000 --- a/quantum/template/README.md +++ /dev/null @@ -1,24 +0,0 @@ -%KEYBOARD% keyboard firmware -====================== - -## Quantum MK Firmware - -For the full Quantum feature list, see [the parent README.md](/doc/README.md). - -## Building - -Download or clone the whole firmware and navigate to the keyboards/%KEYBOARD% folder. Once your dev env is setup, you'll be able to type `make` to generate your .hex - you can then use the Teensy Loader to program your .hex file. - -Depending on which keymap you would like to use, you will have to compile slightly differently. - -### Default -To build with the default keymap, simply run `make`. - -### Other Keymaps -Several version of keymap are available in advance but you are recommended to define your favorite layout yourself. To define your own keymap create file named `.c` in the keymaps folder, and see keymap document (you can find in top README.md) and existent keymap files. - -To build the firmware binary hex file with a keymap just do `make` with `KEYMAP` option like: -``` -$ make KEYMAP=[default|jack|] -``` -Keymaps follow the format **__\.c__** and are stored in the `keymaps` folder. \ No newline at end of file diff --git a/quantum/template/config.h b/quantum/template/config.h index cad3e3260..b02f0c7eb 100644 --- a/quantum/template/config.h +++ b/quantum/template/config.h @@ -48,6 +48,11 @@ along with this program. If not, see . /* COL2ROW or ROW2COL */ #define DIODE_DIRECTION COL2ROW + +// #define BACKLIGHT_PIN B7 +// #define BACKLIGHT_BREATHING +// #define BACKLIGHT_LEVELS 3 + /* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */ #define DEBOUNCING_DELAY 5 @@ -56,7 +61,6 @@ along with this program. If not, see . //#define MATRIX_HAS_GHOST /* number of backlight levels */ -#define BACKLIGHT_LEVELS 3 /* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */ #define LOCKING_SUPPORT_ENABLE diff --git a/quantum/template/keymaps/default/Makefile b/quantum/template/keymaps/default/Makefile new file mode 100644 index 000000000..f4671a9d1 --- /dev/null +++ b/quantum/template/keymaps/default/Makefile @@ -0,0 +1,21 @@ +# Build Options +# change to "no" to disable the options, or define them in the Makefile in +# the appropriate keymap folder that will get included automatically +# +BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000) +MOUSEKEY_ENABLE = yes # Mouse keys(+4700) +EXTRAKEY_ENABLE = yes # Audio control and System control(+450) +CONSOLE_ENABLE = no # Console for debug(+400) +COMMAND_ENABLE = yes # Commands for debug and configuration +NKRO_ENABLE = yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work +BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality +MIDI_ENABLE = no # MIDI controls +AUDIO_ENABLE = no # Audio output on port C6 +UNICODE_ENABLE = no # Unicode +BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID +RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time. +SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend + +ifndef QUANTUM_DIR + include ../../../../Makefile +endif \ No newline at end of file diff --git a/quantum/template/keymaps/default/config.h b/quantum/template/keymaps/default/config.h new file mode 100644 index 000000000..df06a2620 --- /dev/null +++ b/quantum/template/keymaps/default/config.h @@ -0,0 +1,8 @@ +#ifndef CONFIG_USER_H +#define CONFIG_USER_H + +#include "../../config.h" + +// place overrides here + +#endif \ No newline at end of file diff --git a/quantum/template/keymaps/default/keymap.c b/quantum/template/keymaps/default/keymap.c index 4121fd860..e28a4723e 100644 --- a/quantum/template/keymaps/default/keymap.c +++ b/quantum/template/keymaps/default/keymap.c @@ -1,6 +1,3 @@ -// This is the canonical layout file for the Quantum project. If you want to add another keyboard, -// this is the style you want to emulate. - #include "%KEYBOARD%.h" const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { @@ -28,3 +25,20 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) } return MACRO_NONE; }; + + +void matrix_init_user(void) { + +} + +void matrix_scan_user(void) { + +} + +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + return true; +} + +void led_set_user(uint8_t usb_led) { + +} \ No newline at end of file diff --git a/quantum/template/keymaps/default/readme.md b/quantum/template/keymaps/default/readme.md new file mode 100644 index 000000000..21aa663d5 --- /dev/null +++ b/quantum/template/keymaps/default/readme.md @@ -0,0 +1 @@ +# The default keymap for %KEYBOARD% \ No newline at end of file diff --git a/quantum/template/readme.md b/quantum/template/readme.md new file mode 100644 index 000000000..b2fb4dd98 --- /dev/null +++ b/quantum/template/readme.md @@ -0,0 +1,28 @@ +%KEYBOARD% keyboard firmware +====================== + +## Quantum MK Firmware + +For the full Quantum feature list, see [the parent readme.md](/doc/readme.md). + +## Building + +Download or clone the whole firmware and navigate to the keyboards/%KEYBOARD% folder. Once your dev env is setup, you'll be able to type `make` to generate your .hex - you can then use the Teensy Loader to program your .hex file. + +Depending on which keymap you would like to use, you will have to compile slightly differently. + +### Default + +To build with the default keymap, simply run `make`. + +### Other Keymaps + +Several version of keymap are available in advance but you are recommended to define your favorite layout yourself. To define your own keymap create a folder with the name of your keymap in the keymaps folder, and see keymap documentation (you can find in top readme.md) and existant keymap files. + +To build the firmware binary hex file with a keymap just do `make` with `keymap` option like: + +``` +$ make keymap=[default|jack|] +``` + +Keymaps follow the format **__keymap.c__** and are stored in folders in the `keymaps` folder, eg `keymaps/my_keymap/` \ No newline at end of file diff --git a/quantum/template/template.c b/quantum/template/template.c index 649072eb2..dcc4b0a22 100644 --- a/quantum/template/template.c +++ b/quantum/template/template.c @@ -1,26 +1,5 @@ #include "%KEYBOARD%.h" -__attribute__ ((weak)) -void matrix_init_user(void) { - // leave this function blank - it can be defined in a keymap file -}; - -__attribute__ ((weak)) -void matrix_scan_user(void) { - // leave this function blank - it can be defined in a keymap file -} - -__attribute__ ((weak)) -bool process_action_user(keyrecord_t *record) { - // leave this function blank - it can be defined in a keymap file - return true; -} - -__attribute__ ((weak)) -void led_set_user(uint8_t usb_led) { - // leave this function blank - it can be defined in a keymap file -} - void matrix_init_kb(void) { // put your keyboard start-up code here // runs once when the firmware starts up @@ -35,7 +14,7 @@ void matrix_scan_kb(void) { matrix_scan_user(); } -bool process_action_kb(keyrecord_t *record) { +bool process_record_kb(uint16_t keycode, keyrecord_t *record) { // put your per-action keyboard code here // runs for every action, just before processing by the firmware @@ -47,64 +26,3 @@ void led_set_kb(uint8_t usb_led) { led_set_user(usb_led); } - -#ifdef BACKLIGHT_ENABLE -#define CHANNEL OCR1C - -void backlight_init_ports() -{ - - // Setup PB7 as output and output low. - DDRB |= (1<<7); - PORTB &= ~(1<<7); - - // Use full 16-bit resolution. - ICR1 = 0xFFFF; - - // I could write a wall of text here to explain... but TL;DW - // Go read the ATmega32u4 datasheet. - // And this: http://blog.saikoled.com/post/43165849837/secret-konami-cheat-code-to-high-resolution-pwm-on - - // Pin PB7 = OCR1C (Timer 1, Channel C) - // Compare Output Mode = Clear on compare match, Channel C = COM1C1=1 COM1C0=0 - // (i.e. start high, go low when counter matches.) - // WGM Mode 14 (Fast PWM) = WGM13=1 WGM12=1 WGM11=1 WGM10=0 - // Clock Select = clk/1 (no prescaling) = CS12=0 CS11=0 CS10=1 - - TCCR1A = _BV(COM1C1) | _BV(WGM11); // = 0b00001010; - TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // = 0b00011001; - - backlight_init(); -} - -void backlight_set(uint8_t level) -{ - if ( level == 0 ) - { - // Turn off PWM control on PB7, revert to output low. - TCCR1A &= ~(_BV(COM1C1)); - CHANNEL = 0x0; - // Prevent backlight blink on lowest level - PORTB &= ~(_BV(PORTB7)); - } - else if ( level == BACKLIGHT_LEVELS ) - { - // Prevent backlight blink on lowest level - PORTB &= ~(_BV(PORTB7)); - // Turn on PWM control of PB7 - TCCR1A |= _BV(COM1C1); - // Set the brightness - CHANNEL = 0xFFFF; - } - else - { - // Prevent backlight blink on lowest level - PORTB &= ~(_BV(PORTB7)); - // Turn on PWM control of PB7 - TCCR1A |= _BV(COM1C1); - // Set the brightness - CHANNEL = 0xFFFF >> ((BACKLIGHT_LEVELS - level) * ((BACKLIGHT_LEVELS + 1) / 2)); - } -} - -#endif \ No newline at end of file diff --git a/quantum/template/template.h b/quantum/template/template.h index b8e7a0456..cd78a54e3 100644 --- a/quantum/template/template.h +++ b/quantum/template/template.h @@ -1,13 +1,7 @@ #ifndef %KEYBOARD_UPPERCASE%_H #define %KEYBOARD_UPPERCASE%_H -#include "matrix.h" -#include "keymap.h" -#ifdef BACKLIGHT_ENABLE - #include "backlight.h" -#endif -#include -#include +#include "quantum.h" // This a shortcut to help you visually see your layout. // The following is an example using the Planck MIT layout @@ -22,9 +16,4 @@ { k10, KC_NO, k11 }, \ } -void matrix_init_user(void); -void matrix_scan_user(void); -bool process_action_user(keyrecord_t *record); -void led_set_user(uint8_t usb_led); - #endif diff --git a/quantum/tools/README.md b/quantum/tools/README.md deleted file mode 100644 index 5f355256d..000000000 --- a/quantum/tools/README.md +++ /dev/null @@ -1,6 +0,0 @@ -`eeprom_reset.hex` is to reset the eeprom on the Atmega32u4, like this: - - dfu-programmer atmega32u4 erase - dfu-programmer atmega32u4 flash --eeprom eeprom_reset.hex - - You'll need to reflash afterwards, because DFU requires the flash to be erased before messing with the eeprom. diff --git a/quantum/tools/readme.md b/quantum/tools/readme.md new file mode 100644 index 000000000..5f355256d --- /dev/null +++ b/quantum/tools/readme.md @@ -0,0 +1,6 @@ +`eeprom_reset.hex` is to reset the eeprom on the Atmega32u4, like this: + + dfu-programmer atmega32u4 erase + dfu-programmer atmega32u4 flash --eeprom eeprom_reset.hex + + You'll need to reflash afterwards, because DFU requires the flash to be erased before messing with the eeprom. -- cgit v1.2.3-24-g4f1b From b68b722325e1f0f68387e161365fa8e31c79b7b2 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Thu, 23 Jun 2016 23:14:21 -0400 Subject: updates ez's matrix to spec --- quantum/quantum.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'quantum') diff --git a/quantum/quantum.c b/quantum/quantum.c index 3f2edfc92..9c0f9691f 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -1,11 +1,5 @@ #include "quantum.h" -__attribute__ ((weak)) -void matrix_init_kb(void) {} - -__attribute__ ((weak)) -void matrix_scan_kb(void) {} - __attribute__ ((weak)) bool process_action_kb(keyrecord_t *record) { return true; -- cgit v1.2.3-24-g4f1b From 00dcac7270aabeb2f473315e94d298b4766df88c Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Sun, 26 Jun 2016 14:08:11 -0400 Subject: updates planck macros to keycodes, prototype fn_actions --- quantum/keymap.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'quantum') diff --git a/quantum/keymap.c b/quantum/keymap.c index 203a82d95..74fd518c9 100644 --- a/quantum/keymap.c +++ b/quantum/keymap.c @@ -141,6 +141,10 @@ action_t action_for_key(uint8_t layer, keypos_t key) return action; } +__attribute__ ((weak)) +const uint16_t PROGMEM fn_actions[] = { + +}; /* Macro */ __attribute__ ((weak)) -- cgit v1.2.3-24-g4f1b From 215c2119af5281072d5a6efb0308408793cadd08 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Wed, 29 Jun 2016 16:21:41 -0400 Subject: Implements subprojects and updates projects for this (#459) * non-working commit * working * subprojects implemented for planck * pass a subproject variable through to c * consolidates clueboard revisions * thanks for letting me know about conflicts.. * turn off audio for yang's * corrects starting paths for subprojects * messing around with travis * semicolon * travis script * travis script * script for travis * correct directory (probably), amend files to commit * remove origin before adding * git pull, correct syntax * git checkout * git pull origin branch * where are we? * where are we? * merging * force things to happen * adds commit message, adds add * rebase, no commit message * rebase branch * idk! * try just pull * fetch - merge * specify repo branch * checkout * goddammit * merge? idk * pls * after all * don't split up keyboards * syntax * adds quick for all-keyboards * trying out new script * script update * lowercase * all keyboards * stop replacing compiled.hex automatically * adds if statement * skip automated build branches * forces push to automated build branch * throw an add in there * upstream? * adds AUTOGEN * ignore all .hex files again * testing out new repo * global ident * generate script, keyboard_keymap.hex * skip generation for now, print pandoc info, submodule update * try trusty * and sudo * try generate * updates subprojects to keyboards * no idea * updates to keyboards * cleans up clueboard stuff * setup to use local readme * updates cluepad, planck experimental * remove extra led.c [ci skip] * disable power up for now * config files updates * makefile updates * .h file updates, config tuning * disable audio for yang --- quantum/audio/audio.h | 6 +++--- quantum/matrix.c | 46 +++++++++++++++++++++++----------------------- 2 files changed, 26 insertions(+), 26 deletions(-) (limited to 'quantum') diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index 00d45f7ac..47f326ea0 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -1,3 +1,6 @@ +#ifndef AUDIO_H +#define AUDIO_H + #include #include #include @@ -7,9 +10,6 @@ #include "voices.h" #include "quantum.h" -#ifndef AUDIO_H -#define AUDIO_H - // Largely untested PWM audio mode (doesn't sound as good) // #define PWM_AUDIO diff --git a/quantum/matrix.c b/quantum/matrix.c index 6e9f92727..f5744658c 100644 --- a/quantum/matrix.c +++ b/quantum/matrix.c @@ -86,29 +86,29 @@ uint8_t matrix_cols(void) { return MATRIX_COLS; } -void matrix_power_up(void) { -#if DIODE_DIRECTION == COL2ROW - for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { - /* DDRxn */ - _SFR_IO8((row_pins[r] >> 4) + 1) |= _BV(row_pins[r] & 0xF); - toggle_row(r); - } - for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { - /* PORTxn */ - _SFR_IO8((col_pins[c] >> 4) + 2) |= _BV(col_pins[c] & 0xF); - } -#else - for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { - /* DDRxn */ - _SFR_IO8((col_pins[c] >> 4) + 1) |= _BV(col_pins[c] & 0xF); - toggle_col(c); - } - for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { - /* PORTxn */ - _SFR_IO8((row_pins[r] >> 4) + 2) |= _BV(row_pins[r] & 0xF); - } -#endif -} +// void matrix_power_up(void) { +// #if DIODE_DIRECTION == COL2ROW +// for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { +// /* DDRxn */ +// _SFR_IO8((row_pins[r] >> 4) + 1) |= _BV(row_pins[r] & 0xF); +// toggle_row(r); +// } +// for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { +// /* PORTxn */ +// _SFR_IO8((col_pins[c] >> 4) + 2) |= _BV(col_pins[c] & 0xF); +// } +// #else +// for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { +// /* DDRxn */ +// _SFR_IO8((col_pins[c] >> 4) + 1) |= _BV(col_pins[c] & 0xF); +// toggle_col(c); +// } +// for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { +// /* PORTxn */ +// _SFR_IO8((row_pins[r] >> 4) + 2) |= _BV(row_pins[r] & 0xF); +// } +// #endif +// } void matrix_init(void) { /* frees PORTF by setting the JTD bit twice within four cycles */ -- cgit v1.2.3-24-g4f1b From 65faab3b89245f81c50b029ca178aed175d5f330 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Wed, 29 Jun 2016 17:49:41 -0400 Subject: Moves features to their own files (process_*), adds tap dance feature (#460) * non-working commit * working * subprojects implemented for planck * pass a subproject variable through to c * consolidates clueboard revisions * thanks for letting me know about conflicts.. * turn off audio for yang's * corrects starting paths for subprojects * messing around with travis * semicolon * travis script * travis script * script for travis * correct directory (probably), amend files to commit * remove origin before adding * git pull, correct syntax * git checkout * git pull origin branch * where are we? * where are we? * merging * force things to happen * adds commit message, adds add * rebase, no commit message * rebase branch * idk! * try just pull * fetch - merge * specify repo branch * checkout * goddammit * merge? idk * pls * after all * don't split up keyboards * syntax * adds quick for all-keyboards * trying out new script * script update * lowercase * all keyboards * stop replacing compiled.hex automatically * adds if statement * skip automated build branches * forces push to automated build branch * throw an add in there * upstream? * adds AUTOGEN * ignore all .hex files again * testing out new repo * global ident * generate script, keyboard_keymap.hex * skip generation for now, print pandoc info, submodule update * try trusty * and sudo * try generate * updates subprojects to keyboards * no idea * updates to keyboards * cleans up clueboard stuff * setup to use local readme * updates cluepad, planck experimental * remove extra led.c [ci skip] * audio and midi moved over to separate files * chording, leader, unicode separated * consolidate each [skip ci] * correct include * quantum: Add a tap dance feature (#451) * quantum: Add a tap dance feature With this feature one can specify keys that behave differently, based on the amount of times they have been tapped, and when interrupted, they get handled before the interrupter. To make it clear how this is different from `ACTION_FUNCTION_TAP`, lets explore a certain setup! We want one key to send `Space` on single tap, but `Enter` on double-tap. With `ACTION_FUNCTION_TAP`, it is quite a rain-dance to set this up, and has the problem that when the sequence is interrupted, the interrupting key will be send first. Thus, `SPC a` will result in `a SPC` being sent, if they are typed within `TAPPING_TERM`. With the tap dance feature, that'll come out as `SPC a`, correctly. The implementation hooks into two parts of the system, to achieve this: into `process_record_quantum()`, and the matrix scan. We need the latter to be able to time out a tap sequence even when a key is not being pressed, so `SPC` alone will time out and register after `TAPPING_TERM` time. But lets start with how to use it, first! First, you will need `TAP_DANCE_ENABLE=yes` in your `Makefile`, because the feature is disabled by default. This adds a little less than 1k to the firmware size. Next, you will want to define some tap-dance keys, which is easiest to do with the `TD()` macro, that - similar to `F()`, takes a number, which will later be used as an index into the `tap_dance_actions` array. This array specifies what actions shall be taken when a tap-dance key is in action. Currently, there are two possible options: * `ACTION_TAP_DANCE_DOUBLE(kc1, kc2)`: Sends the `kc1` keycode when tapped once, `kc2` otherwise. * `ACTION_TAP_DANCE_FN(fn)`: Calls the specified function - defined in the user keymap - with the current state of the tap-dance action. The first option is enough for a lot of cases, that just want dual roles. For example, `ACTION_TAP_DANCE(KC_SPC, KC_ENT)` will result in `Space` being sent on single-tap, `Enter` otherwise. And that's the bulk of it! Do note, however, that this implementation does have some consequences: keys do not register until either they reach the tapping ceiling, or they time out. This means that if you hold the key, nothing happens, no repeat, no nothing. It is possible to detect held state, and register an action then too, but that's not implemented yet. Keys also unregister immediately after being registered, so you can't even hold the second tap. This is intentional, to be consistent. And now, on to the explanation of how it works! The main entry point is `process_tap_dance()`, called from `process_record_quantum()`, which is run for every keypress, and our handler gets to run early. This function checks whether the key pressed is a tap-dance key. If it is not, and a tap-dance was in action, we handle that first, and enqueue the newly pressed key. If it is a tap-dance key, then we check if it is the same as the already active one (if there's one active, that is). If it is not, we fire off the old one first, then register the new one. If it was the same, we increment the counter and the timer. This means that you have `TAPPING_TERM` time to tap the key again, you do not have to input all the taps within that timeframe. This allows for longer tap counts, with minimal impact on responsiveness. Our next stop is `matrix_scan_tap_dance()`. This handles the timeout of tap-dance keys. For the sake of flexibility, tap-dance actions can be either a pair of keycodes, or a user function. The latter allows one to handle higher tap counts, or do extra things, like blink the LEDs, fiddle with the backlighting, and so on. This is accomplished by using an union, and some clever macros. In the end, lets see a full example! ```c enum { CT_SE = 0, CT_CLN, CT_EGG }; /* Have the above three on the keymap, TD(CT_SE), etc... */ void dance_cln (qk_tap_dance_state_t *state) { if (state->count == 1) { register_code (KC_RSFT); register_code (KC_SCLN); unregister_code (KC_SCLN); unregister_code (KC_RSFT); } else { register_code (KC_SCLN); unregister_code (KC_SCLN); reset_tap_dance (state); } } void dance_egg (qk_tap_dance_state_t *state) { if (state->count >= 100) { SEND_STRING ("Safety dance!"); reset_tap_dance (state); } } const qk_tap_dance_action_t tap_dance_actions[] = { [CT_SE] = ACTION_TAP_DANCE_DOUBLE (KC_SPC, KC_ENT) ,[CT_CLN] = ACTION_TAP_DANCE_FN (dance_cln) ,[CT_EGG] = ACTION_TAP_DANCE_FN (dance_egg) }; ``` This addresses #426. Signed-off-by: Gergely Nagy * hhkb: Fix the build with the new tap-dance feature Signed-off-by: Gergely Nagy * tap_dance: Move process_tap_dance further down Process the tap dance stuff after midi and audio, because those don't process keycodes, but row/col positions. Signed-off-by: Gergely Nagy * tap_dance: Use conditionals instead of dummy functions To be consistent with how the rest of the quantum features are implemented, use ifdefs instead of dummy functions. Signed-off-by: Gergely Nagy * Merge branch 'master' into quantum-keypress-process # Conflicts: # Makefile # keyboards/planck/rev3/config.h # keyboards/planck/rev4/config.h * update build script --- quantum/keymap.h | 2 + quantum/keymap_midi.c | 109 ------- quantum/keymap_midi.h | 222 --------------- quantum/process_keycode/process_chording.c | 60 ++++ quantum/process_keycode/process_chording.h | 16 ++ quantum/process_keycode/process_leader.c | 38 +++ quantum/process_keycode/process_leader.h | 23 ++ quantum/process_keycode/process_midi.c | 66 +++++ quantum/process_keycode/process_midi.h | 207 ++++++++++++++ quantum/process_keycode/process_music.c | 171 +++++++++++ quantum/process_keycode/process_music.h | 27 ++ quantum/process_keycode/process_tap_dance.c | 90 ++++++ quantum/process_keycode/process_tap_dance.h | 62 ++++ quantum/process_keycode/process_unicode.c | 57 ++++ quantum/process_keycode/process_unicode.h | 122 ++++++++ quantum/quantum.c | 425 ++-------------------------- quantum/quantum.h | 57 ++-- quantum/unicode.h | 128 --------- 18 files changed, 981 insertions(+), 901 deletions(-) delete mode 100644 quantum/keymap_midi.c delete mode 100644 quantum/keymap_midi.h create mode 100644 quantum/process_keycode/process_chording.c create mode 100644 quantum/process_keycode/process_chording.h create mode 100644 quantum/process_keycode/process_leader.c create mode 100644 quantum/process_keycode/process_leader.h create mode 100644 quantum/process_keycode/process_midi.c create mode 100644 quantum/process_keycode/process_midi.h create mode 100644 quantum/process_keycode/process_music.c create mode 100644 quantum/process_keycode/process_music.h create mode 100644 quantum/process_keycode/process_tap_dance.c create mode 100644 quantum/process_keycode/process_tap_dance.h create mode 100644 quantum/process_keycode/process_unicode.c create mode 100644 quantum/process_keycode/process_unicode.h delete mode 100644 quantum/unicode.h (limited to 'quantum') diff --git a/quantum/keymap.h b/quantum/keymap.h index 41fa394ab..a994f4f2e 100644 --- a/quantum/keymap.h +++ b/quantum/keymap.h @@ -77,6 +77,8 @@ enum quantum_keycodes { #endif QK_MOD_TAP = 0x6000, QK_MOD_TAP_MAX = 0x6FFF, + QK_TAP_DANCE = 0x7100, + QK_TAP_DANCE_MAX = 0x71FF, #ifdef UNICODE_ENABLE QK_UNICODE = 0x8000, QK_UNICODE_MAX = 0xFFFF, diff --git a/quantum/keymap_midi.c b/quantum/keymap_midi.c deleted file mode 100644 index 46049b987..000000000 --- a/quantum/keymap_midi.c +++ /dev/null @@ -1,109 +0,0 @@ -/* -Copyright 2015 Jack Humbert - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -#include "keymap.h" -#include "keymap_midi.h" - -uint8_t starting_note = 0x0C; -int offset = 7; - -void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) -{ - if (id != 0) { - if (record->event.pressed) { - midi_send_noteon(&midi_device, opt, (id & 0xFF), 127); - } else { - midi_send_noteoff(&midi_device, opt, (id & 0xFF), 127); - } - } - - if (record->event.key.col == (MATRIX_COLS - 1) && record->event.key.row == (MATRIX_ROWS - 1)) { - if (record->event.pressed) { - starting_note++; - play_note(((double)261.626)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[0 + offset])/12.0+(MATRIX_ROWS - 1)), 0xC); - midi_send_cc(&midi_device, 0, 0x7B, 0); - midi_send_cc(&midi_device, 1, 0x7B, 0); - midi_send_cc(&midi_device, 2, 0x7B, 0); - midi_send_cc(&midi_device, 3, 0x7B, 0); - midi_send_cc(&midi_device, 4, 0x7B, 0); - return; - } else { - stop_note(((double)261.626)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[0 + offset])/12.0+(MATRIX_ROWS - 1))); - stop_all_notes(); - return; - } - } - if (record->event.key.col == (MATRIX_COLS - 2) && record->event.key.row == (MATRIX_ROWS - 1)) { - if (record->event.pressed) { - starting_note--; - play_note(((double)261.626)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[0 + offset])/12.0+(MATRIX_ROWS - 1)), 0xC); - midi_send_cc(&midi_device, 0, 0x7B, 0); - midi_send_cc(&midi_device, 1, 0x7B, 0); - midi_send_cc(&midi_device, 2, 0x7B, 0); - midi_send_cc(&midi_device, 3, 0x7B, 0); - midi_send_cc(&midi_device, 4, 0x7B, 0); - return; - } else { - stop_note(((double)261.626)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[0 + offset])/12.0+(MATRIX_ROWS - 1))); - stop_all_notes(); - return; - } - } - - if (record->event.key.col == (MATRIX_COLS - 3) && record->event.key.row == (MATRIX_ROWS - 1) && record->event.pressed) { - offset++; - midi_send_cc(&midi_device, 0, 0x7B, 0); - midi_send_cc(&midi_device, 1, 0x7B, 0); - midi_send_cc(&midi_device, 2, 0x7B, 0); - midi_send_cc(&midi_device, 3, 0x7B, 0); - midi_send_cc(&midi_device, 4, 0x7B, 0); - stop_all_notes(); - for (int i = 0; i <= 7; i++) { - play_note(((double)261.626)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[i + offset])/12.0+(MATRIX_ROWS - 1)), 0xC); - _delay_us(80000); - stop_note(((double)261.626)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[i + offset])/12.0+(MATRIX_ROWS - 1))); - _delay_us(8000); - } - return; - } - if (record->event.key.col == (MATRIX_COLS - 4) && record->event.key.row == (MATRIX_ROWS - 1) && record->event.pressed) { - offset--; - midi_send_cc(&midi_device, 0, 0x7B, 0); - midi_send_cc(&midi_device, 1, 0x7B, 0); - midi_send_cc(&midi_device, 2, 0x7B, 0); - midi_send_cc(&midi_device, 3, 0x7B, 0); - midi_send_cc(&midi_device, 4, 0x7B, 0); - stop_all_notes(); - for (int i = 0; i <= 7; i++) { - play_note(((double)261.626)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[i + offset])/12.0+(MATRIX_ROWS - 1)), 0xC); - _delay_us(80000); - stop_note(((double)261.626)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[i + offset])/12.0+(MATRIX_ROWS - 1))); - _delay_us(8000); - } - return; - } - - if (record->event.pressed) { - // midi_send_noteon(&midi_device, record->event.key.row, starting_note + SCALE[record->event.key.col], 127); - // midi_send_noteon(&midi_device, 0, (starting_note + SCALE[record->event.key.col + offset])+12*(MATRIX_ROWS - record->event.key.row), 127); - play_note(((double)261.626)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[record->event.key.col + offset])/12.0+(MATRIX_ROWS - record->event.key.row)), 0xF); - } else { - // midi_send_noteoff(&midi_device, record->event.key.row, starting_note + SCALE[record->event.key.col], 127); - // midi_send_noteoff(&midi_device, 0, (starting_note + SCALE[record->event.key.col + offset])+12*(MATRIX_ROWS - record->event.key.row), 127); - stop_note(((double)261.626)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[record->event.key.col + offset])/12.0+(MATRIX_ROWS - record->event.key.row))); - } -} \ No newline at end of file diff --git a/quantum/keymap_midi.h b/quantum/keymap_midi.h deleted file mode 100644 index 3a2bf3aff..000000000 --- a/quantum/keymap_midi.h +++ /dev/null @@ -1,222 +0,0 @@ -/* -Copyright 2015 Jack Humbert - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -#ifndef KEYMAP_MIDI_H -#define KEYMAP_MIDI_H - -#include - -#define MIDI(n) ((n) | 0x6000) -#define MIDI12 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000 - -#define CHNL(note, channel) (note + (channel << 8)) - -#define SCALE (int8_t []){ 0 + (12*0), 2 + (12*0), 4 + (12*0), 5 + (12*0), 7 + (12*0), 9 + (12*0), 11 + (12*0), \ - 0 + (12*1), 2 + (12*1), 4 + (12*1), 5 + (12*1), 7 + (12*1), 9 + (12*1), 11 + (12*1), \ - 0 + (12*2), 2 + (12*2), 4 + (12*2), 5 + (12*2), 7 + (12*2), 9 + (12*2), 11 + (12*2), \ - 0 + (12*3), 2 + (12*3), 4 + (12*3), 5 + (12*3), 7 + (12*3), 9 + (12*3), 11 + (12*3), \ - 0 + (12*4), 2 + (12*4), 4 + (12*4), 5 + (12*4), 7 + (12*4), 9 + (12*4), 11 + (12*4), } - -#define N_CN1 (0x600C + (12 * -1) + 0 ) -#define N_CN1S (0x600C + (12 * -1) + 1 ) -#define N_DN1F (0x600C + (12 * -1) + 1 ) -#define N_DN1 (0x600C + (12 * -1) + 2 ) -#define N_DN1S (0x600C + (12 * -1) + 3 ) -#define N_EN1F (0x600C + (12 * -1) + 3 ) -#define N_EN1 (0x600C + (12 * -1) + 4 ) -#define N_FN1 (0x600C + (12 * -1) + 5 ) -#define N_FN1S (0x600C + (12 * -1) + 6 ) -#define N_GN1F (0x600C + (12 * -1) + 6 ) -#define N_GN1 (0x600C + (12 * -1) + 7 ) -#define N_GN1S (0x600C + (12 * -1) + 8 ) -#define N_AN1F (0x600C + (12 * -1) + 8 ) -#define N_AN1 (0x600C + (12 * -1) + 9 ) -#define N_AN1S (0x600C + (12 * -1) + 10) -#define N_BN1F (0x600C + (12 * -1) + 10) -#define N_BN1 (0x600C + (12 * -1) + 11) -#define N_C0 (0x600C + (12 * 0) + 0 ) -#define N_C0S (0x600C + (12 * 0) + 1 ) -#define N_D0F (0x600C + (12 * 0) + 1 ) -#define N_D0 (0x600C + (12 * 0) + 2 ) -#define N_D0S (0x600C + (12 * 0) + 3 ) -#define N_E0F (0x600C + (12 * 0) + 3 ) -#define N_E0 (0x600C + (12 * 0) + 4 ) -#define N_F0 (0x600C + (12 * 0) + 5 ) -#define N_F0S (0x600C + (12 * 0) + 6 ) -#define N_G0F (0x600C + (12 * 0) + 6 ) -#define N_G0 (0x600C + (12 * 0) + 7 ) -#define N_G0S (0x600C + (12 * 0) + 8 ) -#define N_A0F (0x600C + (12 * 0) + 8 ) -#define N_A0 (0x600C + (12 * 0) + 9 ) -#define N_A0S (0x600C + (12 * 0) + 10) -#define N_B0F (0x600C + (12 * 0) + 10) -#define N_B0 (0x600C + (12 * 0) + 11) -#define N_C1 (0x600C + (12 * 1) + 0 ) -#define N_C1S (0x600C + (12 * 1) + 1 ) -#define N_D1F (0x600C + (12 * 1) + 1 ) -#define N_D1 (0x600C + (12 * 1) + 2 ) -#define N_D1S (0x600C + (12 * 1) + 3 ) -#define N_E1F (0x600C + (12 * 1) + 3 ) -#define N_E1 (0x600C + (12 * 1) + 4 ) -#define N_F1 (0x600C + (12 * 1) + 5 ) -#define N_F1S (0x600C + (12 * 1) + 6 ) -#define N_G1F (0x600C + (12 * 1) + 6 ) -#define N_G1 (0x600C + (12 * 1) + 7 ) -#define N_G1S (0x600C + (12 * 1) + 8 ) -#define N_A1F (0x600C + (12 * 1) + 8 ) -#define N_A1 (0x600C + (12 * 1) + 9 ) -#define N_A1S (0x600C + (12 * 1) + 10) -#define N_B1F (0x600C + (12 * 1) + 10) -#define N_B1 (0x600C + (12 * 1) + 11) -#define N_C2 (0x600C + (12 * 2) + 0 ) -#define N_C2S (0x600C + (12 * 2) + 1 ) -#define N_D2F (0x600C + (12 * 2) + 1 ) -#define N_D2 (0x600C + (12 * 2) + 2 ) -#define N_D2S (0x600C + (12 * 2) + 3 ) -#define N_E2F (0x600C + (12 * 2) + 3 ) -#define N_E2 (0x600C + (12 * 2) + 4 ) -#define N_F2 (0x600C + (12 * 2) + 5 ) -#define N_F2S (0x600C + (12 * 2) + 6 ) -#define N_G2F (0x600C + (12 * 2) + 6 ) -#define N_G2 (0x600C + (12 * 2) + 7 ) -#define N_G2S (0x600C + (12 * 2) + 8 ) -#define N_A2F (0x600C + (12 * 2) + 8 ) -#define N_A2 (0x600C + (12 * 2) + 9 ) -#define N_A2S (0x600C + (12 * 2) + 10) -#define N_B2F (0x600C + (12 * 2) + 10) -#define N_B2 (0x600C + (12 * 2) + 11) -#define N_C3 (0x600C + (12 * 3) + 0 ) -#define N_C3S (0x600C + (12 * 3) + 1 ) -#define N_D3F (0x600C + (12 * 3) + 1 ) -#define N_D3 (0x600C + (12 * 3) + 2 ) -#define N_D3S (0x600C + (12 * 3) + 3 ) -#define N_E3F (0x600C + (12 * 3) + 3 ) -#define N_E3 (0x600C + (12 * 3) + 4 ) -#define N_F3 (0x600C + (12 * 3) + 5 ) -#define N_F3S (0x600C + (12 * 3) + 6 ) -#define N_G3F (0x600C + (12 * 3) + 6 ) -#define N_G3 (0x600C + (12 * 3) + 7 ) -#define N_G3S (0x600C + (12 * 3) + 8 ) -#define N_A3F (0x600C + (12 * 3) + 8 ) -#define N_A3 (0x600C + (12 * 3) + 9 ) -#define N_A3S (0x600C + (12 * 3) + 10) -#define N_B3F (0x600C + (12 * 3) + 10) -#define N_B3 (0x600C + (12 * 3) + 11) -#define N_C4 (0x600C + (12 * 4) + 0 ) -#define N_C4S (0x600C + (12 * 4) + 1 ) -#define N_D4F (0x600C + (12 * 4) + 1 ) -#define N_D4 (0x600C + (12 * 4) + 2 ) -#define N_D4S (0x600C + (12 * 4) + 3 ) -#define N_E4F (0x600C + (12 * 4) + 3 ) -#define N_E4 (0x600C + (12 * 4) + 4 ) -#define N_F4 (0x600C + (12 * 4) + 5 ) -#define N_F4S (0x600C + (12 * 4) + 6 ) -#define N_G4F (0x600C + (12 * 4) + 6 ) -#define N_G4 (0x600C + (12 * 4) + 7 ) -#define N_G4S (0x600C + (12 * 4) + 8 ) -#define N_A4F (0x600C + (12 * 4) + 8 ) -#define N_A4 (0x600C + (12 * 4) + 9 ) -#define N_A4S (0x600C + (12 * 4) + 10) -#define N_B4F (0x600C + (12 * 4) + 10) -#define N_B4 (0x600C + (12 * 4) + 11) -#define N_C5 (0x600C + (12 * 5) + 0 ) -#define N_C5S (0x600C + (12 * 5) + 1 ) -#define N_D5F (0x600C + (12 * 5) + 1 ) -#define N_D5 (0x600C + (12 * 5) + 2 ) -#define N_D5S (0x600C + (12 * 5) + 3 ) -#define N_E5F (0x600C + (12 * 5) + 3 ) -#define N_E5 (0x600C + (12 * 5) + 4 ) -#define N_F5 (0x600C + (12 * 5) + 5 ) -#define N_F5S (0x600C + (12 * 5) + 6 ) -#define N_G5F (0x600C + (12 * 5) + 6 ) -#define N_G5 (0x600C + (12 * 5) + 7 ) -#define N_G5S (0x600C + (12 * 5) + 8 ) -#define N_A5F (0x600C + (12 * 5) + 8 ) -#define N_A5 (0x600C + (12 * 5) + 9 ) -#define N_A5S (0x600C + (12 * 5) + 10) -#define N_B5F (0x600C + (12 * 5) + 10) -#define N_B5 (0x600C + (12 * 5) + 11) -#define N_C6 (0x600C + (12 * 6) + 0 ) -#define N_C6S (0x600C + (12 * 6) + 1 ) -#define N_D6F (0x600C + (12 * 6) + 1 ) -#define N_D6 (0x600C + (12 * 6) + 2 ) -#define N_D6S (0x600C + (12 * 6) + 3 ) -#define N_E6F (0x600C + (12 * 6) + 3 ) -#define N_E6 (0x600C + (12 * 6) + 4 ) -#define N_F6 (0x600C + (12 * 6) + 5 ) -#define N_F6S (0x600C + (12 * 6) + 6 ) -#define N_G6F (0x600C + (12 * 6) + 6 ) -#define N_G6 (0x600C + (12 * 6) + 7 ) -#define N_G6S (0x600C + (12 * 6) + 8 ) -#define N_A6F (0x600C + (12 * 6) + 8 ) -#define N_A6 (0x600C + (12 * 6) + 9 ) -#define N_A6S (0x600C + (12 * 6) + 10) -#define N_B6F (0x600C + (12 * 6) + 10) -#define N_B6 (0x600C + (12 * 6) + 11) -#define N_C7 (0x600C + (12 * 7) + 0 ) -#define N_C7S (0x600C + (12 * 7) + 1 ) -#define N_D7F (0x600C + (12 * 7) + 1 ) -#define N_D7 (0x600C + (12 * 7) + 2 ) -#define N_D7S (0x600C + (12 * 7) + 3 ) -#define N_E7F (0x600C + (12 * 7) + 3 ) -#define N_E7 (0x600C + (12 * 7) + 4 ) -#define N_F7 (0x600C + (12 * 7) + 5 ) -#define N_F7S (0x600C + (12 * 7) + 6 ) -#define N_G7F (0x600C + (12 * 7) + 6 ) -#define N_G7 (0x600C + (12 * 7) + 7 ) -#define N_G7S (0x600C + (12 * 7) + 8 ) -#define N_A7F (0x600C + (12 * 7) + 8 ) -#define N_A7 (0x600C + (12 * 7) + 9 ) -#define N_A7S (0x600C + (12 * 7) + 10) -#define N_B7F (0x600C + (12 * 7) + 10) -#define N_B7 (0x600C + (12 * 7) + 11) -#define N_C8 (0x600C + (12 * 8) + 0 ) -#define N_C8S (0x600C + (12 * 8) + 1 ) -#define N_D8F (0x600C + (12 * 8) + 1 ) -#define N_D8 (0x600C + (12 * 8) + 2 ) -#define N_D8S (0x600C + (12 * 8) + 3 ) -#define N_E8F (0x600C + (12 * 8) + 3 ) -#define N_E8 (0x600C + (12 * 8) + 4 ) -#define N_F8 (0x600C + (12 * 8) + 5 ) -#define N_F8S (0x600C + (12 * 8) + 6 ) -#define N_G8F (0x600C + (12 * 8) + 6 ) -#define N_G8 (0x600C + (12 * 8) + 7 ) -#define N_G8S (0x600C + (12 * 8) + 8 ) -#define N_A8F (0x600C + (12 * 8) + 8 ) -#define N_A8 (0x600C + (12 * 8) + 9 ) -#define N_A8S (0x600C + (12 * 8) + 10) -#define N_B8F (0x600C + (12 * 8) + 10) -#define N_B8 (0x600C + (12 * 8) + 11) -#define N_C8 (0x600C + (12 * 8) + 0 ) -#define N_C8S (0x600C + (12 * 8) + 1 ) -#define N_D8F (0x600C + (12 * 8) + 1 ) -#define N_D8 (0x600C + (12 * 8) + 2 ) -#define N_D8S (0x600C + (12 * 8) + 3 ) -#define N_E8F (0x600C + (12 * 8) + 3 ) -#define N_E8 (0x600C + (12 * 8) + 4 ) -#define N_F8 (0x600C + (12 * 8) + 5 ) -#define N_F8S (0x600C + (12 * 8) + 6 ) -#define N_G8F (0x600C + (12 * 8) + 6 ) -#define N_G8 (0x600C + (12 * 8) + 7 ) -#define N_G8S (0x600C + (12 * 8) + 8 ) -#define N_A8F (0x600C + (12 * 8) + 8 ) -#define N_A8 (0x600C + (12 * 8) + 9 ) -#define N_A8S (0x600C + (12 * 8) + 10) -#define N_B8F (0x600C + (12 * 8) + 10) -#define N_B8 (0x600C + (12 * 8) + 11) - -#endif \ No newline at end of file diff --git a/quantum/process_keycode/process_chording.c b/quantum/process_keycode/process_chording.c new file mode 100644 index 000000000..d7814629f --- /dev/null +++ b/quantum/process_keycode/process_chording.c @@ -0,0 +1,60 @@ +#include "process_chording.h" + +bool keys_chord(uint8_t keys[]) { + uint8_t keys_size = sizeof(keys)/sizeof(keys[0]); + bool pass = true; + uint8_t in = 0; + for (uint8_t i = 0; i < chord_key_count; i++) { + bool found = false; + for (uint8_t j = 0; j < keys_size; j++) { + if (chord_keys[i] == (keys[j] & 0xFF)) { + in++; // detects key in chord + found = true; + break; + } + } + if (found) + continue; + if (chord_keys[i] != 0) { + pass = false; // makes sure rest are blank + } + } + return (pass && (in == keys_size)); +} + +bool process_chording(uint16_t keycode, keyrecord_t *record) { + if (keycode >= QK_CHORDING && keycode <= QK_CHORDING_MAX) { + if (record->event.pressed) { + if (!chording) { + chording = true; + for (uint8_t i = 0; i < CHORDING_MAX; i++) + chord_keys[i] = 0; + chord_key_count = 0; + chord_key_down = 0; + } + chord_keys[chord_key_count] = (keycode & 0xFF); + chord_key_count++; + chord_key_down++; + return false; + } else { + if (chording) { + chord_key_down--; + if (chord_key_down == 0) { + chording = false; + // Chord Dictionary + if (keys_chord((uint8_t[]){KC_ENTER, KC_SPACE})) { + register_code(KC_A); + unregister_code(KC_A); + return false; + } + for (uint8_t i = 0; i < chord_key_count; i++) { + register_code(chord_keys[i]); + unregister_code(chord_keys[i]); + return false; + } + } + } + } + } + return true; +} \ No newline at end of file diff --git a/quantum/process_keycode/process_chording.h b/quantum/process_keycode/process_chording.h new file mode 100644 index 000000000..49c97db3b --- /dev/null +++ b/quantum/process_keycode/process_chording.h @@ -0,0 +1,16 @@ +#ifndef PROCESS_CHORDING_H +#define PROCESS_CHORDING_H + +#include "quantum.h" + +// Chording stuff +#define CHORDING_MAX 4 +bool chording = false; + +uint8_t chord_keys[CHORDING_MAX] = {0}; +uint8_t chord_key_count = 0; +uint8_t chord_key_down = 0; + +bool process_chording(uint16_t keycode, keyrecord_t *record); + +#endif \ No newline at end of file diff --git a/quantum/process_keycode/process_leader.c b/quantum/process_keycode/process_leader.c new file mode 100644 index 000000000..e53d221e7 --- /dev/null +++ b/quantum/process_keycode/process_leader.c @@ -0,0 +1,38 @@ +#include "process_leader.h" + +__attribute__ ((weak)) +void leader_start(void) {} + +__attribute__ ((weak)) +void leader_end(void) {} + +// Leader key stuff +bool leading = false; +uint16_t leader_time = 0; + +uint16_t leader_sequence[5] = {0, 0, 0, 0, 0}; +uint8_t leader_sequence_size = 0; + +bool process_leader(uint16_t keycode, keyrecord_t *record) { + // Leader key set-up + if (record->event.pressed) { + if (!leading && keycode == KC_LEAD) { + leader_start(); + leading = true; + leader_time = timer_read(); + leader_sequence_size = 0; + leader_sequence[0] = 0; + leader_sequence[1] = 0; + leader_sequence[2] = 0; + leader_sequence[3] = 0; + leader_sequence[4] = 0; + return false; + } + if (leading && timer_elapsed(leader_time) < LEADER_TIMEOUT) { + leader_sequence[leader_sequence_size] = keycode; + leader_sequence_size++; + return false; + } + } + return true; +} \ No newline at end of file diff --git a/quantum/process_keycode/process_leader.h b/quantum/process_keycode/process_leader.h new file mode 100644 index 000000000..c83db8abb --- /dev/null +++ b/quantum/process_keycode/process_leader.h @@ -0,0 +1,23 @@ +#ifndef PROCESS_LEADER_H +#define PROCESS_LEADER_H + +#include "quantum.h" + +bool process_leader(uint16_t keycode, keyrecord_t *record); + +void leader_start(void); +void leader_end(void); + +#ifndef LEADER_TIMEOUT + #define LEADER_TIMEOUT 200 +#endif +#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) +#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) +#define SEQ_THREE_KEYS(key1, key2, key3) if (leader_sequence[0] == (key1) && leader_sequence[1] == (key2) && leader_sequence[2] == (key3) && leader_sequence[3] == 0 && leader_sequence[4] == 0) +#define SEQ_FOUR_KEYS(key1, key2, key3, key4) if (leader_sequence[0] == (key1) && leader_sequence[1] == (key2) && leader_sequence[2] == (key3) && leader_sequence[3] == (key4) && leader_sequence[4] == 0) +#define SEQ_FIVE_KEYS(key1, key2, key3, key4, key5) if (leader_sequence[0] == (key1) && leader_sequence[1] == (key2) && leader_sequence[2] == (key3) && leader_sequence[3] == (key4) && leader_sequence[4] == (key5)) + +#define LEADER_EXTERNS() extern bool leading; extern uint16_t leader_time; extern uint16_t leader_sequence[5]; extern uint8_t leader_sequence_size +#define LEADER_DICTIONARY() if (leading && timer_elapsed(leader_time) > LEADER_TIMEOUT) + +#endif \ No newline at end of file diff --git a/quantum/process_keycode/process_midi.c b/quantum/process_keycode/process_midi.c new file mode 100644 index 000000000..d6ab9c626 --- /dev/null +++ b/quantum/process_keycode/process_midi.c @@ -0,0 +1,66 @@ +#include "process_midi.h" + +bool midi_activated = false; +uint8_t starting_note = 0x0C; +int offset = 7; + +bool process_midi(uint16_t keycode, keyrecord_t *record) { + if (keycode == MI_ON && record->event.pressed) { + midi_activated = true; + music_scale_user(); + return false; + } + + if (keycode == MI_OFF && record->event.pressed) { + midi_activated = false; + midi_send_cc(&midi_device, 0, 0x7B, 0); + return false; + } + + if (midi_activated) { + if (record->event.key.col == (MATRIX_COLS - 1) && record->event.key.row == (MATRIX_ROWS - 1)) { + if (record->event.pressed) { + starting_note++; // Change key + midi_send_cc(&midi_device, 0, 0x7B, 0); + } + return false; + } + if (record->event.key.col == (MATRIX_COLS - 2) && record->event.key.row == (MATRIX_ROWS - 1)) { + if (record->event.pressed) { + starting_note--; // Change key + midi_send_cc(&midi_device, 0, 0x7B, 0); + } + return false; + } + if (record->event.key.col == (MATRIX_COLS - 3) && record->event.key.row == (MATRIX_ROWS - 1) && record->event.pressed) { + offset++; // Change scale + midi_send_cc(&midi_device, 0, 0x7B, 0); + return false; + } + if (record->event.key.col == (MATRIX_COLS - 4) && record->event.key.row == (MATRIX_ROWS - 1) && record->event.pressed) { + offset--; // Change scale + midi_send_cc(&midi_device, 0, 0x7B, 0); + return false; + } + // basic + // uint8_t note = (starting_note + SCALE[record->event.key.col + offset])+12*(MATRIX_ROWS - record->event.key.row); + // advanced + // uint8_t note = (starting_note + record->event.key.col + offset)+12*(MATRIX_ROWS - record->event.key.row); + // guitar + uint8_t note = (starting_note + record->event.key.col + offset)+5*(MATRIX_ROWS - record->event.key.row); + // violin + // uint8_t note = (starting_note + record->event.key.col + offset)+7*(MATRIX_ROWS - record->event.key.row); + + if (record->event.pressed) { + // midi_send_noteon(&midi_device, record->event.key.row, starting_note + SCALE[record->event.key.col], 127); + midi_send_noteon(&midi_device, 0, note, 127); + } else { + // midi_send_noteoff(&midi_device, record->event.key.row, starting_note + SCALE[record->event.key.col], 127); + midi_send_noteoff(&midi_device, 0, note, 127); + } + + if (keycode < 0xFF) // ignores all normal keycodes, but lets RAISE, LOWER, etc through + return false; + } + return true; +} \ No newline at end of file diff --git a/quantum/process_keycode/process_midi.h b/quantum/process_keycode/process_midi.h new file mode 100644 index 000000000..acd4fc1b1 --- /dev/null +++ b/quantum/process_keycode/process_midi.h @@ -0,0 +1,207 @@ +#ifndef PROCESS_MIDI_H +#define PROCESS_MIDI_H + +#include "quantum.h" + +bool process_midi(uint16_t keycode, keyrecord_t *record); + +#define MIDI(n) ((n) | 0x6000) +#define MIDI12 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000 + +#define CHNL(note, channel) (note + (channel << 8)) + +#define SCALE (int8_t []){ 0 + (12*0), 2 + (12*0), 4 + (12*0), 5 + (12*0), 7 + (12*0), 9 + (12*0), 11 + (12*0), \ + 0 + (12*1), 2 + (12*1), 4 + (12*1), 5 + (12*1), 7 + (12*1), 9 + (12*1), 11 + (12*1), \ + 0 + (12*2), 2 + (12*2), 4 + (12*2), 5 + (12*2), 7 + (12*2), 9 + (12*2), 11 + (12*2), \ + 0 + (12*3), 2 + (12*3), 4 + (12*3), 5 + (12*3), 7 + (12*3), 9 + (12*3), 11 + (12*3), \ + 0 + (12*4), 2 + (12*4), 4 + (12*4), 5 + (12*4), 7 + (12*4), 9 + (12*4), 11 + (12*4), } + +#define N_CN1 (0x600C + (12 * -1) + 0 ) +#define N_CN1S (0x600C + (12 * -1) + 1 ) +#define N_DN1F (0x600C + (12 * -1) + 1 ) +#define N_DN1 (0x600C + (12 * -1) + 2 ) +#define N_DN1S (0x600C + (12 * -1) + 3 ) +#define N_EN1F (0x600C + (12 * -1) + 3 ) +#define N_EN1 (0x600C + (12 * -1) + 4 ) +#define N_FN1 (0x600C + (12 * -1) + 5 ) +#define N_FN1S (0x600C + (12 * -1) + 6 ) +#define N_GN1F (0x600C + (12 * -1) + 6 ) +#define N_GN1 (0x600C + (12 * -1) + 7 ) +#define N_GN1S (0x600C + (12 * -1) + 8 ) +#define N_AN1F (0x600C + (12 * -1) + 8 ) +#define N_AN1 (0x600C + (12 * -1) + 9 ) +#define N_AN1S (0x600C + (12 * -1) + 10) +#define N_BN1F (0x600C + (12 * -1) + 10) +#define N_BN1 (0x600C + (12 * -1) + 11) +#define N_C0 (0x600C + (12 * 0) + 0 ) +#define N_C0S (0x600C + (12 * 0) + 1 ) +#define N_D0F (0x600C + (12 * 0) + 1 ) +#define N_D0 (0x600C + (12 * 0) + 2 ) +#define N_D0S (0x600C + (12 * 0) + 3 ) +#define N_E0F (0x600C + (12 * 0) + 3 ) +#define N_E0 (0x600C + (12 * 0) + 4 ) +#define N_F0 (0x600C + (12 * 0) + 5 ) +#define N_F0S (0x600C + (12 * 0) + 6 ) +#define N_G0F (0x600C + (12 * 0) + 6 ) +#define N_G0 (0x600C + (12 * 0) + 7 ) +#define N_G0S (0x600C + (12 * 0) + 8 ) +#define N_A0F (0x600C + (12 * 0) + 8 ) +#define N_A0 (0x600C + (12 * 0) + 9 ) +#define N_A0S (0x600C + (12 * 0) + 10) +#define N_B0F (0x600C + (12 * 0) + 10) +#define N_B0 (0x600C + (12 * 0) + 11) +#define N_C1 (0x600C + (12 * 1) + 0 ) +#define N_C1S (0x600C + (12 * 1) + 1 ) +#define N_D1F (0x600C + (12 * 1) + 1 ) +#define N_D1 (0x600C + (12 * 1) + 2 ) +#define N_D1S (0x600C + (12 * 1) + 3 ) +#define N_E1F (0x600C + (12 * 1) + 3 ) +#define N_E1 (0x600C + (12 * 1) + 4 ) +#define N_F1 (0x600C + (12 * 1) + 5 ) +#define N_F1S (0x600C + (12 * 1) + 6 ) +#define N_G1F (0x600C + (12 * 1) + 6 ) +#define N_G1 (0x600C + (12 * 1) + 7 ) +#define N_G1S (0x600C + (12 * 1) + 8 ) +#define N_A1F (0x600C + (12 * 1) + 8 ) +#define N_A1 (0x600C + (12 * 1) + 9 ) +#define N_A1S (0x600C + (12 * 1) + 10) +#define N_B1F (0x600C + (12 * 1) + 10) +#define N_B1 (0x600C + (12 * 1) + 11) +#define N_C2 (0x600C + (12 * 2) + 0 ) +#define N_C2S (0x600C + (12 * 2) + 1 ) +#define N_D2F (0x600C + (12 * 2) + 1 ) +#define N_D2 (0x600C + (12 * 2) + 2 ) +#define N_D2S (0x600C + (12 * 2) + 3 ) +#define N_E2F (0x600C + (12 * 2) + 3 ) +#define N_E2 (0x600C + (12 * 2) + 4 ) +#define N_F2 (0x600C + (12 * 2) + 5 ) +#define N_F2S (0x600C + (12 * 2) + 6 ) +#define N_G2F (0x600C + (12 * 2) + 6 ) +#define N_G2 (0x600C + (12 * 2) + 7 ) +#define N_G2S (0x600C + (12 * 2) + 8 ) +#define N_A2F (0x600C + (12 * 2) + 8 ) +#define N_A2 (0x600C + (12 * 2) + 9 ) +#define N_A2S (0x600C + (12 * 2) + 10) +#define N_B2F (0x600C + (12 * 2) + 10) +#define N_B2 (0x600C + (12 * 2) + 11) +#define N_C3 (0x600C + (12 * 3) + 0 ) +#define N_C3S (0x600C + (12 * 3) + 1 ) +#define N_D3F (0x600C + (12 * 3) + 1 ) +#define N_D3 (0x600C + (12 * 3) + 2 ) +#define N_D3S (0x600C + (12 * 3) + 3 ) +#define N_E3F (0x600C + (12 * 3) + 3 ) +#define N_E3 (0x600C + (12 * 3) + 4 ) +#define N_F3 (0x600C + (12 * 3) + 5 ) +#define N_F3S (0x600C + (12 * 3) + 6 ) +#define N_G3F (0x600C + (12 * 3) + 6 ) +#define N_G3 (0x600C + (12 * 3) + 7 ) +#define N_G3S (0x600C + (12 * 3) + 8 ) +#define N_A3F (0x600C + (12 * 3) + 8 ) +#define N_A3 (0x600C + (12 * 3) + 9 ) +#define N_A3S (0x600C + (12 * 3) + 10) +#define N_B3F (0x600C + (12 * 3) + 10) +#define N_B3 (0x600C + (12 * 3) + 11) +#define N_C4 (0x600C + (12 * 4) + 0 ) +#define N_C4S (0x600C + (12 * 4) + 1 ) +#define N_D4F (0x600C + (12 * 4) + 1 ) +#define N_D4 (0x600C + (12 * 4) + 2 ) +#define N_D4S (0x600C + (12 * 4) + 3 ) +#define N_E4F (0x600C + (12 * 4) + 3 ) +#define N_E4 (0x600C + (12 * 4) + 4 ) +#define N_F4 (0x600C + (12 * 4) + 5 ) +#define N_F4S (0x600C + (12 * 4) + 6 ) +#define N_G4F (0x600C + (12 * 4) + 6 ) +#define N_G4 (0x600C + (12 * 4) + 7 ) +#define N_G4S (0x600C + (12 * 4) + 8 ) +#define N_A4F (0x600C + (12 * 4) + 8 ) +#define N_A4 (0x600C + (12 * 4) + 9 ) +#define N_A4S (0x600C + (12 * 4) + 10) +#define N_B4F (0x600C + (12 * 4) + 10) +#define N_B4 (0x600C + (12 * 4) + 11) +#define N_C5 (0x600C + (12 * 5) + 0 ) +#define N_C5S (0x600C + (12 * 5) + 1 ) +#define N_D5F (0x600C + (12 * 5) + 1 ) +#define N_D5 (0x600C + (12 * 5) + 2 ) +#define N_D5S (0x600C + (12 * 5) + 3 ) +#define N_E5F (0x600C + (12 * 5) + 3 ) +#define N_E5 (0x600C + (12 * 5) + 4 ) +#define N_F5 (0x600C + (12 * 5) + 5 ) +#define N_F5S (0x600C + (12 * 5) + 6 ) +#define N_G5F (0x600C + (12 * 5) + 6 ) +#define N_G5 (0x600C + (12 * 5) + 7 ) +#define N_G5S (0x600C + (12 * 5) + 8 ) +#define N_A5F (0x600C + (12 * 5) + 8 ) +#define N_A5 (0x600C + (12 * 5) + 9 ) +#define N_A5S (0x600C + (12 * 5) + 10) +#define N_B5F (0x600C + (12 * 5) + 10) +#define N_B5 (0x600C + (12 * 5) + 11) +#define N_C6 (0x600C + (12 * 6) + 0 ) +#define N_C6S (0x600C + (12 * 6) + 1 ) +#define N_D6F (0x600C + (12 * 6) + 1 ) +#define N_D6 (0x600C + (12 * 6) + 2 ) +#define N_D6S (0x600C + (12 * 6) + 3 ) +#define N_E6F (0x600C + (12 * 6) + 3 ) +#define N_E6 (0x600C + (12 * 6) + 4 ) +#define N_F6 (0x600C + (12 * 6) + 5 ) +#define N_F6S (0x600C + (12 * 6) + 6 ) +#define N_G6F (0x600C + (12 * 6) + 6 ) +#define N_G6 (0x600C + (12 * 6) + 7 ) +#define N_G6S (0x600C + (12 * 6) + 8 ) +#define N_A6F (0x600C + (12 * 6) + 8 ) +#define N_A6 (0x600C + (12 * 6) + 9 ) +#define N_A6S (0x600C + (12 * 6) + 10) +#define N_B6F (0x600C + (12 * 6) + 10) +#define N_B6 (0x600C + (12 * 6) + 11) +#define N_C7 (0x600C + (12 * 7) + 0 ) +#define N_C7S (0x600C + (12 * 7) + 1 ) +#define N_D7F (0x600C + (12 * 7) + 1 ) +#define N_D7 (0x600C + (12 * 7) + 2 ) +#define N_D7S (0x600C + (12 * 7) + 3 ) +#define N_E7F (0x600C + (12 * 7) + 3 ) +#define N_E7 (0x600C + (12 * 7) + 4 ) +#define N_F7 (0x600C + (12 * 7) + 5 ) +#define N_F7S (0x600C + (12 * 7) + 6 ) +#define N_G7F (0x600C + (12 * 7) + 6 ) +#define N_G7 (0x600C + (12 * 7) + 7 ) +#define N_G7S (0x600C + (12 * 7) + 8 ) +#define N_A7F (0x600C + (12 * 7) + 8 ) +#define N_A7 (0x600C + (12 * 7) + 9 ) +#define N_A7S (0x600C + (12 * 7) + 10) +#define N_B7F (0x600C + (12 * 7) + 10) +#define N_B7 (0x600C + (12 * 7) + 11) +#define N_C8 (0x600C + (12 * 8) + 0 ) +#define N_C8S (0x600C + (12 * 8) + 1 ) +#define N_D8F (0x600C + (12 * 8) + 1 ) +#define N_D8 (0x600C + (12 * 8) + 2 ) +#define N_D8S (0x600C + (12 * 8) + 3 ) +#define N_E8F (0x600C + (12 * 8) + 3 ) +#define N_E8 (0x600C + (12 * 8) + 4 ) +#define N_F8 (0x600C + (12 * 8) + 5 ) +#define N_F8S (0x600C + (12 * 8) + 6 ) +#define N_G8F (0x600C + (12 * 8) + 6 ) +#define N_G8 (0x600C + (12 * 8) + 7 ) +#define N_G8S (0x600C + (12 * 8) + 8 ) +#define N_A8F (0x600C + (12 * 8) + 8 ) +#define N_A8 (0x600C + (12 * 8) + 9 ) +#define N_A8S (0x600C + (12 * 8) + 10) +#define N_B8F (0x600C + (12 * 8) + 10) +#define N_B8 (0x600C + (12 * 8) + 11) +#define N_C8 (0x600C + (12 * 8) + 0 ) +#define N_C8S (0x600C + (12 * 8) + 1 ) +#define N_D8F (0x600C + (12 * 8) + 1 ) +#define N_D8 (0x600C + (12 * 8) + 2 ) +#define N_D8S (0x600C + (12 * 8) + 3 ) +#define N_E8F (0x600C + (12 * 8) + 3 ) +#define N_E8 (0x600C + (12 * 8) + 4 ) +#define N_F8 (0x600C + (12 * 8) + 5 ) +#define N_F8S (0x600C + (12 * 8) + 6 ) +#define N_G8F (0x600C + (12 * 8) + 6 ) +#define N_G8 (0x600C + (12 * 8) + 7 ) +#define N_G8S (0x600C + (12 * 8) + 8 ) +#define N_A8F (0x600C + (12 * 8) + 8 ) +#define N_A8 (0x600C + (12 * 8) + 9 ) +#define N_A8S (0x600C + (12 * 8) + 10) +#define N_B8F (0x600C + (12 * 8) + 10) +#define N_B8 (0x600C + (12 * 8) + 11) + +#endif \ No newline at end of file diff --git a/quantum/process_keycode/process_music.c b/quantum/process_keycode/process_music.c new file mode 100644 index 000000000..c8f3ddb90 --- /dev/null +++ b/quantum/process_keycode/process_music.c @@ -0,0 +1,171 @@ +#include "process_music.h" + +bool music_activated = false; +uint8_t starting_note = 0x0C; +int offset = 7; + +// music sequencer +static bool music_sequence_recording = false; +static bool music_sequence_playing = false; +static float music_sequence[16] = {0}; +static uint8_t music_sequence_count = 0; +static uint8_t music_sequence_position = 0; + +static uint16_t music_sequence_timer = 0; +static uint16_t music_sequence_interval = 100; + +bool process_music(uint16_t keycode, keyrecord_t *record) { + + if (keycode == AU_ON && record->event.pressed) { + audio_on(); + return false; + } + + if (keycode == AU_OFF && record->event.pressed) { + audio_off(); + return false; + } + + if (keycode == AU_TOG && record->event.pressed) { + if (is_audio_on()) + { + audio_off(); + } + else + { + audio_on(); + } + return false; + } + + if (keycode == MU_ON && record->event.pressed) { + music_on(); + return false; + } + + if (keycode == MU_OFF && record->event.pressed) { + music_off(); + return false; + } + + if (keycode == MU_TOG && record->event.pressed) { + if (music_activated) + { + music_off(); + } + else + { + music_on(); + } + return false; + } + + if (keycode == MUV_IN && record->event.pressed) { + voice_iterate(); + music_scale_user(); + return false; + } + + if (keycode == MUV_DE && record->event.pressed) { + voice_deiterate(); + music_scale_user(); + return false; + } + + if (music_activated) { + + if (keycode == KC_LCTL && record->event.pressed) { // Start recording + stop_all_notes(); + music_sequence_recording = true; + music_sequence_playing = false; + music_sequence_count = 0; + return false; + } + + if (keycode == KC_LALT && record->event.pressed) { // Stop recording/playing + stop_all_notes(); + music_sequence_recording = false; + music_sequence_playing = false; + return false; + } + + if (keycode == KC_LGUI && record->event.pressed) { // Start playing + stop_all_notes(); + music_sequence_recording = false; + music_sequence_playing = true; + music_sequence_position = 0; + music_sequence_timer = 0; + return false; + } + + if (keycode == KC_UP) { + if (record->event.pressed) + music_sequence_interval-=10; + return false; + } + + if (keycode == KC_DOWN) { + if (record->event.pressed) + music_sequence_interval+=10; + return false; + } + + float freq = ((float)220.0)*pow(2.0, -5.0)*pow(2.0,(starting_note + SCALE[record->event.key.col + offset])/12.0+(MATRIX_ROWS - record->event.key.row)); + if (record->event.pressed) { + play_note(freq, 0xF); + if (music_sequence_recording) { + music_sequence[music_sequence_count] = freq; + music_sequence_count++; + } + } else { + stop_note(freq); + } + + if (keycode < 0xFF) // ignores all normal keycodes, but lets RAISE, LOWER, etc through + return false; + } + return true; +} + +bool is_music_on(void) { + return (music_activated != 0); +} + +void music_toggle(void) { + if (!music_activated) { + music_on(); + } else { + music_off(); + } +} + +void music_on(void) { + music_activated = 1; + music_on_user(); +} + +void music_off(void) { + music_activated = 0; + stop_all_notes(); +} + + +__attribute__ ((weak)) +void music_on_user() {} + +__attribute__ ((weak)) +void audio_on_user() {} + +__attribute__ ((weak)) +void music_scale_user() {} + +void matrix_scan_music(void) { + if (music_sequence_playing) { + if ((music_sequence_timer == 0) || (timer_elapsed(music_sequence_timer) > music_sequence_interval)) { + music_sequence_timer = timer_read(); + stop_note(music_sequence[(music_sequence_position - 1 < 0)?(music_sequence_position - 1 + music_sequence_count):(music_sequence_position - 1)]); + play_note(music_sequence[music_sequence_position], 0xF); + music_sequence_position = (music_sequence_position + 1) % music_sequence_count; + } + } +} diff --git a/quantum/process_keycode/process_music.h b/quantum/process_keycode/process_music.h new file mode 100644 index 000000000..318b3e387 --- /dev/null +++ b/quantum/process_keycode/process_music.h @@ -0,0 +1,27 @@ +#ifndef PROCESS_MUSIC_H +#define PROCESS_MUSIC_H + +#include "quantum.h" + +bool process_music(uint16_t keycode, keyrecord_t *record); + +bool is_music_on(void); +void music_toggle(void); +void music_on(void); +void music_off(void); + +void audio_on_user(void); +void music_on_user(void); +void music_scale_user(void); + +void matrix_scan_music(void); + +#ifndef SCALE +#define SCALE (int8_t []){ 0 + (12*0), 2 + (12*0), 4 + (12*0), 5 + (12*0), 7 + (12*0), 9 + (12*0), 11 + (12*0), \ + 0 + (12*1), 2 + (12*1), 4 + (12*1), 5 + (12*1), 7 + (12*1), 9 + (12*1), 11 + (12*1), \ + 0 + (12*2), 2 + (12*2), 4 + (12*2), 5 + (12*2), 7 + (12*2), 9 + (12*2), 11 + (12*2), \ + 0 + (12*3), 2 + (12*3), 4 + (12*3), 5 + (12*3), 7 + (12*3), 9 + (12*3), 11 + (12*3), \ + 0 + (12*4), 2 + (12*4), 4 + (12*4), 5 + (12*4), 7 + (12*4), 9 + (12*4), 11 + (12*4), } +#endif + +#endif \ No newline at end of file diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c new file mode 100644 index 000000000..9b172e1b6 --- /dev/null +++ b/quantum/process_keycode/process_tap_dance.c @@ -0,0 +1,90 @@ +#include "quantum.h" + +static qk_tap_dance_state_t qk_tap_dance_state; + +static void _process_tap_dance_action_pair (qk_tap_dance_state_t *state, + uint16_t kc1, uint16_t kc2) { + uint16_t kc; + + if (state->count == 0) + return; + + kc = (state->count == 1) ? kc1 : kc2; + + register_code (kc); + unregister_code (kc); + + if (state->count >= 2) { + reset_tap_dance (state); + } +} + +static void _process_tap_dance_action_fn (qk_tap_dance_state_t *state, + qk_tap_dance_user_fn_t fn) +{ + fn(state); +} + +void process_tap_dance_action (uint16_t keycode) +{ + uint16_t idx = keycode - QK_TAP_DANCE; + qk_tap_dance_action_t action; + + action = tap_dance_actions[idx]; + + switch (action.type) { + case QK_TAP_DANCE_TYPE_PAIR: + _process_tap_dance_action_pair (&qk_tap_dance_state, + action.pair.kc1, action.pair.kc2); + break; + case QK_TAP_DANCE_TYPE_FN: + _process_tap_dance_action_fn (&qk_tap_dance_state, action.fn); + break; + + default: + break; + } +} + +bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { + bool r = true; + + switch(keycode) { + case QK_TAP_DANCE ... QK_TAP_DANCE_MAX: + if (qk_tap_dance_state.keycode && qk_tap_dance_state.keycode != keycode) { + process_tap_dance_action (qk_tap_dance_state.keycode); + } else { + r = false; + } + + if (record->event.pressed) { + qk_tap_dance_state.keycode = keycode; + qk_tap_dance_state.timer = timer_read (); + qk_tap_dance_state.count++; + } + break; + + default: + if (qk_tap_dance_state.keycode) { + process_tap_dance_action (qk_tap_dance_state.keycode); + + reset_tap_dance (&qk_tap_dance_state); + } + break; + } + + return r; +} + +void matrix_scan_tap_dance () { + if (qk_tap_dance_state.keycode && timer_elapsed (qk_tap_dance_state.timer) > TAPPING_TERM) { + process_tap_dance_action (qk_tap_dance_state.keycode); + + reset_tap_dance (&qk_tap_dance_state); + } +} + +void reset_tap_dance (qk_tap_dance_state_t *state) { + state->keycode = 0; + state->count = 0; +} diff --git a/quantum/process_keycode/process_tap_dance.h b/quantum/process_keycode/process_tap_dance.h new file mode 100644 index 000000000..b9d7c7fcf --- /dev/null +++ b/quantum/process_keycode/process_tap_dance.h @@ -0,0 +1,62 @@ +#ifndef PROCESS_TAP_DANCE_H +#define PROCESS_TAP_DANCE_H + +#ifdef TAP_DANCE_ENABLE + +#include +#include + +typedef struct +{ + uint8_t count; + uint16_t keycode; + uint16_t timer; +} qk_tap_dance_state_t; + +#define TD(n) (QK_TAP_DANCE + n) + +typedef enum +{ + QK_TAP_DANCE_TYPE_PAIR, + QK_TAP_DANCE_TYPE_FN, +} qk_tap_dance_type_t; + +typedef void (*qk_tap_dance_user_fn_t) (qk_tap_dance_state_t *state); + +typedef struct +{ + qk_tap_dance_type_t type; + union { + struct { + uint16_t kc1; + uint16_t kc2; + } pair; + qk_tap_dance_user_fn_t fn; + }; +} qk_tap_dance_action_t; + +#define ACTION_TAP_DANCE_DOUBLE(kc1, kc2) { \ + .type = QK_TAP_DANCE_TYPE_PAIR, \ + .pair = { kc1, kc2 } \ + } + +#define ACTION_TAP_DANCE_FN(user_fn) { \ + .type = QK_TAP_DANCE_TYPE_FN, \ + .fn = user_fn \ + } + +extern const qk_tap_dance_action_t tap_dance_actions[]; + +/* To be used internally */ + +bool process_tap_dance(uint16_t keycode, keyrecord_t *record); +void matrix_scan_tap_dance (void); +void reset_tap_dance (qk_tap_dance_state_t *state); + +#else + +#define TD(n) KC_NO + +#endif + +#endif diff --git a/quantum/process_keycode/process_unicode.c b/quantum/process_keycode/process_unicode.c new file mode 100644 index 000000000..ad5d7f86b --- /dev/null +++ b/quantum/process_keycode/process_unicode.c @@ -0,0 +1,57 @@ +#include "process_unicode.h" + +static uint8_t input_mode; + +uint16_t hex_to_keycode(uint8_t hex) +{ + if (hex == 0x0) { + return KC_0; + } else if (hex < 0xA) { + return KC_1 + (hex - 0x1); + } else { + return KC_A + (hex - 0xA); + } +} + +void set_unicode_mode(uint8_t os_target) +{ + input_mode = os_target; +} + +bool process_unicode(uint16_t keycode, keyrecord_t *record) { + if (keycode > QK_UNICODE && record->event.pressed) { + uint16_t unicode = keycode & 0x7FFF; + switch(input_mode) { + case UC_OSX: + register_code(KC_LALT); + break; + case UC_LNX: + register_code(KC_LCTL); + register_code(KC_LSFT); + register_code(KC_U); + unregister_code(KC_U); + break; + case UC_WIN: + register_code(KC_LALT); + register_code(KC_PPLS); + unregister_code(KC_PPLS); + break; + } + for(int i = 3; i >= 0; i--) { + uint8_t digit = ((unicode >> (i*4)) & 0xF); + register_code(hex_to_keycode(digit)); + unregister_code(hex_to_keycode(digit)); + } + switch(input_mode) { + case UC_OSX: + case UC_WIN: + unregister_code(KC_LALT); + break; + case UC_LNX: + unregister_code(KC_LCTL); + unregister_code(KC_LSFT); + break; + } + } + return true; +} \ No newline at end of file diff --git a/quantum/process_keycode/process_unicode.h b/quantum/process_keycode/process_unicode.h new file mode 100644 index 000000000..ca17f8f66 --- /dev/null +++ b/quantum/process_keycode/process_unicode.h @@ -0,0 +1,122 @@ +#ifndef PROCESS_UNICODE_H +#define PROCESS_UNICODE_H + +#include "quantum.h" + +#define UC_OSX 0 +#define UC_LNX 1 +#define UC_WIN 2 +#define UC_BSD 3 + +void set_unicode_input_mode(uint8_t os_target); + +bool process_unicode(uint16_t keycode, keyrecord_t *record); + +#define UC_BSPC UC(0x0008) + +#define UC_SPC UC(0x0020) + +#define UC_EXLM UC(0x0021) +#define UC_DQUT UC(0x0022) +#define UC_HASH UC(0x0023) +#define UC_DLR UC(0x0024) +#define UC_PERC UC(0x0025) +#define UC_AMPR UC(0x0026) +#define UC_QUOT UC(0x0027) +#define UC_LPRN UC(0x0028) +#define UC_RPRN UC(0x0029) +#define UC_ASTR UC(0x002A) +#define UC_PLUS UC(0x002B) +#define UC_COMM UC(0x002C) +#define UC_DASH UC(0x002D) +#define UC_DOT UC(0x002E) +#define UC_SLSH UC(0x002F) + +#define UC_0 UC(0x0030) +#define UC_1 UC(0x0031) +#define UC_2 UC(0x0032) +#define UC_3 UC(0x0033) +#define UC_4 UC(0x0034) +#define UC_5 UC(0x0035) +#define UC_6 UC(0x0036) +#define UC_7 UC(0x0037) +#define UC_8 UC(0x0038) +#define UC_9 UC(0x0039) + +#define UC_COLN UC(0x003A) +#define UC_SCLN UC(0x003B) +#define UC_LT UC(0x003C) +#define UC_EQL UC(0x003D) +#define UC_GT UC(0x003E) +#define UC_QUES UC(0x003F) +#define UC_AT UC(0x0040) + +#define UC_A UC(0x0041) +#define UC_B UC(0x0042) +#define UC_C UC(0x0043) +#define UC_D UC(0x0044) +#define UC_E UC(0x0045) +#define UC_F UC(0x0046) +#define UC_G UC(0x0047) +#define UC_H UC(0x0048) +#define UC_I UC(0x0049) +#define UC_J UC(0x004A) +#define UC_K UC(0x004B) +#define UC_L UC(0x004C) +#define UC_M UC(0x004D) +#define UC_N UC(0x004E) +#define UC_O UC(0x004F) +#define UC_P UC(0x0050) +#define UC_Q UC(0x0051) +#define UC_R UC(0x0052) +#define UC_S UC(0x0053) +#define UC_T UC(0x0054) +#define UC_U UC(0x0055) +#define UC_V UC(0x0056) +#define UC_W UC(0x0057) +#define UC_X UC(0x0058) +#define UC_Y UC(0x0059) +#define UC_Z UC(0x005A) + +#define UC_LBRC UC(0x005B) +#define UC_BSLS UC(0x005C) +#define UC_RBRC UC(0x005D) +#define UC_CIRM UC(0x005E) +#define UC_UNDR UC(0x005F) + +#define UC_GRV UC(0x0060) + +#define UC_a UC(0x0061) +#define UC_b UC(0x0062) +#define UC_c UC(0x0063) +#define UC_d UC(0x0064) +#define UC_e UC(0x0065) +#define UC_f UC(0x0066) +#define UC_g UC(0x0067) +#define UC_h UC(0x0068) +#define UC_i UC(0x0069) +#define UC_j UC(0x006A) +#define UC_k UC(0x006B) +#define UC_l UC(0x006C) +#define UC_m UC(0x006D) +#define UC_n UC(0x006E) +#define UC_o UC(0x006F) +#define UC_p UC(0x0070) +#define UC_q UC(0x0071) +#define UC_r UC(0x0072) +#define UC_s UC(0x0073) +#define UC_t UC(0x0074) +#define UC_u UC(0x0075) +#define UC_v UC(0x0076) +#define UC_w UC(0x0077) +#define UC_x UC(0x0078) +#define UC_y UC(0x0079) +#define UC_z UC(0x007A) + +#define UC_LCBR UC(0x007B) +#define UC_PIPE UC(0x007C) +#define UC_RCBR UC(0x007D) +#define UC_TILD UC(0x007E) +#define UC_DEL UC(0x007F) + +#endif \ No newline at end of file diff --git a/quantum/quantum.c b/quantum/quantum.c index 9c0f9691f..c0580e0aa 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -15,54 +15,6 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { return true; } -__attribute__ ((weak)) -void leader_start(void) {} - -__attribute__ ((weak)) -void leader_end(void) {} - -uint8_t starting_note = 0x0C; -int offset = 7; - - -#ifdef AUDIO_ENABLE - bool music_activated = false; - - // music sequencer - static bool music_sequence_recording = false; - static bool music_sequence_playing = false; - static float music_sequence[16] = {0}; - static uint8_t music_sequence_count = 0; - static uint8_t music_sequence_position = 0; - - static uint16_t music_sequence_timer = 0; - static uint16_t music_sequence_interval = 100; - -#endif - -#ifdef MIDI_ENABLE - bool midi_activated = false; -#endif - -// Leader key stuff -bool leading = false; -uint16_t leader_time = 0; - -uint16_t leader_sequence[5] = {0, 0, 0, 0, 0}; -uint8_t leader_sequence_size = 0; - -// Chording stuff -#define CHORDING_MAX 4 -bool chording = false; - -uint8_t chord_keys[CHORDING_MAX] = {0}; -uint8_t chord_key_count = 0; -uint8_t chord_key_down = 0; - -#ifdef UNICODE_ENABLE - static uint8_t input_mode; -#endif - // Shift / paren setup #ifndef LSPO_KEY @@ -74,48 +26,6 @@ uint8_t chord_key_down = 0; static bool shift_interrupted[2] = {0, 0}; -bool keys_chord(uint8_t keys[]) { - uint8_t keys_size = sizeof(keys)/sizeof(keys[0]); - bool pass = true; - uint8_t in = 0; - for (uint8_t i = 0; i < chord_key_count; i++) { - bool found = false; - for (uint8_t j = 0; j < keys_size; j++) { - if (chord_keys[i] == (keys[j] & 0xFF)) { - in++; // detects key in chord - found = true; - break; - } - } - if (found) - continue; - if (chord_keys[i] != 0) { - pass = false; // makes sure rest are blank - } - } - return (pass && (in == keys_size)); -} - -#ifdef UNICODE_ENABLE - -uint16_t hex_to_keycode(uint8_t hex) -{ - if (hex == 0x0) { - return KC_0; - } else if (hex < 0xA) { - return KC_1 + (hex - 0x1); - } else { - return KC_A + (hex - 0xA); - } -} - -void set_unicode_mode(uint8_t os_target) -{ - input_mode = os_target; -} - -#endif - bool process_record_quantum(keyrecord_t *record) { /* This gets the keycode from the key pressed */ @@ -136,9 +46,6 @@ bool process_record_quantum(keyrecord_t *record) { keycode = keymap_key_to_keycode(layer_switch_get_layer(key), key); #endif - if (!process_record_kb(keycode, record)) - return false; - // This is how you use actions here // if (keycode == KC_LEAD) { // action_t action; @@ -147,278 +54,30 @@ bool process_record_quantum(keyrecord_t *record) { // return false; // } + if (!( + process_record_kb(keycode, record) && #ifdef MIDI_ENABLE - if (keycode == MI_ON && record->event.pressed) { - midi_activated = true; - music_scale_user(); - return false; - } - - if (keycode == MI_OFF && record->event.pressed) { - midi_activated = false; - midi_send_cc(&midi_device, 0, 0x7B, 0); - return false; - } - - if (midi_activated) { - if (record->event.key.col == (MATRIX_COLS - 1) && record->event.key.row == (MATRIX_ROWS - 1)) { - if (record->event.pressed) { - starting_note++; // Change key - midi_send_cc(&midi_device, 0, 0x7B, 0); - } - return false; - } - if (record->event.key.col == (MATRIX_COLS - 2) && record->event.key.row == (MATRIX_ROWS - 1)) { - if (record->event.pressed) { - starting_note--; // Change key - midi_send_cc(&midi_device, 0, 0x7B, 0); - } - return false; - } - if (record->event.key.col == (MATRIX_COLS - 3) && record->event.key.row == (MATRIX_ROWS - 1) && record->event.pressed) { - offset++; // Change scale - midi_send_cc(&midi_device, 0, 0x7B, 0); - return false; - } - if (record->event.key.col == (MATRIX_COLS - 4) && record->event.key.row == (MATRIX_ROWS - 1) && record->event.pressed) { - offset--; // Change scale - midi_send_cc(&midi_device, 0, 0x7B, 0); - return false; - } - // basic - // uint8_t note = (starting_note + SCALE[record->event.key.col + offset])+12*(MATRIX_ROWS - record->event.key.row); - // advanced - // uint8_t note = (starting_note + record->event.key.col + offset)+12*(MATRIX_ROWS - record->event.key.row); - // guitar - uint8_t note = (starting_note + record->event.key.col + offset)+5*(MATRIX_ROWS - record->event.key.row); - // violin - // uint8_t note = (starting_note + record->event.key.col + offset)+7*(MATRIX_ROWS - record->event.key.row); - - if (record->event.pressed) { - // midi_send_noteon(&midi_device, record->event.key.row, starting_note + SCALE[record->event.key.col], 127); - midi_send_noteon(&midi_device, 0, note, 127); - } else { - // midi_send_noteoff(&midi_device, record->event.key.row, starting_note + SCALE[record->event.key.col], 127); - midi_send_noteoff(&midi_device, 0, note, 127); - } - - if (keycode < 0xFF) // ignores all normal keycodes, but lets RAISE, LOWER, etc through - return false; - } + process_midi(keycode, record) && #endif - #ifdef AUDIO_ENABLE - if (keycode == AU_ON && record->event.pressed) { - audio_on(); - return false; - } - - if (keycode == AU_OFF && record->event.pressed) { - audio_off(); - return false; - } - - if (keycode == AU_TOG && record->event.pressed) { - if (is_audio_on()) - { - audio_off(); - } - else - { - audio_on(); - } - return false; - } - - if (keycode == MU_ON && record->event.pressed) { - music_on(); - return false; - } - - if (keycode == MU_OFF && record->event.pressed) { - music_off(); - return false; - } - - if (keycode == MU_TOG && record->event.pressed) { - if (music_activated) - { - music_off(); - } - else - { - music_on(); - } - return false; - } - - if (keycode == MUV_IN && record->event.pressed) { - voice_iterate(); - music_scale_user(); - return false; - } - - if (keycode == MUV_DE && record->event.pressed) { - voice_deiterate(); - music_scale_user(); - return false; - } - - if (music_activated) { - - if (keycode == KC_LCTL && record->event.pressed) { // Start recording - stop_all_notes(); - music_sequence_recording = true; - music_sequence_playing = false; - music_sequence_count = 0; - return false; - } - - if (keycode == KC_LALT && record->event.pressed) { // Stop recording/playing - stop_all_notes(); - music_sequence_recording = false; - music_sequence_playing = false; - return false; - } - - if (keycode == KC_LGUI && record->event.pressed) { // Start playing - stop_all_notes(); - music_sequence_recording = false; - music_sequence_playing = true; - music_sequence_position = 0; - music_sequence_timer = 0; - return false; - } - - if (keycode == KC_UP) { - if (record->event.pressed) - music_sequence_interval-=10; - return false; - } - - if (keycode == KC_DOWN) { - if (record->event.pressed) - music_sequence_interval+=10; - return false; - } - - float freq = ((float)220.0)*pow(2.0, -5.0)*pow(2.0,(starting_note + SCALE[record->event.key.col + offset])/12.0+(MATRIX_ROWS - record->event.key.row)); - if (record->event.pressed) { - play_note(freq, 0xF); - if (music_sequence_recording) { - music_sequence[music_sequence_count] = freq; - music_sequence_count++; - } - } else { - stop_note(freq); - } - - if (keycode < 0xFF) // ignores all normal keycodes, but lets RAISE, LOWER, etc through - return false; - } + process_music(keycode, record) && #endif - -#ifndef DISABLE_LEADER - // Leader key set-up - if (record->event.pressed) { - if (!leading && keycode == KC_LEAD) { - leader_start(); - leading = true; - leader_time = timer_read(); - leader_sequence_size = 0; - leader_sequence[0] = 0; - leader_sequence[1] = 0; - leader_sequence[2] = 0; - leader_sequence[3] = 0; - leader_sequence[4] = 0; - return false; - } - if (leading && timer_elapsed(leader_time) < LEADER_TIMEOUT) { - leader_sequence[leader_sequence_size] = keycode; - leader_sequence_size++; - return false; - } - } -#endif - -#define DISABLE_CHORDING -#ifndef DISABLE_CHORDING - - if (keycode >= QK_CHORDING && keycode <= QK_CHORDING_MAX) { - if (record->event.pressed) { - if (!chording) { - chording = true; - for (uint8_t i = 0; i < CHORDING_MAX; i++) - chord_keys[i] = 0; - chord_key_count = 0; - chord_key_down = 0; - } - chord_keys[chord_key_count] = (keycode & 0xFF); - chord_key_count++; - chord_key_down++; - return false; - } else { - if (chording) { - chord_key_down--; - if (chord_key_down == 0) { - chording = false; - // Chord Dictionary - if (keys_chord((uint8_t[]){KC_ENTER, KC_SPACE})) { - register_code(KC_A); - unregister_code(KC_A); - return false; - } - for (uint8_t i = 0; i < chord_key_count; i++) { - register_code(chord_keys[i]); - unregister_code(chord_keys[i]); - return false; - } - } - } - } - } - -#endif - -#ifdef UNICODE_ENABLE - - if (keycode > QK_UNICODE && record->event.pressed) { - uint16_t unicode = keycode & 0x7FFF; - switch(input_mode) { - case UC_OSX: - register_code(KC_LALT); - break; - case UC_LNX: - register_code(KC_LCTL); - register_code(KC_LSFT); - register_code(KC_U); - unregister_code(KC_U); - break; - case UC_WIN: - register_code(KC_LALT); - register_code(KC_PPLS); - unregister_code(KC_PPLS); - break; - } - for(int i = 3; i >= 0; i--) { - uint8_t digit = ((unicode >> (i*4)) & 0xF); - register_code(hex_to_keycode(digit)); - unregister_code(hex_to_keycode(digit)); - } - switch(input_mode) { - case UC_OSX: - case UC_WIN: - unregister_code(KC_LALT); - break; - case UC_LNX: - unregister_code(KC_LCTL); - unregister_code(KC_LSFT); - break; - } + #ifdef TAP_DANCE_ENABLE + process_tap_dance(keycode, record) && + #endif + #ifndef DISABLE_LEADER + process_leader(keycode, record) && + #endif + #ifndef DISABLE_CHORDING + process_chording(keycode, record) && + #endif + #ifdef UNICODE_ENABLE + process_unicode(keycode, record) && + #endif + true)) { + return false; } -#endif - // Shift / paren setup switch(keycode) { @@ -657,46 +316,15 @@ void matrix_init_quantum() { void matrix_scan_quantum() { #ifdef AUDIO_ENABLE - if (music_sequence_playing) { - if ((music_sequence_timer == 0) || (timer_elapsed(music_sequence_timer) > music_sequence_interval)) { - music_sequence_timer = timer_read(); - stop_note(music_sequence[(music_sequence_position - 1 < 0)?(music_sequence_position - 1 + music_sequence_count):(music_sequence_position - 1)]); - play_note(music_sequence[music_sequence_position], 0xF); - music_sequence_position = (music_sequence_position + 1) % music_sequence_count; - } - } - + matrix_scan_music(); #endif + #ifdef TAP_DANCE_ENABLE + matrix_scan_tap_dance(); + #endif matrix_scan_kb(); } -#ifdef AUDIO_ENABLE - bool is_music_on(void) { - return (music_activated != 0); - } - - void music_toggle(void) { - if (!music_activated) { - music_on(); - } else { - music_off(); - } - } - - void music_on(void) { - music_activated = 1; - music_on_user(); - } - - void music_off(void) { - music_activated = 0; - stop_all_notes(); - } - -#endif - - #if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_PIN) static const uint8_t backlight_pin = BACKLIGHT_PIN; @@ -1048,13 +676,4 @@ void startup_user() {} __attribute__ ((weak)) void shutdown_user() {} -__attribute__ ((weak)) -void music_on_user() {} - -__attribute__ ((weak)) -void audio_on_user() {} - -__attribute__ ((weak)) -void music_scale_user() {} - //------------------------------------------------------------------------------ diff --git a/quantum/quantum.h b/quantum/quantum.h index 7795294d5..ad180c71f 100644 --- a/quantum/quantum.h +++ b/quantum/quantum.h @@ -10,15 +10,6 @@ #ifdef RGBLIGHT_ENABLE #include "rgblight.h" #endif -#ifdef AUDIO_ENABLE - #include "audio.h" -#endif -#ifdef MIDI_ENABLE - #include -#endif -#ifdef UNICODE_ENABLE - #include "unicode.h" -#endif #include "action_layer.h" #include "eeconfig.h" @@ -32,42 +23,38 @@ #include "led.h" #include "action_util.h" + extern uint32_t default_layer_state; #ifndef NO_ACTION_LAYER extern uint32_t layer_state; #endif +#ifdef MIDI_ENABLE + #include + #include "process_midi.h" +#endif + #ifdef AUDIO_ENABLE - bool music_activated; + #include "audio.h" + #include "process_music.h" #endif -#ifdef UNICODE_ENABLE - #define UC_OSX 0 - #define UC_LNX 1 - #define UC_WIN 2 - #define UC_BSD 3 +#ifndef DISABLE_LEADER + #include "process_leader.h" +#endif - void set_unicode_input_mode(uint8_t os_target); +#define DISABLE_CHORDING +#ifndef DISABLE_CHORDING + #include "process_chording.h" #endif -#ifndef DISABLE_LEADER - void leader_start(void); - void leader_end(void); - - #ifndef LEADER_TIMEOUT - #define LEADER_TIMEOUT 200 - #endif - #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) - #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) - #define SEQ_THREE_KEYS(key1, key2, key3) if (leader_sequence[0] == (key1) && leader_sequence[1] == (key2) && leader_sequence[2] == (key3) && leader_sequence[3] == 0 && leader_sequence[4] == 0) - #define SEQ_FOUR_KEYS(key1, key2, key3, key4) if (leader_sequence[0] == (key1) && leader_sequence[1] == (key2) && leader_sequence[2] == (key3) && leader_sequence[3] == (key4) && leader_sequence[4] == 0) - #define SEQ_FIVE_KEYS(key1, key2, key3, key4, key5) if (leader_sequence[0] == (key1) && leader_sequence[1] == (key2) && leader_sequence[2] == (key3) && leader_sequence[3] == (key4) && leader_sequence[4] == (key5)) - - #define LEADER_EXTERNS() extern bool leading; extern uint16_t leader_time; extern uint16_t leader_sequence[5]; extern uint8_t leader_sequence_size - #define LEADER_DICTIONARY() if (leading && timer_elapsed(leader_time) > LEADER_TIMEOUT) +#ifdef UNICODE_ENABLE + #include "process_unicode.h" #endif +#include "process_tap_dance.h" + #define SEND_STRING(str) send_string(PSTR(str)) void send_string(const char *str); @@ -84,16 +71,8 @@ bool process_action_kb(keyrecord_t *record); bool process_record_kb(uint16_t keycode, keyrecord_t *record); bool process_record_user(uint16_t keycode, keyrecord_t *record); -bool is_music_on(void); -void music_toggle(void); -void music_on(void); -void music_off(void); - void startup_user(void); void shutdown_user(void); -void audio_on_user(void); -void music_on_user(void); -void music_scale_user(void); #ifdef BACKLIGHT_ENABLE void backlight_init_ports(void); diff --git a/quantum/unicode.h b/quantum/unicode.h deleted file mode 100644 index 756ec8bc3..000000000 --- a/quantum/unicode.h +++ /dev/null @@ -1,128 +0,0 @@ -/* -Copyright 2016 Jack Humbert -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -#ifndef UNICODE_H -#define UNICODE_H - -#include "quantum.h" -#include - -#define UC_BSPC UC(0x0008) - -#define UC_SPC UC(0x0020) - -#define UC_EXLM UC(0x0021) -#define UC_DQUT UC(0x0022) -#define UC_HASH UC(0x0023) -#define UC_DLR UC(0x0024) -#define UC_PERC UC(0x0025) -#define UC_AMPR UC(0x0026) -#define UC_QUOT UC(0x0027) -#define UC_LPRN UC(0x0028) -#define UC_RPRN UC(0x0029) -#define UC_ASTR UC(0x002A) -#define UC_PLUS UC(0x002B) -#define UC_COMM UC(0x002C) -#define UC_DASH UC(0x002D) -#define UC_DOT UC(0x002E) -#define UC_SLSH UC(0x002F) - -#define UC_0 UC(0x0030) -#define UC_1 UC(0x0031) -#define UC_2 UC(0x0032) -#define UC_3 UC(0x0033) -#define UC_4 UC(0x0034) -#define UC_5 UC(0x0035) -#define UC_6 UC(0x0036) -#define UC_7 UC(0x0037) -#define UC_8 UC(0x0038) -#define UC_9 UC(0x0039) - -#define UC_COLN UC(0x003A) -#define UC_SCLN UC(0x003B) -#define UC_LT UC(0x003C) -#define UC_EQL UC(0x003D) -#define UC_GT UC(0x003E) -#define UC_QUES UC(0x003F) -#define UC_AT UC(0x0040) - -#define UC_A UC(0x0041) -#define UC_B UC(0x0042) -#define UC_C UC(0x0043) -#define UC_D UC(0x0044) -#define UC_E UC(0x0045) -#define UC_F UC(0x0046) -#define UC_G UC(0x0047) -#define UC_H UC(0x0048) -#define UC_I UC(0x0049) -#define UC_J UC(0x004A) -#define UC_K UC(0x004B) -#define UC_L UC(0x004C) -#define UC_M UC(0x004D) -#define UC_N UC(0x004E) -#define UC_O UC(0x004F) -#define UC_P UC(0x0050) -#define UC_Q UC(0x0051) -#define UC_R UC(0x0052) -#define UC_S UC(0x0053) -#define UC_T UC(0x0054) -#define UC_U UC(0x0055) -#define UC_V UC(0x0056) -#define UC_W UC(0x0057) -#define UC_X UC(0x0058) -#define UC_Y UC(0x0059) -#define UC_Z UC(0x005A) - -#define UC_LBRC UC(0x005B) -#define UC_BSLS UC(0x005C) -#define UC_RBRC UC(0x005D) -#define UC_CIRM UC(0x005E) -#define UC_UNDR UC(0x005F) - -#define UC_GRV UC(0x0060) - -#define UC_a UC(0x0061) -#define UC_b UC(0x0062) -#define UC_c UC(0x0063) -#define UC_d UC(0x0064) -#define UC_e UC(0x0065) -#define UC_f UC(0x0066) -#define UC_g UC(0x0067) -#define UC_h UC(0x0068) -#define UC_i UC(0x0069) -#define UC_j UC(0x006A) -#define UC_k UC(0x006B) -#define UC_l UC(0x006C) -#define UC_m UC(0x006D) -#define UC_n UC(0x006E) -#define UC_o UC(0x006F) -#define UC_p UC(0x0070) -#define UC_q UC(0x0071) -#define UC_r UC(0x0072) -#define UC_s UC(0x0073) -#define UC_t UC(0x0074) -#define UC_u UC(0x0075) -#define UC_v UC(0x0076) -#define UC_w UC(0x0077) -#define UC_x UC(0x0078) -#define UC_y UC(0x0079) -#define UC_z UC(0x007A) - -#define UC_LCBR UC(0x007B) -#define UC_PIPE UC(0x007C) -#define UC_RCBR UC(0x007D) -#define UC_TILD UC(0x007E) -#define UC_DEL UC(0x007F) - -#endif \ No newline at end of file -- cgit v1.2.3-24-g4f1b From 197f152dee834a737cd820f2a95d1ade98be4898 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Wed, 29 Jun 2016 18:29:20 -0400 Subject: adds random base64 character generator --- quantum/quantum.c | 35 +++++++++++++++++++++++++++++++++++ quantum/quantum.h | 3 +++ 2 files changed, 38 insertions(+) (limited to 'quantum') diff --git a/quantum/quantum.c b/quantum/quantum.c index c0580e0aa..224bfb795 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -307,6 +307,41 @@ void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3) { } } +void tap_random_base64(void) { + uint8_t key = (TCNT0 + TCNT1 + TCNT3 + TCNT4) % 64; + // uint8_t key = rand() % 64; + switch (key) { + case 0 ... 25: + register_code(KC_LSFT); + register_code(key + KC_A); + unregister_code(key + KC_A); + unregister_code(KC_LSFT); + break; + case 26 ... 51: + register_code(key - 26 + KC_A); + unregister_code(key - 26 + KC_A); + break; + case 52: + register_code(KC_0); + unregister_code(KC_0); + break; + case 53 ... 61: + register_code(key - 53 + KC_1); + unregister_code(key - 53 + KC_1); + break; + case 62: + register_code(KC_LSFT); + register_code(KC_EQL); + unregister_code(KC_EQL); + unregister_code(KC_LSFT); + break; + case 63: + register_code(KC_SLSH); + unregister_code(KC_SLSH); + break; + } +} + void matrix_init_quantum() { #ifdef BACKLIGHT_ENABLE backlight_init_ports(); diff --git a/quantum/quantum.h b/quantum/quantum.h index ad180c71f..dd290ac00 100644 --- a/quantum/quantum.h +++ b/quantum/quantum.h @@ -60,6 +60,9 @@ void send_string(const char *str); // For tri-layer void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3); + +void tap_random_base64(void); + #define IS_LAYER_ON(layer) (layer_state & (1UL << (layer))) #define IS_LAYER_OFF(layer) (~layer_state & (1UL << (layer))) -- cgit v1.2.3-24-g4f1b From 60fd885a6e540509baa2193932e15caeaeb8f4c5 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Wed, 29 Jun 2016 18:35:29 -0400 Subject: rand supports other chips --- quantum/quantum.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'quantum') diff --git a/quantum/quantum.c b/quantum/quantum.c index 224bfb795..270b976e3 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -308,8 +308,11 @@ void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3) { } void tap_random_base64(void) { - uint8_t key = (TCNT0 + TCNT1 + TCNT3 + TCNT4) % 64; - // uint8_t key = rand() % 64; + #if defined(__AVR_ATmega32U4__) + uint8_t key = (TCNT0 + TCNT1 + TCNT3 + TCNT4) % 64; + #else + uint8_t key = rand() % 64; + #endif switch (key) { case 0 ... 25: register_code(KC_LSFT); -- cgit v1.2.3-24-g4f1b From 8125cdb88ce1201fcfd16ed4c5313222ef4c230c Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Wed, 29 Jun 2016 18:36:52 -0400 Subject: gets rid of rand warning [skip ci] --- quantum/quantum.h | 1 + 1 file changed, 1 insertion(+) (limited to 'quantum') diff --git a/quantum/quantum.h b/quantum/quantum.h index dd290ac00..9b5d310bd 100644 --- a/quantum/quantum.h +++ b/quantum/quantum.h @@ -22,6 +22,7 @@ #include #include "led.h" #include "action_util.h" +#include extern uint32_t default_layer_state; -- cgit v1.2.3-24-g4f1b From 4d4f7684e684bec319f166121463a88cd4a62703 Mon Sep 17 00:00:00 2001 From: fredizzimo Date: Fri, 1 Jul 2016 17:04:53 +0300 Subject: Add ChibiOS support for QMK (#465) * Modularity and gcc warnings fixes. * Add ChibiOS support (USB stack + support files). * Make usb_main more USB_DRIVER #define independent. * Move chibios to tool. * Implement jump-to-bootloader. * Small updates. * Fix bootloader-jump compiling. * Move AVR specific sleep_led.c into avr. * Add basic sleep_led for chibios. * Update chibios README. * NKRO fixes. * Rename some Makefile defines. * Move STM32 bootloader address config to separate .h file. * Add ARM Teensies bootloader code. * Fix chibios/usb_main GET_REPORT handing. * Add missing #include to keymap.c. * Make bootmagic.c code portable (_delay_ms -> wait_ms). * Move declaration of keymap_config. Should really not declare variables in .h files - since it's included in different .c files, a proper linker then complains that the same variable is declared more than once (once for each .c file that the offending .h is included in). * Add eeprom support for chibios/kinetis. * Rename chibios example keyboard. * Move chibios/cortex selection to local Makefiles. * Chibios: use WFI in idle. WIP suspend stuff. * ChibiOS/kinetis: sending remote wakeup. * ChibiOS/STM32: send remote wakeup. * Fix report size of boot protocol. * Fix drop key stroke Keyboard report should be checked if its transfer finishs successfully. Otherwise key stroke can be missing when other key event occurs before the last report transfer is done. Boot protocol 10ms interval probably causes this problem in case it receives key events in a row within the period. NKRO protocol suffers less or nothing due to its interval 1ms. * Chibios/usb_main: rename a variable for clarity. * Add correct chibios/bootloader_jump for infinity KB. * ChibiOS: make reset request more CMSISy. * Chibios: Add breathing sleep LED on Kinetis MCUs. * ChibiOS: Update infinity bootloader code to match updated ChibiOS. * ChibiOS: prettify/document sleep_led code. * Chibios: Remove the wait in the main loop. * Add maple mini code. * Do timeout when writing to CONSOLE EP queue. Fixes TMK bug #266. * Chibios: add 'core/protocol' to the makefiles' search path. * Chibios: Update to new USB API. * Chibios: add more guards for transmitting (fix a deadlock bug). * Add update for chibios in README * Chibios: Fix a HardFault bug (wait after start). * Chibios: cleanup usb_main code. * Chibios: Revert common.mk change (fix AVR linking problem). * core: Fix chibios user compile options Compile options can be defined in project Makefile such as UDEFS, UADEFS, UINCDIR, ULIBDIR and ULIBS. * Sysv format for ChibiOS arm-none-eabi-size Some new patches to ChibiOS puts heap as it's own section. So the berkeley format is now useless, as the heap will be included in the BSS report. The sysv format displays the bss size correctly. * Fix hard-coded path of CHIBIOS * Add support for new version of ChibiOS and Contrib The Kinetis support has moved to a separate Contrib repository in the newest version of Chibios. There has also been some structure changes. So this adds support for those, while maintaining back- wards compability. * Update ChibiOS instructions * Chibios: implement sleep LED for STM32. * Chibios: Update the main chibios README. * Chibios: fix STM32_BOOTLOADER_ADDRESS name. * Chibios: make the default bootloader_jump redefinable (weak). * Chibios: disable LTO (link-time optimisation). With LTO enabled, sometimes things fail for mysterious reasons (e.g. bootloader jump on WF with LEDs enabled), just because the linker optimisation is too aggressive. * Chibios: add default location for chibios-contrib. * ChibiOS: update mk to match chibios/master. * ChibiOS: update instructions.md. * Add chibi_onekey example. * Add comments to chibi_onekey Makefile. * Rename some Makefile defines. * Move STM32 bootloader address config to separate .h file. * Rename chibios example keyboard. * Move chibios/cortex selection to local Makefiles. * Add Teensy LC onekey example. * Chibios: use WFI in idle. WIP suspend stuff. * Update chibi/teensy instructions. * Update chibios/Teensy instructions. * Add infinity_chibios * Add keymap_hasu.c * Infinity_chibios: select correct bootloader_jump. * Infinity_chibios: improve comments. * Add generic STM32F103C8T6 example. * Add maple mini code. * STM32F103x fixes. * Add maple mini pinout pic. * Chibios: updates for 3.0.4 git. * Chibios: rename example stm32_onekey -> stm32_f072_onekey. * Chibios: add makefiles for Teensy 3.x examples. * Chibios: update Teensy 3.x instructions. * Chibios: Tsy LC is cortex-m0plus. * Chibios: add more guards for transmitting (fix a deadlock bug). * Change README for chibios * Chibios: update examples to current chibios git. Match the changes in mainline chibios: - update chconf.h - update supplied ld scripts structure - update Teensy instructions (switch to official chibios and introduce contrib) * Add ChibiOS and ChibiOS-Contrib submodules Also fix the makefile path for them. * Moves chibios keyboards to keyboards folder * First version of ChibiOS compilation Only the stm32_f072_onkey keyboard is ported at the moment. It compiles, but still doesn't link. * More chibios fixes It now compiles without warnings and links * Move the teensy_lc_onekey to the keyboards folder * Clean up the make file rule structure * Remove keymap_fn_to_action * Update more ChibiOS keyboards to QMK Most of them does not compile at the moment though. * Use older version of Chibios libraries The newest ones have problems with compilation * Remove USB_UNCONFIGURED event It isn't present in the older version of ChibiOS * Fix the infinity_chibios compilation * Fix potentially uninitialized variable * Add missing include * Fix the ChibiOS makefile * Fix some Chibios keyboard compilation * Revert the rules.mk file back to master version * Combine the chibios and AVR makefiles With just the required overrides in the respective platform specific one. * Slight makefile restrucuring Platform specific compiler options * Move avr specific targets out of the main rules * Fix ChibiOS objcopy The ChibiOS objcopy needs different parameters, so the parameters are moved to the corresponding platform rule file * Fix the objcopy for real this time The comands were moved around, so chibios used avr and the ohter way around. Also change the objsize output format * Fix the thumb flags * Fix the infinity hasu keymap * Per platform cpp flags * Add gcc-arm-none-eabi package to travis * Add arm-none-eabi-newlib to travis * Fix the name of the libnewlib-arm-none-eabi lib * Fix the ChibiOS paths So that they are properly relative, and builds don't generate extra folders * Fix the board path of stm32_f103_onekey * Only consider folders with Makefiles as subproject --- quantum/keycode_config.h | 2 +- quantum/keymap.c | 167 --------------------------------------------- quantum/keymap.h | 11 ++- quantum/keymap_common.c | 171 +++++++++++++++++++++++++++++++++++++++++++++++ quantum/matrix.c | 2 + quantum/quantum.c | 2 +- quantum/quantum.h | 8 ++- 7 files changed, 188 insertions(+), 175 deletions(-) delete mode 100644 quantum/keymap.c create mode 100644 quantum/keymap_common.c (limited to 'quantum') diff --git a/quantum/keycode_config.h b/quantum/keycode_config.h index c41c08706..6216eefc9 100644 --- a/quantum/keycode_config.h +++ b/quantum/keycode_config.h @@ -18,4 +18,4 @@ typedef union { }; } keymap_config_t; -keymap_config_t keymap_config; \ No newline at end of file +extern keymap_config_t keymap_config; diff --git a/quantum/keymap.c b/quantum/keymap.c deleted file mode 100644 index 74fd518c9..000000000 --- a/quantum/keymap.c +++ /dev/null @@ -1,167 +0,0 @@ -/* -Copyright 2012,2013 Jun Wako - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -#include "keymap.h" -#include "report.h" -#include "keycode.h" -#include "action_layer.h" -#include -#include "action.h" -#include "action_macro.h" -#include "debug.h" -#include "backlight.h" -#include "quantum.h" - -#ifdef MIDI_ENABLE - #include "keymap_midi.h" -#endif - -extern keymap_config_t keymap_config; - -#include -#include - -/* converts key to action */ -action_t action_for_key(uint8_t layer, keypos_t key) -{ - // 16bit keycodes - important - uint16_t keycode = keymap_key_to_keycode(layer, key); - - // keycode remapping - keycode = keycode_config(keycode); - - action_t action; - uint8_t action_layer, when, mod; - - switch (keycode) { - case KC_FN0 ... KC_FN31: - action.code = pgm_read_word(&fn_actions[FN_INDEX(keycode)]); - break; - case KC_A ... KC_EXSEL: - case KC_LCTRL ... KC_RGUI: - action.code = ACTION_KEY(keycode); - break; - case KC_SYSTEM_POWER ... KC_SYSTEM_WAKE: - action.code = ACTION_USAGE_SYSTEM(KEYCODE2SYSTEM(keycode)); - break; - case KC_AUDIO_MUTE ... KC_WWW_FAVORITES: - action.code = ACTION_USAGE_CONSUMER(KEYCODE2CONSUMER(keycode)); - break; - case KC_MS_UP ... KC_MS_ACCEL2: - action.code = ACTION_MOUSEKEY(keycode); - break; - case KC_TRNS: - action.code = ACTION_TRANSPARENT; - break; - case QK_MODS ... QK_MODS_MAX: ; - // Has a modifier - // Split it up - action.code = ACTION_MODS_KEY(keycode >> 8, keycode & 0xFF); // adds modifier to key - break; - case QK_FUNCTION ... QK_FUNCTION_MAX: ; - // Is a shortcut for function action_layer, pull last 12bits - // This means we have 4,096 FN macros at our disposal - action.code = pgm_read_word(&fn_actions[(int)keycode & 0xFFF]); - break; - case QK_MACRO ... QK_MACRO_MAX: - action.code = ACTION_MACRO(keycode & 0xFF); - break; - case QK_LAYER_TAP ... QK_LAYER_TAP_MAX: - action.code = ACTION_LAYER_TAP_KEY((keycode >> 0x8) & 0xF, keycode & 0xFF); - break; - case QK_TO ... QK_TO_MAX: ; - // Layer set "GOTO" - when = (keycode >> 0x4) & 0x3; - action_layer = keycode & 0xF; - action.code = ACTION_LAYER_SET(action_layer, when); - break; - case QK_MOMENTARY ... QK_MOMENTARY_MAX: ; - // Momentary action_layer - action_layer = keycode & 0xFF; - action.code = ACTION_LAYER_MOMENTARY(action_layer); - break; - case QK_DEF_LAYER ... QK_DEF_LAYER_MAX: ; - // Set default action_layer - action_layer = keycode & 0xFF; - action.code = ACTION_DEFAULT_LAYER_SET(action_layer); - break; - case QK_TOGGLE_LAYER ... QK_TOGGLE_LAYER_MAX: ; - // Set toggle - action_layer = keycode & 0xFF; - action.code = ACTION_LAYER_TOGGLE(action_layer); - break; - case QK_ONE_SHOT_LAYER ... QK_ONE_SHOT_LAYER_MAX: ; - // OSL(action_layer) - One-shot action_layer - action_layer = keycode & 0xFF; - action.code = ACTION_LAYER_ONESHOT(action_layer); - break; - case QK_ONE_SHOT_MOD ... QK_ONE_SHOT_MOD_MAX: ; - // OSM(mod) - One-shot mod - mod = keycode & 0xFF; - action.code = ACTION_MODS_ONESHOT(mod); - break; - case QK_MOD_TAP ... QK_MOD_TAP_MAX: - action.code = ACTION_MODS_TAP_KEY((keycode >> 0x8) & 0xF, keycode & 0xFF); - break; - #ifdef BACKLIGHT_ENABLE - case BL_0 ... BL_15: - action.code = ACTION_BACKLIGHT_LEVEL(keycode - BL_0); - break; - case BL_DEC: - action.code = ACTION_BACKLIGHT_DECREASE(); - break; - case BL_INC: - action.code = ACTION_BACKLIGHT_INCREASE(); - break; - case BL_TOGG: - action.code = ACTION_BACKLIGHT_TOGGLE(); - break; - case BL_STEP: - action.code = ACTION_BACKLIGHT_STEP(); - break; - #endif - default: - action.code = ACTION_NO; - break; - } - return action; -} - -__attribute__ ((weak)) -const uint16_t PROGMEM fn_actions[] = { - -}; - -/* Macro */ -__attribute__ ((weak)) -const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) -{ - return MACRO_NONE; -} - -/* Function */ -__attribute__ ((weak)) -void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) -{ -} - -/* translates key to keycode */ -uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key) -{ - // Read entire word (16bits) - return pgm_read_word(&keymaps[(layer)][(key.row)][(key.col)]); -} diff --git a/quantum/keymap.h b/quantum/keymap.h index a994f4f2e..73f99f821 100644 --- a/quantum/keymap.h +++ b/quantum/keymap.h @@ -21,7 +21,9 @@ along with this program. If not, see . #include #include #include "action.h" +#if defined(__AVR__) #include +#endif #include "keycode.h" #include "action_macro.h" #include "report.h" @@ -30,12 +32,15 @@ along with this program. If not, see . #include "debug.h" #include "keycode_config.h" +// ChibiOS uses RESET in its FlagStatus enumeration +// Therefore define it as QK_RESET here, to avoid name collision +#if defined(PROTOCOL_CHIBIOS) +#define RESET QK_RESET +#endif + /* translates key to keycode */ uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key); -/* translates Fn keycode to action */ -action_t keymap_fn_to_action(uint16_t keycode); - extern const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS]; extern const uint16_t fn_actions[]; diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c new file mode 100644 index 000000000..76872ac59 --- /dev/null +++ b/quantum/keymap_common.c @@ -0,0 +1,171 @@ +/* +Copyright 2012,2013 Jun Wako + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include "keymap.h" +#include "report.h" +#include "keycode.h" +#include "action_layer.h" +#if defined(__AVR__) +#include +#include +#endif +#include "action.h" +#include "action_macro.h" +#include "debug.h" +#include "backlight.h" +#include "quantum.h" + +#ifdef MIDI_ENABLE + #include "keymap_midi.h" +#endif + +extern keymap_config_t keymap_config; + +#include + +/* converts key to action */ +action_t action_for_key(uint8_t layer, keypos_t key) +{ + // 16bit keycodes - important + uint16_t keycode = keymap_key_to_keycode(layer, key); + + // keycode remapping + keycode = keycode_config(keycode); + + action_t action; + uint8_t action_layer, when, mod; + // The arm-none-eabi compiler generates out of bounds warnings when using the fn_actions directly for some reason + const uint16_t* actions = fn_actions; + + switch (keycode) { + case KC_FN0 ... KC_FN31: + action.code = pgm_read_word(&actions[FN_INDEX(keycode)]); + break; + case KC_A ... KC_EXSEL: + case KC_LCTRL ... KC_RGUI: + action.code = ACTION_KEY(keycode); + break; + case KC_SYSTEM_POWER ... KC_SYSTEM_WAKE: + action.code = ACTION_USAGE_SYSTEM(KEYCODE2SYSTEM(keycode)); + break; + case KC_AUDIO_MUTE ... KC_WWW_FAVORITES: + action.code = ACTION_USAGE_CONSUMER(KEYCODE2CONSUMER(keycode)); + break; + case KC_MS_UP ... KC_MS_ACCEL2: + action.code = ACTION_MOUSEKEY(keycode); + break; + case KC_TRNS: + action.code = ACTION_TRANSPARENT; + break; + case QK_MODS ... QK_MODS_MAX: ; + // Has a modifier + // Split it up + action.code = ACTION_MODS_KEY(keycode >> 8, keycode & 0xFF); // adds modifier to key + break; + case QK_FUNCTION ... QK_FUNCTION_MAX: ; + // Is a shortcut for function action_layer, pull last 12bits + // This means we have 4,096 FN macros at our disposal + action.code = pgm_read_word(&actions[(int)keycode & 0xFFF]); + break; + case QK_MACRO ... QK_MACRO_MAX: + action.code = ACTION_MACRO(keycode & 0xFF); + break; + case QK_LAYER_TAP ... QK_LAYER_TAP_MAX: + action.code = ACTION_LAYER_TAP_KEY((keycode >> 0x8) & 0xF, keycode & 0xFF); + break; + case QK_TO ... QK_TO_MAX: ; + // Layer set "GOTO" + when = (keycode >> 0x4) & 0x3; + action_layer = keycode & 0xF; + action.code = ACTION_LAYER_SET(action_layer, when); + break; + case QK_MOMENTARY ... QK_MOMENTARY_MAX: ; + // Momentary action_layer + action_layer = keycode & 0xFF; + action.code = ACTION_LAYER_MOMENTARY(action_layer); + break; + case QK_DEF_LAYER ... QK_DEF_LAYER_MAX: ; + // Set default action_layer + action_layer = keycode & 0xFF; + action.code = ACTION_DEFAULT_LAYER_SET(action_layer); + break; + case QK_TOGGLE_LAYER ... QK_TOGGLE_LAYER_MAX: ; + // Set toggle + action_layer = keycode & 0xFF; + action.code = ACTION_LAYER_TOGGLE(action_layer); + break; + case QK_ONE_SHOT_LAYER ... QK_ONE_SHOT_LAYER_MAX: ; + // OSL(action_layer) - One-shot action_layer + action_layer = keycode & 0xFF; + action.code = ACTION_LAYER_ONESHOT(action_layer); + break; + case QK_ONE_SHOT_MOD ... QK_ONE_SHOT_MOD_MAX: ; + // OSM(mod) - One-shot mod + mod = keycode & 0xFF; + action.code = ACTION_MODS_ONESHOT(mod); + break; + case QK_MOD_TAP ... QK_MOD_TAP_MAX: + action.code = ACTION_MODS_TAP_KEY((keycode >> 0x8) & 0xF, keycode & 0xFF); + break; + #ifdef BACKLIGHT_ENABLE + case BL_0 ... BL_15: + action.code = ACTION_BACKLIGHT_LEVEL(keycode - BL_0); + break; + case BL_DEC: + action.code = ACTION_BACKLIGHT_DECREASE(); + break; + case BL_INC: + action.code = ACTION_BACKLIGHT_INCREASE(); + break; + case BL_TOGG: + action.code = ACTION_BACKLIGHT_TOGGLE(); + break; + case BL_STEP: + action.code = ACTION_BACKLIGHT_STEP(); + break; + #endif + default: + action.code = ACTION_NO; + break; + } + return action; +} + +__attribute__ ((weak)) +const uint16_t PROGMEM fn_actions[] = { + +}; + +/* Macro */ +__attribute__ ((weak)) +const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) +{ + return MACRO_NONE; +} + +/* Function */ +__attribute__ ((weak)) +void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) +{ +} + +/* translates key to keycode */ +uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key) +{ + // Read entire word (16bits) + return pgm_read_word(&keymaps[(layer)][(key.row)][(key.col)]); +} diff --git a/quantum/matrix.c b/quantum/matrix.c index f5744658c..a38c13f15 100644 --- a/quantum/matrix.c +++ b/quantum/matrix.c @@ -17,7 +17,9 @@ along with this program. If not, see . */ #include #include +#if defined(__AVR__) #include +#endif #include "wait.h" #include "print.h" #include "debug.h" diff --git a/quantum/quantum.c b/quantum/quantum.c index 270b976e3..d59bd5a3f 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -88,7 +88,7 @@ bool process_record_quantum(keyrecord_t *record) { stop_all_notes(); shutdown_user(); #endif - _delay_ms(250); + wait_ms(250); #ifdef ATREUS_ASTAR *(uint16_t *)0x0800 = 0x7777; // these two are a-star-specific #endif diff --git a/quantum/quantum.h b/quantum/quantum.h index 9b5d310bd..3a0b74202 100644 --- a/quantum/quantum.h +++ b/quantum/quantum.h @@ -1,7 +1,12 @@ #ifndef QUANTUM_H #define QUANTUM_H +#if defined(__AVR__) #include +#include +#include +#endif +#include "wait.h" #include "matrix.h" #include "keymap.h" #ifdef BACKLIGHT_ENABLE @@ -14,12 +19,9 @@ #include "action_layer.h" #include "eeconfig.h" #include -#include -#include #include "bootloader.h" #include "timer.h" #include "config_common.h" -#include #include "led.h" #include "action_util.h" #include -- cgit v1.2.3-24-g4f1b From 132c04746910f7230b63ed33717c4ed65599ed1b Mon Sep 17 00:00:00 2001 From: Rubén Díaz-Jorge Date: Sat, 2 Jul 2016 10:26:04 +0200 Subject: Fix for '~' in spanish layout --- quantum/keymap_extras/keymap_spanish.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'quantum') diff --git a/quantum/keymap_extras/keymap_spanish.h b/quantum/keymap_extras/keymap_spanish.h index 512d8a374..af76e39fc 100644 --- a/quantum/keymap_extras/keymap_spanish.h +++ b/quantum/keymap_extras/keymap_spanish.h @@ -49,7 +49,7 @@ #define ES_PIPE ALGR(KC_1) #define ES_AT ALGR(KC_2) #define ES_HASH ALGR(KC_3) -#define ES_TILD ALGR(KC_4) +#define ES_TILD ALGR(ES_NTIL) #define ES_EURO ALGR(KC_5) #define ES_NOT ALGR(KC_6) @@ -59,4 +59,4 @@ #define ES_LCBR ALGR(ES_ACUT) #define ES_RCRB ALGR(ES_CCED) -#endif \ No newline at end of file +#endif -- cgit v1.2.3-24-g4f1b From 8e88d55bfd7c88cb15845e0c6415e4e892532861 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Mon, 4 Jul 2016 11:45:58 -0400 Subject: reverts #343 for the most part (#474) --- quantum/matrix.c | 292 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 163 insertions(+), 129 deletions(-) (limited to 'quantum') diff --git a/quantum/matrix.c b/quantum/matrix.c index a38c13f15..094917025 100644 --- a/quantum/matrix.c +++ b/quantum/matrix.c @@ -26,32 +26,46 @@ along with this program. If not, see . #include "util.h" #include "matrix.h" -#ifdef MATRIX_HAS_GHOST -# error "The universal matrix.c file cannot be used for this keyboard." -#endif +/* Set 0 if debouncing isn't needed */ +/* + * This constant define not debouncing time in msecs, but amount of matrix + * scan loops which should be made to get stable debounced results. + * + * On Ergodox matrix scan rate is relatively low, because of slow I2C. + * Now it's only 317 scans/second, or about 3.15 msec/scan. + * According to Cherry specs, debouncing time is 5 msec. + * + * And so, there is no sense to have DEBOUNCE higher than 2. + */ #ifndef DEBOUNCING_DELAY # define DEBOUNCING_DELAY 5 #endif +static uint8_t debouncing = DEBOUNCING_DELAY; static const uint8_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; static const uint8_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS; -/* matrix state */ -#if DIODE_DIRECTION == COL2ROW + +/* matrix state(1:on, 0:off) */ static matrix_row_t matrix[MATRIX_ROWS]; -#else -static matrix_col_t matrix[MATRIX_COLS]; +static matrix_row_t matrix_debouncing[MATRIX_ROWS]; + +#if DIODE_DIRECTION == ROW2COL + static matrix_row_t matrix_reversed[MATRIX_COLS]; + static matrix_row_t matrix_reversed_debouncing[MATRIX_COLS]; #endif -static int8_t debouncing_delay = -1; -#if DIODE_DIRECTION == COL2ROW -static void toggle_row(uint8_t row); -static matrix_row_t read_cols(void); +#if MATRIX_COLS > 16 + #define SHIFTER 1UL #else -static void toggle_col(uint8_t col); -static matrix_col_t read_rows(void); + #define SHIFTER 1 #endif +static matrix_row_t read_cols(void); +static void init_cols(void); +static void unselect_rows(void); +static void select_row(uint8_t row); + __attribute__ ((weak)) void matrix_init_quantum(void) { matrix_init_kb(); @@ -80,10 +94,12 @@ __attribute__ ((weak)) void matrix_scan_user(void) { } +inline uint8_t matrix_rows(void) { return MATRIX_ROWS; } +inline uint8_t matrix_cols(void) { return MATRIX_COLS; } @@ -113,161 +129,179 @@ uint8_t matrix_cols(void) { // } void matrix_init(void) { - /* frees PORTF by setting the JTD bit twice within four cycles */ + // To use PORTF disable JTAG with writing JTD bit twice within four cycles. #ifdef __AVR_ATmega32U4__ MCUCR |= _BV(JTD); MCUCR |= _BV(JTD); #endif - /* initializes the I/O pins */ -#if DIODE_DIRECTION == COL2ROW - for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { - /* DDRxn */ - _SFR_IO8((row_pins[r] >> 4) + 1) |= _BV(row_pins[r] & 0xF); - toggle_row(r); - } - for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { - /* PORTxn */ - _SFR_IO8((col_pins[c] >> 4) + 2) |= _BV(col_pins[c] & 0xF); - } -#else - for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { - /* DDRxn */ - _SFR_IO8((col_pins[c] >> 4) + 1) |= _BV(col_pins[c] & 0xF); - toggle_col(c); - } - for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { - /* PORTxn */ - _SFR_IO8((row_pins[r] >> 4) + 2) |= _BV(row_pins[r] & 0xF); + + // initialize row and col + unselect_rows(); + init_cols(); + + // initialize matrix state: all keys off + for (uint8_t i=0; i < MATRIX_ROWS; i++) { + matrix[i] = 0; + matrix_debouncing[i] = 0; } -#endif + matrix_init_quantum(); } +uint8_t matrix_scan(void) +{ + #if DIODE_DIRECTION == COL2ROW -uint8_t matrix_scan(void) { - static matrix_row_t debouncing_matrix[MATRIX_ROWS]; - for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { - toggle_row(r); - matrix_row_t state = read_cols(); - if (debouncing_matrix[r] != state) { - debouncing_matrix[r] = state; - debouncing_delay = DEBOUNCING_DELAY; - } - toggle_row(r); - } - if (debouncing_delay >= 0) { - dprintf("Debouncing delay remaining: %X\n", debouncing_delay); - --debouncing_delay; - if (debouncing_delay >= 0) { - wait_ms(1); - } - else { - for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { - matrix[r] = debouncing_matrix[r]; + for (uint8_t i = 0; i < MATRIX_ROWS; i++) { + select_row(i); + wait_us(30); // without this wait read unstable value. + matrix_row_t cols = read_cols(); + if (matrix_debouncing[i] != cols) { + matrix_debouncing[i] = cols; + if (debouncing) { + debug("bounce!: "); debug_hex(debouncing); debug("\n"); } + debouncing = DEBOUNCING_DELAY; } + unselect_rows(); } - matrix_scan_quantum(); - return 1; -} - -static void toggle_row(uint8_t row) { - /* PINxn */ - _SFR_IO8((row_pins[row] >> 4)) = _BV(row_pins[row] & 0xF); -} -static matrix_row_t read_cols(void) { - matrix_row_t state = 0; - for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { - /* PINxn */ - if (!(_SFR_IO8((col_pins[c] >> 4)) & _BV(col_pins[c] & 0xF))) { - state |= (matrix_row_t)1 << c; + if (debouncing) { + if (--debouncing) { + wait_us(1); + } else { + for (uint8_t i = 0; i < MATRIX_ROWS; i++) { + matrix[i] = matrix_debouncing[i]; + } } } - return state; -} - -matrix_row_t matrix_get_row(uint8_t row) { - return matrix[row]; -} - #else -uint8_t matrix_scan(void) { - static matrix_col_t debouncing_matrix[MATRIX_COLS]; - for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { - toggle_col(c); - matrix_col_t state = read_rows(); - if (debouncing_matrix[c] != state) { - debouncing_matrix[c] = state; - debouncing_delay = DEBOUNCING_DELAY; + for (uint8_t i = 0; i < MATRIX_COLS; i++) { + select_row(i); + wait_us(30); // without this wait read unstable value. + matrix_row_t rows = read_cols(); + if (matrix_reversed_debouncing[i] != rows) { + matrix_reversed_debouncing[i] = rows; + if (debouncing) { + debug("bounce!: "); debug_hex(debouncing); debug("\n"); + } + debouncing = DEBOUNCING_DELAY; } - toggle_col(c); + unselect_rows(); } - if (debouncing_delay >= 0) { - dprintf("Debouncing delay remaining: %X\n", debouncing_delay); - --debouncing_delay; - if (debouncing_delay >= 0) { - wait_ms(1); - } - else { - for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { - matrix[c] = debouncing_matrix[c]; + + if (debouncing) { + if (--debouncing) { + wait_us(1); + } else { + for (uint8_t i = 0; i < MATRIX_COLS; i++) { + matrix_reversed[i] = matrix_reversed_debouncing[i]; } } } + for (uint8_t y = 0; y < MATRIX_ROWS; y++) { + matrix_row_t row = 0; + for (uint8_t x = 0; x < MATRIX_COLS; x++) { + row |= ((matrix_reversed[x] & (1<> y) << x; + } + matrix[y] = row; + } +#endif + matrix_scan_quantum(); + return 1; } -static void toggle_col(uint8_t col) { - /* PINxn */ - _SFR_IO8((col_pins[col] >> 4)) = _BV(col_pins[col] & 0xF); +bool matrix_is_modified(void) +{ + if (debouncing) return false; + return true; } -static matrix_col_t read_rows(void) { - matrix_col_t state = 0; - for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { - /* PINxn */ - if (!(_SFR_IO8((row_pins[r] >> 4)) & _BV(row_pins[r] & 0xF))) { - state |= (matrix_col_t)1 << r; - } +inline +bool matrix_is_on(uint8_t row, uint8_t col) +{ + return (matrix[row] & ((matrix_row_t)1= 0; --c) { - if (matrix[c] & mask) { - state |= (matrix_row_t)1 << c; - } +uint8_t matrix_key_count(void) +{ + uint8_t count = 0; + for (uint8_t i = 0; i < MATRIX_ROWS; i++) { + count += bitpop16(matrix[i]); } - return state; + return count; } +static void init_cols(void) +{ +#if DIODE_DIRECTION == COL2ROW + for(int x = 0; x < MATRIX_COLS; x++) { + int pin = col_pins[x]; +#else + for(int x = 0; x < MATRIX_ROWS; x++) { + int pin = row_pins[x]; #endif - -bool matrix_is_modified(void) { - if (debouncing_delay >= 0) return false; - return true; + _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); + _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); + } } -bool matrix_is_on(uint8_t row, uint8_t col) { - return matrix_get_row(row) & (matrix_row_t)1 << col; -} +static matrix_row_t read_cols(void) +{ + matrix_row_t result = 0; -void matrix_print(void) { - dprintln("Human-readable matrix state:"); - for (uint8_t r = 0; r < MATRIX_ROWS; r++) { - dprintf("State of row %X: %016b\n", r, bitrev16(matrix_get_row(r))); +#if DIODE_DIRECTION == COL2ROW + for(int x = 0; x < MATRIX_COLS; x++) { + int pin = col_pins[x]; +#else + for(int x = 0; x < MATRIX_ROWS; x++) { + int pin = row_pins[x]; +#endif + result |= (_SFR_IO8(pin >> 4) & _BV(pin & 0xF)) ? 0 : (SHIFTER << x); } + return result; } -uint8_t matrix_key_count(void) { - uint8_t count = 0; - for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { - count += bitpop16(matrix_get_row(r)); +static void unselect_rows(void) +{ +#if DIODE_DIRECTION == COL2ROW + for(int x = 0; x < MATRIX_ROWS; x++) { + int pin = row_pins[x]; +#else + for(int x = 0; x < MATRIX_COLS; x++) { + int pin = col_pins[x]; +#endif + _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); + _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); } - return count; +} + +static void select_row(uint8_t row) +{ + +#if DIODE_DIRECTION == COL2ROW + int pin = row_pins[row]; +#else + int pin = col_pins[row]; +#endif + _SFR_IO8((pin >> 4) + 1) |= _BV(pin & 0xF); + _SFR_IO8((pin >> 4) + 2) &= ~_BV(pin & 0xF); } -- cgit v1.2.3-24-g4f1b From 1412076df68ac00f9a00173977d2826603c12ddf Mon Sep 17 00:00:00 2001 From: Smilliam Date: Mon, 4 Jul 2016 19:56:08 -0700 Subject: Allow Space Cadet state to be canceled by alternate Shift key Allows you to press RSHIFT to cancel the insertion of a "(" when holding down LSHIFT. Alternatively, allows you to press LSHIFT to cancel the insertion of a ")" when holding down RSHIFT. This change enables you to renege from outputting a character should you press a shift key erroneously. --- quantum/quantum.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'quantum') diff --git a/quantum/quantum.c b/quantum/quantum.c index d59bd5a3f..65290338d 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -162,6 +162,10 @@ bool process_record_quantum(keyrecord_t *record) { register_mods(MOD_BIT(KC_LSFT)); } else { + if (get_mods() & MOD_BIT(KC_RSFT)) { + shift_interrupted[0] = true; + shift_interrupted[1] = true; + } if (!shift_interrupted[0]) { register_code(LSPO_KEY); unregister_code(LSPO_KEY); @@ -178,6 +182,10 @@ bool process_record_quantum(keyrecord_t *record) { register_mods(MOD_BIT(KC_RSFT)); } else { + if (get_mods() & MOD_BIT(KC_LSFT)) { + shift_interrupted[0] = true; + shift_interrupted[1] = true; + } if (!shift_interrupted[1]) { register_code(RSPC_KEY); unregister_code(RSPC_KEY); -- cgit v1.2.3-24-g4f1b From 6b0c9cc905c0985f96a80306cf5fe0d6724b28fc Mon Sep 17 00:00:00 2001 From: Smilliam Date: Mon, 4 Jul 2016 19:58:26 -0700 Subject: fixed indentation. --- quantum/quantum.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'quantum') diff --git a/quantum/quantum.c b/quantum/quantum.c index 65290338d..71c3c723b 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -162,10 +162,10 @@ bool process_record_quantum(keyrecord_t *record) { register_mods(MOD_BIT(KC_LSFT)); } else { - if (get_mods() & MOD_BIT(KC_RSFT)) { - shift_interrupted[0] = true; - shift_interrupted[1] = true; - } + if (get_mods() & MOD_BIT(KC_RSFT)) { + shift_interrupted[0] = true; + shift_interrupted[1] = true; + } if (!shift_interrupted[0]) { register_code(LSPO_KEY); unregister_code(LSPO_KEY); @@ -182,10 +182,10 @@ bool process_record_quantum(keyrecord_t *record) { register_mods(MOD_BIT(KC_RSFT)); } else { - if (get_mods() & MOD_BIT(KC_LSFT)) { - shift_interrupted[0] = true; - shift_interrupted[1] = true; - } + if (get_mods() & MOD_BIT(KC_LSFT)) { + shift_interrupted[0] = true; + shift_interrupted[1] = true; + } if (!shift_interrupted[1]) { register_code(RSPC_KEY); unregister_code(RSPC_KEY); -- cgit v1.2.3-24-g4f1b From 3577e26fd9916ceab58779ec6323d43da54eb3b5 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Wed, 6 Jul 2016 00:24:31 -0400 Subject: fix/annotate wait_us lines --- quantum/matrix.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) (limited to 'quantum') diff --git a/quantum/matrix.c b/quantum/matrix.c index 094917025..3174e0739 100644 --- a/quantum/matrix.c +++ b/quantum/matrix.c @@ -27,16 +27,6 @@ along with this program. If not, see . #include "matrix.h" /* Set 0 if debouncing isn't needed */ -/* - * This constant define not debouncing time in msecs, but amount of matrix - * scan loops which should be made to get stable debounced results. - * - * On Ergodox matrix scan rate is relatively low, because of slow I2C. - * Now it's only 317 scans/second, or about 3.15 msec/scan. - * According to Cherry specs, debouncing time is 5 msec. - * - * And so, there is no sense to have DEBOUNCE higher than 2. - */ #ifndef DEBOUNCING_DELAY # define DEBOUNCING_DELAY 5 @@ -168,7 +158,7 @@ uint8_t matrix_scan(void) if (debouncing) { if (--debouncing) { - wait_us(1); + wait_ms(1); } else { for (uint8_t i = 0; i < MATRIX_ROWS; i++) { matrix[i] = matrix_debouncing[i]; @@ -192,7 +182,7 @@ uint8_t matrix_scan(void) if (debouncing) { if (--debouncing) { - wait_us(1); + wait_ms(1); } else { for (uint8_t i = 0; i < MATRIX_COLS; i++) { matrix_reversed[i] = matrix_reversed_debouncing[i]; -- cgit v1.2.3-24-g4f1b From 3ac52b2e7623152f177670549b780492a0447c12 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Wed, 6 Jul 2016 13:09:51 +0300 Subject: Remove serial_link .gitignore and .gitmodules --- quantum/serial_link/.gitignore | 1 - quantum/serial_link/.gitmodules | 3 --- 2 files changed, 4 deletions(-) delete mode 100644 quantum/serial_link/.gitignore delete mode 100644 quantum/serial_link/.gitmodules (limited to 'quantum') diff --git a/quantum/serial_link/.gitignore b/quantum/serial_link/.gitignore deleted file mode 100644 index 2d68e206e..000000000 --- a/quantum/serial_link/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.stackdump diff --git a/quantum/serial_link/.gitmodules b/quantum/serial_link/.gitmodules deleted file mode 100644 index 991cfe96d..000000000 --- a/quantum/serial_link/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "cgreen/cgreen"] - path = cgreen/cgreen - url = http://github.com/cgreen-devs/cgreen -- cgit v1.2.3-24-g4f1b From c5bf090d16cf1fc4d8186f1e8fbbd62457e72da6 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Wed, 6 Jul 2016 13:10:30 +0300 Subject: Remove CGreen make files --- quantum/serial_link/cgreen/Makefile | 38 ------------------------------- quantum/serial_link/cgreen/Makefile.build | 33 --------------------------- quantum/serial_link/cgreen/cgreen | 1 - 3 files changed, 72 deletions(-) delete mode 100644 quantum/serial_link/cgreen/Makefile delete mode 100644 quantum/serial_link/cgreen/Makefile.build delete mode 160000 quantum/serial_link/cgreen/cgreen (limited to 'quantum') diff --git a/quantum/serial_link/cgreen/Makefile b/quantum/serial_link/cgreen/Makefile deleted file mode 100644 index 6b31a3f92..000000000 --- a/quantum/serial_link/cgreen/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -# This Makefile ensures that the build is made out of source in a subdirectory called 'build' -# If it doesn't exist, it is created and a Makefile created there (from Makefile.build) -# -# This Makefile also contains delegation of the most common make commands -# -# If you have cmake installed you should be able to do: -# -# make -# make test -# make install -# make package -# -# That should build cgreen for C and C++, run some tests, install it locally and -# generate two distributable packages. - -all: build - cd $(CGREEN_BUILD_DIR); make all - -test: build - cd $(CGREEN_BUILD_DIR); make test - -clean: build - cd $(CGREEN_BUILD_DIR); make clean - -package: build - cd $(CGREEN_BUILD_DIR); make package - -install: - cd $(CGREEN_BUILD_DIR); make install - -############# Internal - -build: - mkdir -p $(CGREEN_BUILD_DIR) - cp Makefile.build $(CGREEN_BUILD_DIR)/Makefile - - -.SILENT: diff --git a/quantum/serial_link/cgreen/Makefile.build b/quantum/serial_link/cgreen/Makefile.build deleted file mode 100644 index f76165244..000000000 --- a/quantum/serial_link/cgreen/Makefile.build +++ /dev/null @@ -1,33 +0,0 @@ -# This Makefile is copied from the cgreen top directory (where it is -# named Makefile.build) and put in a subdirectory called 'build' where -# builds are made This Makefile then automatically creates -# subdirectories for C and C++ builds configuring them using the cmake -# command. Once created you can always tweak the cmake setup as with -# any cmake build directory - -all: build-c build-c++ - for d in build-* ; do cd $$d; make ; cd .. ; done - -clean: - for d in build-* ; do cd $$d; make clean ; cd .. ; done - -check test: - for d in build-* ; do cd $$d; make check ; cd .. ; done - -package: - for d in build-* ; do cd $$d; make package ; cd .. ; done - -install: - for d in build-* ; do cd $$d; make install ; cd .. ; done - -############ Internal - -build-c: - mkdir build-c - cd build-c; cmake -G "Unix Makefiles" $(CGREEN_DIR) - -build-c++: - mkdir build-c++ - cd build-c++; cmake -G "Unix Makefiles" -DWITH_CXX:bool=ON $(CGREEN_DIR) - -.SILENT: diff --git a/quantum/serial_link/cgreen/cgreen b/quantum/serial_link/cgreen/cgreen deleted file mode 160000 index d4d438dda..000000000 --- a/quantum/serial_link/cgreen/cgreen +++ /dev/null @@ -1 +0,0 @@ -Subproject commit d4d438dda1b7131f0bd0530b2c258e9dea6a2a9f -- cgit v1.2.3-24-g4f1b From d5e7603d551a31836bf0c59db259ddc3593a1aa7 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Wed, 6 Jul 2016 13:26:20 +0300 Subject: Remove extra serial_link subdirectory --- quantum/serial_link/README.md | 2 +- quantum/serial_link/protocol/byte_stuffer.c | 145 ++++++ quantum/serial_link/protocol/byte_stuffer.h | 34 ++ quantum/serial_link/protocol/frame_router.c | 69 +++ quantum/serial_link/protocol/frame_router.h | 38 ++ quantum/serial_link/protocol/frame_validator.c | 121 +++++ quantum/serial_link/protocol/frame_validator.h | 34 ++ quantum/serial_link/protocol/physical.h | 30 ++ quantum/serial_link/protocol/transport.c | 124 +++++ quantum/serial_link/protocol/transport.h | 151 ++++++ .../serial_link/protocol/triple_buffered_object.c | 78 ++++ .../serial_link/protocol/triple_buffered_object.h | 51 +++ quantum/serial_link/serial_link.mk | 27 -- .../serial_link/protocol/byte_stuffer.c | 145 ------ .../serial_link/protocol/byte_stuffer.h | 34 -- .../serial_link/protocol/frame_router.c | 69 --- .../serial_link/protocol/frame_router.h | 38 -- .../serial_link/protocol/frame_validator.c | 121 ----- .../serial_link/protocol/frame_validator.h | 34 -- .../serial_link/serial_link/protocol/physical.h | 30 -- .../serial_link/serial_link/protocol/transport.c | 124 ----- .../serial_link/serial_link/protocol/transport.h | 151 ------ .../serial_link/protocol/triple_buffered_object.c | 78 ---- .../serial_link/protocol/triple_buffered_object.h | 51 --- .../serial_link/serial_link/system/serial_link.c | 265 ----------- .../serial_link/serial_link/system/serial_link.h | 63 --- quantum/serial_link/serial_link/tests/Makefile | 61 --- .../serial_link/tests/byte_stuffer_tests.c | 506 --------------------- .../serial_link/tests/frame_router_tests.c | 231 ---------- .../serial_link/tests/frame_validator_tests.c | 101 ---- .../serial_link/tests/transport_tests.c | 168 ------- .../tests/triple_buffered_object_tests.c | 82 ---- quantum/serial_link/serial_link_tests.mk | 34 -- quantum/serial_link/system/serial_link.c | 265 +++++++++++ quantum/serial_link/system/serial_link.h | 63 +++ quantum/serial_link/tests/Makefile | 61 +++ quantum/serial_link/tests/byte_stuffer_tests.c | 506 +++++++++++++++++++++ quantum/serial_link/tests/frame_router_tests.c | 231 ++++++++++ quantum/serial_link/tests/frame_validator_tests.c | 101 ++++ quantum/serial_link/tests/transport_tests.c | 168 +++++++ .../tests/triple_buffered_object_tests.c | 82 ++++ 41 files changed, 2353 insertions(+), 2414 deletions(-) create mode 100644 quantum/serial_link/protocol/byte_stuffer.c create mode 100644 quantum/serial_link/protocol/byte_stuffer.h create mode 100644 quantum/serial_link/protocol/frame_router.c create mode 100644 quantum/serial_link/protocol/frame_router.h create mode 100644 quantum/serial_link/protocol/frame_validator.c create mode 100644 quantum/serial_link/protocol/frame_validator.h create mode 100644 quantum/serial_link/protocol/physical.h create mode 100644 quantum/serial_link/protocol/transport.c create mode 100644 quantum/serial_link/protocol/transport.h create mode 100644 quantum/serial_link/protocol/triple_buffered_object.c create mode 100644 quantum/serial_link/protocol/triple_buffered_object.h delete mode 100644 quantum/serial_link/serial_link.mk delete mode 100644 quantum/serial_link/serial_link/protocol/byte_stuffer.c delete mode 100644 quantum/serial_link/serial_link/protocol/byte_stuffer.h delete mode 100644 quantum/serial_link/serial_link/protocol/frame_router.c delete mode 100644 quantum/serial_link/serial_link/protocol/frame_router.h delete mode 100644 quantum/serial_link/serial_link/protocol/frame_validator.c delete mode 100644 quantum/serial_link/serial_link/protocol/frame_validator.h delete mode 100644 quantum/serial_link/serial_link/protocol/physical.h delete mode 100644 quantum/serial_link/serial_link/protocol/transport.c delete mode 100644 quantum/serial_link/serial_link/protocol/transport.h delete mode 100644 quantum/serial_link/serial_link/protocol/triple_buffered_object.c delete mode 100644 quantum/serial_link/serial_link/protocol/triple_buffered_object.h delete mode 100644 quantum/serial_link/serial_link/system/serial_link.c delete mode 100644 quantum/serial_link/serial_link/system/serial_link.h delete mode 100644 quantum/serial_link/serial_link/tests/Makefile delete mode 100644 quantum/serial_link/serial_link/tests/byte_stuffer_tests.c delete mode 100644 quantum/serial_link/serial_link/tests/frame_router_tests.c delete mode 100644 quantum/serial_link/serial_link/tests/frame_validator_tests.c delete mode 100644 quantum/serial_link/serial_link/tests/transport_tests.c delete mode 100644 quantum/serial_link/serial_link/tests/triple_buffered_object_tests.c delete mode 100644 quantum/serial_link/serial_link_tests.mk create mode 100644 quantum/serial_link/system/serial_link.c create mode 100644 quantum/serial_link/system/serial_link.h create mode 100644 quantum/serial_link/tests/Makefile create mode 100644 quantum/serial_link/tests/byte_stuffer_tests.c create mode 100644 quantum/serial_link/tests/frame_router_tests.c create mode 100644 quantum/serial_link/tests/frame_validator_tests.c create mode 100644 quantum/serial_link/tests/transport_tests.c create mode 100644 quantum/serial_link/tests/triple_buffered_object_tests.c (limited to 'quantum') diff --git a/quantum/serial_link/README.md b/quantum/serial_link/README.md index 94af9125c..e8490e290 100644 --- a/quantum/serial_link/README.md +++ b/quantum/serial_link/README.md @@ -1 +1 @@ -# tmk_serial_link \ No newline at end of file +# qmk_serial_link \ No newline at end of file diff --git a/quantum/serial_link/protocol/byte_stuffer.c b/quantum/serial_link/protocol/byte_stuffer.c new file mode 100644 index 000000000..fb4c45a8d --- /dev/null +++ b/quantum/serial_link/protocol/byte_stuffer.c @@ -0,0 +1,145 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016 Fred Sundvik + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include "serial_link/protocol/byte_stuffer.h" +#include "serial_link/protocol/frame_validator.h" +#include "serial_link/protocol/physical.h" +#include + +// This implements the "Consistent overhead byte stuffing protocol" +// https://en.wikipedia.org/wiki/Consistent_Overhead_Byte_Stuffing +// http://www.stuartcheshire.org/papers/COBSforToN.pdf + +#define MAX_FRAME_SIZE 1024 +#define NUM_LINKS 2 + +typedef struct byte_stuffer_state { + uint16_t next_zero; + uint16_t data_pos; + bool long_frame; + uint8_t data[MAX_FRAME_SIZE]; +}byte_stuffer_state_t; + +static byte_stuffer_state_t states[NUM_LINKS]; + +void init_byte_stuffer_state(byte_stuffer_state_t* state) { + state->next_zero = 0; + state->data_pos = 0; + state->long_frame = false; +} + +void init_byte_stuffer(void) { + int i; + for (i=0;inext_zero == 0) { + state->next_zero = data; + state->long_frame = data == 0xFF; + state->data_pos = 0; + return; + } + + state->next_zero--; + if (data == 0) { + if (state->next_zero == 0) { + // The frame is completed + if (state->data_pos > 0) { + validator_recv_frame(link, state->data, state->data_pos); + } + } + else { + // The frame is invalid, so reset + init_byte_stuffer_state(state); + } + } + else { + if (state->data_pos == MAX_FRAME_SIZE) { + // We exceeded our maximum frame size + // therefore there's nothing else to do than reset to a new frame + state->next_zero = data; + state->long_frame = data == 0xFF; + state->data_pos = 0; + } + else if (state->next_zero == 0) { + if (state->long_frame) { + // This is part of a long frame, so continue + state->next_zero = data; + state->long_frame = data == 0xFF; + } + else { + // Special case for zeroes + state->next_zero = data; + state->data[state->data_pos++] = 0; + } + } + else { + state->data[state->data_pos++] = data; + } + } +} + +static void send_block(uint8_t link, uint8_t* start, uint8_t* end, uint8_t num_non_zero) { + send_data(link, &num_non_zero, 1); + if (end > start) { + send_data(link, start, end-start); + } +} + +void byte_stuffer_send_frame(uint8_t link, uint8_t* data, uint16_t size) { + const uint8_t zero = 0; + if (size > 0) { + uint16_t num_non_zero = 1; + uint8_t* end = data + size; + uint8_t* start = data; + while (data < end) { + if (num_non_zero == 0xFF) { + // There's more data after big non-zero block + // So send it, and start a new block + send_block(link, start, data, num_non_zero); + start = data; + num_non_zero = 1; + } + else { + if (*data == 0) { + // A zero encountered, so send the block + send_block(link, start, data, num_non_zero); + start = data + 1; + num_non_zero = 1; + } + else { + num_non_zero++; + } + ++data; + } + } + send_block(link, start, data, num_non_zero); + send_data(link, &zero, 1); + } +} diff --git a/quantum/serial_link/protocol/byte_stuffer.h b/quantum/serial_link/protocol/byte_stuffer.h new file mode 100644 index 000000000..2cc88beb4 --- /dev/null +++ b/quantum/serial_link/protocol/byte_stuffer.h @@ -0,0 +1,34 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016 Fred Sundvik + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#ifndef SERIAL_LINK_BYTE_STUFFER_H +#define SERIAL_LINK_BYTE_STUFFER_H + +#include + +void init_byte_stuffer(void); +void byte_stuffer_recv_byte(uint8_t link, uint8_t data); +void byte_stuffer_send_frame(uint8_t link, uint8_t* data, uint16_t size); + +#endif diff --git a/quantum/serial_link/protocol/frame_router.c b/quantum/serial_link/protocol/frame_router.c new file mode 100644 index 000000000..04b8c2e75 --- /dev/null +++ b/quantum/serial_link/protocol/frame_router.c @@ -0,0 +1,69 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016 Fred Sundvik + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include "serial_link/protocol/frame_router.h" +#include "serial_link/protocol/transport.h" +#include "serial_link/protocol/frame_validator.h" + +static bool is_master; + +void router_set_master(bool master) { + is_master = master; +} + +void route_incoming_frame(uint8_t link, uint8_t* data, uint16_t size){ + if (is_master) { + if (link == DOWN_LINK) { + transport_recv_frame(data[size-1], data, size - 1); + } + } + else { + if (link == UP_LINK) { + if (data[size-1] & 1) { + transport_recv_frame(0, data, size - 1); + } + data[size-1] >>= 1; + validator_send_frame(DOWN_LINK, data, size); + } + else { + data[size-1]++; + validator_send_frame(UP_LINK, data, size); + } + } +} + +void router_send_frame(uint8_t destination, uint8_t* data, uint16_t size) { + if (destination == 0) { + if (!is_master) { + data[size] = 1; + validator_send_frame(UP_LINK, data, size + 1); + } + } + else { + if (is_master) { + data[size] = destination; + validator_send_frame(DOWN_LINK, data, size + 1); + } + } +} diff --git a/quantum/serial_link/protocol/frame_router.h b/quantum/serial_link/protocol/frame_router.h new file mode 100644 index 000000000..712250ff3 --- /dev/null +++ b/quantum/serial_link/protocol/frame_router.h @@ -0,0 +1,38 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016 Fred Sundvik + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#ifndef SERIAL_LINK_FRAME_ROUTER_H +#define SERIAL_LINK_FRAME_ROUTER_H + +#include +#include + +#define UP_LINK 0 +#define DOWN_LINK 1 + +void router_set_master(bool master); +void route_incoming_frame(uint8_t link, uint8_t* data, uint16_t size); +void router_send_frame(uint8_t destination, uint8_t* data, uint16_t size); + +#endif diff --git a/quantum/serial_link/protocol/frame_validator.c b/quantum/serial_link/protocol/frame_validator.c new file mode 100644 index 000000000..474f80ee8 --- /dev/null +++ b/quantum/serial_link/protocol/frame_validator.c @@ -0,0 +1,121 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016 Fred Sundvik + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include "serial_link/protocol/frame_validator.h" +#include "serial_link/protocol/frame_router.h" +#include "serial_link/protocol/byte_stuffer.h" +#include + +const uint32_t poly8_lookup[256] = +{ + 0, 0x77073096, 0xEE0E612C, 0x990951BA, + 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, + 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, + 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, + 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, + 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, + 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, + 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, + 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, + 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, + 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, + 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, + 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, + 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, + 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, + 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, + 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, + 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, + 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, + 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, + 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, + 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, + 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, + 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, + 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, + 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, + 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, + 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, + 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, + 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, + 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, + 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, + 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, + 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, + 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, + 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, + 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, + 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, + 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, + 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, + 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, + 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, + 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, + 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, + 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, + 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, + 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, + 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, + 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, + 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, + 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, + 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, + 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, + 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, + 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, + 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, + 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, + 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, + 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, + 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, + 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, + 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, + 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, + 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D +}; + +static uint32_t crc32_byte(uint8_t *p, uint32_t bytelength) +{ + uint32_t crc = 0xffffffff; + while (bytelength-- !=0) crc = poly8_lookup[((uint8_t) crc ^ *(p++))] ^ (crc >> 8); + // return (~crc); also works + return (crc ^ 0xffffffff); +} + +void validator_recv_frame(uint8_t link, uint8_t* data, uint16_t size) { + if (size > 4) { + uint32_t frame_crc; + memcpy(&frame_crc, data + size -4, 4); + uint32_t expected_crc = crc32_byte(data, size - 4); + if (frame_crc == expected_crc) { + route_incoming_frame(link, data, size-4); + } + } +} + +void validator_send_frame(uint8_t link, uint8_t* data, uint16_t size) { + uint32_t crc = crc32_byte(data, size); + memcpy(data + size, &crc, 4); + byte_stuffer_send_frame(link, data, size + 4); +} diff --git a/quantum/serial_link/protocol/frame_validator.h b/quantum/serial_link/protocol/frame_validator.h new file mode 100644 index 000000000..4a910d510 --- /dev/null +++ b/quantum/serial_link/protocol/frame_validator.h @@ -0,0 +1,34 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016 Fred Sundvik + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#ifndef SERIAL_LINK_FRAME_VALIDATOR_H +#define SERIAL_LINK_FRAME_VALIDATOR_H + +#include + +void validator_recv_frame(uint8_t link, uint8_t* data, uint16_t size); +// The buffer pointed to by the data needs 4 additional bytes +void validator_send_frame(uint8_t link, uint8_t* data, uint16_t size); + +#endif diff --git a/quantum/serial_link/protocol/physical.h b/quantum/serial_link/protocol/physical.h new file mode 100644 index 000000000..425e06cdd --- /dev/null +++ b/quantum/serial_link/protocol/physical.h @@ -0,0 +1,30 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016 Fred Sundvik + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#ifndef SERIAL_LINK_PHYSICAL_H +#define SERIAL_LINK_PHYSICAL_H + +void send_data(uint8_t link, const uint8_t* data, uint16_t size); + +#endif diff --git a/quantum/serial_link/protocol/transport.c b/quantum/serial_link/protocol/transport.c new file mode 100644 index 000000000..f418d11ce --- /dev/null +++ b/quantum/serial_link/protocol/transport.c @@ -0,0 +1,124 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016 Fred Sundvik + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include "serial_link/protocol/transport.h" +#include "serial_link/protocol/frame_router.h" +#include "serial_link/protocol/triple_buffered_object.h" +#include + +#define MAX_REMOTE_OBJECTS 16 +static remote_object_t* remote_objects[MAX_REMOTE_OBJECTS]; +static uint32_t num_remote_objects = 0; + +void add_remote_objects(remote_object_t** _remote_objects, uint32_t _num_remote_objects) { + unsigned int i; + for(i=0;i<_num_remote_objects;i++) { + remote_object_t* obj = _remote_objects[i]; + remote_objects[num_remote_objects++] = obj; + if (obj->object_type == MASTER_TO_ALL_SLAVES) { + triple_buffer_object_t* tb = (triple_buffer_object_t*)obj->buffer; + triple_buffer_init(tb); + uint8_t* start = obj->buffer + LOCAL_OBJECT_SIZE(obj->object_size); + tb = (triple_buffer_object_t*)start; + triple_buffer_init(tb); + } + else if(obj->object_type == MASTER_TO_SINGLE_SLAVE) { + uint8_t* start = obj->buffer; + unsigned int j; + for (j=0;jobject_size); + } + triple_buffer_object_t* tb = (triple_buffer_object_t*)start; + triple_buffer_init(tb); + } + else { + uint8_t* start = obj->buffer; + triple_buffer_object_t* tb = (triple_buffer_object_t*)start; + triple_buffer_init(tb); + start += LOCAL_OBJECT_SIZE(obj->object_size); + unsigned int j; + for (j=0;jobject_size); + } + } + } +} + +void transport_recv_frame(uint8_t from, uint8_t* data, uint16_t size) { + uint8_t id = data[size-1]; + if (id < num_remote_objects) { + remote_object_t* obj = remote_objects[id]; + if (obj->object_size == size - 1) { + uint8_t* start; + if (obj->object_type == MASTER_TO_ALL_SLAVES) { + start = obj->buffer + LOCAL_OBJECT_SIZE(obj->object_size); + } + else if(obj->object_type == SLAVE_TO_MASTER) { + start = obj->buffer + LOCAL_OBJECT_SIZE(obj->object_size); + start += (from - 1) * REMOTE_OBJECT_SIZE(obj->object_size); + } + else { + start = obj->buffer + NUM_SLAVES * LOCAL_OBJECT_SIZE(obj->object_size); + } + triple_buffer_object_t* tb = (triple_buffer_object_t*)start; + void* ptr = triple_buffer_begin_write_internal(obj->object_size, tb); + memcpy(ptr, data, size - 1); + triple_buffer_end_write_internal(tb); + } + } +} + +void update_transport(void) { + unsigned int i; + for(i=0;iobject_type == MASTER_TO_ALL_SLAVES || obj->object_type == SLAVE_TO_MASTER) { + triple_buffer_object_t* tb = (triple_buffer_object_t*)obj->buffer; + uint8_t* ptr = (uint8_t*)triple_buffer_read_internal(obj->object_size + LOCAL_OBJECT_EXTRA, tb); + if (ptr) { + ptr[obj->object_size] = i; + uint8_t dest = obj->object_type == MASTER_TO_ALL_SLAVES ? 0xFF : 0; + router_send_frame(dest, ptr, obj->object_size + 1); + } + } + else { + uint8_t* start = obj->buffer; + unsigned int j; + for (j=0;jobject_size + LOCAL_OBJECT_EXTRA, tb); + if (ptr) { + ptr[obj->object_size] = i; + uint8_t dest = j + 1; + router_send_frame(dest, ptr, obj->object_size + 1); + } + start += LOCAL_OBJECT_SIZE(obj->object_size); + } + } + } +} diff --git a/quantum/serial_link/protocol/transport.h b/quantum/serial_link/protocol/transport.h new file mode 100644 index 000000000..9a052d880 --- /dev/null +++ b/quantum/serial_link/protocol/transport.h @@ -0,0 +1,151 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016 Fred Sundvik + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#ifndef SERIAL_LINK_TRANSPORT_H +#define SERIAL_LINK_TRANSPORT_H + +#include "serial_link/protocol/triple_buffered_object.h" +#include "serial_link/system/serial_link.h" + +#define NUM_SLAVES 8 +#define LOCAL_OBJECT_EXTRA 16 + +// master -> slave = 1 local(target all), 1 remote object +// slave -> master = 1 local(target 0), multiple remote objects +// master -> single slave (multiple local, target id), 1 remote object +typedef enum { + MASTER_TO_ALL_SLAVES, + MASTER_TO_SINGLE_SLAVE, + SLAVE_TO_MASTER, +} remote_object_type; + +typedef struct { + remote_object_type object_type; + uint16_t object_size; + uint8_t buffer[] __attribute__((aligned(4))); +} remote_object_t; + +#define REMOTE_OBJECT_SIZE(objectsize) \ + (sizeof(triple_buffer_object_t) + objectsize * 3) +#define LOCAL_OBJECT_SIZE(objectsize) \ + (sizeof(triple_buffer_object_t) + (objectsize + LOCAL_OBJECT_EXTRA) * 3) + +#define REMOTE_OBJECT_HELPER(name, type, num_local, num_remote) \ +typedef struct { \ + remote_object_t object; \ + uint8_t buffer[ \ + num_remote * REMOTE_OBJECT_SIZE(sizeof(type)) + \ + num_local * LOCAL_OBJECT_SIZE(sizeof(type))]; \ +} remote_object_##name##_t; + +#define MASTER_TO_ALL_SLAVES_OBJECT(name, type) \ + REMOTE_OBJECT_HELPER(name, type, 1, 1) \ + remote_object_##name##_t remote_object_##name = { \ + .object = { \ + .object_type = MASTER_TO_ALL_SLAVES, \ + .object_size = sizeof(type), \ + } \ + }; \ + type* begin_write_##name(void) { \ + remote_object_t* obj = (remote_object_t*)&remote_object_##name; \ + triple_buffer_object_t* tb = (triple_buffer_object_t*)obj->buffer; \ + return (type*)triple_buffer_begin_write_internal(sizeof(type) + LOCAL_OBJECT_EXTRA, tb); \ + }\ + void end_write_##name(void) { \ + remote_object_t* obj = (remote_object_t*)&remote_object_##name; \ + triple_buffer_object_t* tb = (triple_buffer_object_t*)obj->buffer; \ + triple_buffer_end_write_internal(tb); \ + signal_data_written(); \ + }\ + type* read_##name(void) { \ + remote_object_t* obj = (remote_object_t*)&remote_object_##name; \ + uint8_t* start = obj->buffer + LOCAL_OBJECT_SIZE(obj->object_size);\ + triple_buffer_object_t* tb = (triple_buffer_object_t*)start; \ + return triple_buffer_read_internal(obj->object_size, tb); \ + } + +#define MASTER_TO_SINGLE_SLAVE_OBJECT(name, type) \ + REMOTE_OBJECT_HELPER(name, type, NUM_SLAVES, 1) \ + remote_object_##name##_t remote_object_##name = { \ + .object = { \ + .object_type = MASTER_TO_SINGLE_SLAVE, \ + .object_size = sizeof(type), \ + } \ + }; \ + type* begin_write_##name(uint8_t slave) { \ + remote_object_t* obj = (remote_object_t*)&remote_object_##name; \ + uint8_t* start = obj->buffer;\ + start += slave * LOCAL_OBJECT_SIZE(obj->object_size); \ + triple_buffer_object_t* tb = (triple_buffer_object_t*)start; \ + return (type*)triple_buffer_begin_write_internal(sizeof(type) + LOCAL_OBJECT_EXTRA, tb); \ + }\ + void end_write_##name(uint8_t slave) { \ + remote_object_t* obj = (remote_object_t*)&remote_object_##name; \ + uint8_t* start = obj->buffer;\ + start += slave * LOCAL_OBJECT_SIZE(obj->object_size); \ + triple_buffer_object_t* tb = (triple_buffer_object_t*)start; \ + triple_buffer_end_write_internal(tb); \ + signal_data_written(); \ + }\ + type* read_##name() { \ + remote_object_t* obj = (remote_object_t*)&remote_object_##name; \ + uint8_t* start = obj->buffer + NUM_SLAVES * LOCAL_OBJECT_SIZE(obj->object_size);\ + triple_buffer_object_t* tb = (triple_buffer_object_t*)start; \ + return triple_buffer_read_internal(obj->object_size, tb); \ + } + +#define SLAVE_TO_MASTER_OBJECT(name, type) \ + REMOTE_OBJECT_HELPER(name, type, 1, NUM_SLAVES) \ + remote_object_##name##_t remote_object_##name = { \ + .object = { \ + .object_type = SLAVE_TO_MASTER, \ + .object_size = sizeof(type), \ + } \ + }; \ + type* begin_write_##name(void) { \ + remote_object_t* obj = (remote_object_t*)&remote_object_##name; \ + triple_buffer_object_t* tb = (triple_buffer_object_t*)obj->buffer; \ + return (type*)triple_buffer_begin_write_internal(sizeof(type) + LOCAL_OBJECT_EXTRA, tb); \ + }\ + void end_write_##name(void) { \ + remote_object_t* obj = (remote_object_t*)&remote_object_##name; \ + triple_buffer_object_t* tb = (triple_buffer_object_t*)obj->buffer; \ + triple_buffer_end_write_internal(tb); \ + signal_data_written(); \ + }\ + type* read_##name(uint8_t slave) { \ + remote_object_t* obj = (remote_object_t*)&remote_object_##name; \ + uint8_t* start = obj->buffer + LOCAL_OBJECT_SIZE(obj->object_size);\ + start+=slave * REMOTE_OBJECT_SIZE(obj->object_size); \ + triple_buffer_object_t* tb = (triple_buffer_object_t*)start; \ + return triple_buffer_read_internal(obj->object_size, tb); \ + } + +#define REMOTE_OBJECT(name) (remote_object_t*)&remote_object_##name + +void add_remote_objects(remote_object_t** remote_objects, uint32_t num_remote_objects); +void transport_recv_frame(uint8_t from, uint8_t* data, uint16_t size); +void update_transport(void); + +#endif diff --git a/quantum/serial_link/protocol/triple_buffered_object.c b/quantum/serial_link/protocol/triple_buffered_object.c new file mode 100644 index 000000000..e3e8989d3 --- /dev/null +++ b/quantum/serial_link/protocol/triple_buffered_object.c @@ -0,0 +1,78 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016 Fred Sundvik + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include "serial_link/protocol/triple_buffered_object.h" +#include "serial_link/system/serial_link.h" +#include +#include + +#define GET_READ_INDEX() object->state & 3 +#define GET_WRITE_INDEX() (object->state >> 2) & 3 +#define GET_SHARED_INDEX() (object->state >> 4) & 3 +#define GET_DATA_AVAILABLE() (object->state >> 6) & 1 + +#define SET_READ_INDEX(i) object->state = ((object->state & ~3) | i) +#define SET_WRITE_INDEX(i) object->state = ((object->state & ~(3 << 2)) | (i << 2)) +#define SET_SHARED_INDEX(i) object->state = ((object->state & ~(3 << 4)) | (i << 4)) +#define SET_DATA_AVAILABLE(i) object->state = ((object->state & ~(1 << 6)) | (i << 6)) + +void triple_buffer_init(triple_buffer_object_t* object) { + object->state = 0; + SET_WRITE_INDEX(0); + SET_READ_INDEX(1); + SET_SHARED_INDEX(2); + SET_DATA_AVAILABLE(0); +} + +void* triple_buffer_read_internal(uint16_t object_size, triple_buffer_object_t* object) { + serial_link_lock(); + if (GET_DATA_AVAILABLE()) { + uint8_t shared_index = GET_SHARED_INDEX(); + uint8_t read_index = GET_READ_INDEX(); + SET_READ_INDEX(shared_index); + SET_SHARED_INDEX(read_index); + SET_DATA_AVAILABLE(false); + serial_link_unlock(); + return object->buffer + object_size * shared_index; + } + else { + serial_link_unlock(); + return NULL; + } +} + +void* triple_buffer_begin_write_internal(uint16_t object_size, triple_buffer_object_t* object) { + uint8_t write_index = GET_WRITE_INDEX(); + return object->buffer + object_size * write_index; +} + +void triple_buffer_end_write_internal(triple_buffer_object_t* object) { + serial_link_lock(); + uint8_t shared_index = GET_SHARED_INDEX(); + uint8_t write_index = GET_WRITE_INDEX(); + SET_SHARED_INDEX(write_index); + SET_WRITE_INDEX(shared_index); + SET_DATA_AVAILABLE(true); + serial_link_unlock(); +} diff --git a/quantum/serial_link/protocol/triple_buffered_object.h b/quantum/serial_link/protocol/triple_buffered_object.h new file mode 100644 index 000000000..2e57db3f5 --- /dev/null +++ b/quantum/serial_link/protocol/triple_buffered_object.h @@ -0,0 +1,51 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016 Fred Sundvik + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#ifndef SERIAL_LINK_TRIPLE_BUFFERED_OBJECT_H +#define SERIAL_LINK_TRIPLE_BUFFERED_OBJECT_H + +#include + +typedef struct { + uint8_t state; + uint8_t buffer[] __attribute__((aligned(4))); +}triple_buffer_object_t; + +void triple_buffer_init(triple_buffer_object_t* object); + +#define triple_buffer_begin_write(object) \ + (typeof(*object.buffer[0])*)triple_buffer_begin_write_internal(sizeof(*object.buffer[0]), (triple_buffer_object_t*)object) + +#define triple_buffer_end_write(object) \ + triple_buffer_end_write_internal((triple_buffer_object_t*)object) + +#define triple_buffer_read(object) \ + (typeof(*object.buffer[0])*)triple_buffer_read_internal(sizeof(*object.buffer[0]), (triple_buffer_object_t*)object) + +void* triple_buffer_begin_write_internal(uint16_t object_size, triple_buffer_object_t* object); +void triple_buffer_end_write_internal(triple_buffer_object_t* object); +void* triple_buffer_read_internal(uint16_t object_size, triple_buffer_object_t* object); + + +#endif diff --git a/quantum/serial_link/serial_link.mk b/quantum/serial_link/serial_link.mk deleted file mode 100644 index e164cc5ff..000000000 --- a/quantum/serial_link/serial_link.mk +++ /dev/null @@ -1,27 +0,0 @@ -# The MIT License (MIT) -# -# Copyright (c) 2016 Fred Sundvik -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -UINCDIR += $(SERIAL_DIR) -SRC += $(wildcard $(SERIAL_DIR)/serial_link/protocol/*.c) -SRC += $(wildcard $(SERIAL_DIR)/serial_link/system/*.c) -SRC += serial_link_hal.c -OPT_DEFS += -DUSE_SERIAL_LINK diff --git a/quantum/serial_link/serial_link/protocol/byte_stuffer.c b/quantum/serial_link/serial_link/protocol/byte_stuffer.c deleted file mode 100644 index fb4c45a8d..000000000 --- a/quantum/serial_link/serial_link/protocol/byte_stuffer.c +++ /dev/null @@ -1,145 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "serial_link/protocol/byte_stuffer.h" -#include "serial_link/protocol/frame_validator.h" -#include "serial_link/protocol/physical.h" -#include - -// This implements the "Consistent overhead byte stuffing protocol" -// https://en.wikipedia.org/wiki/Consistent_Overhead_Byte_Stuffing -// http://www.stuartcheshire.org/papers/COBSforToN.pdf - -#define MAX_FRAME_SIZE 1024 -#define NUM_LINKS 2 - -typedef struct byte_stuffer_state { - uint16_t next_zero; - uint16_t data_pos; - bool long_frame; - uint8_t data[MAX_FRAME_SIZE]; -}byte_stuffer_state_t; - -static byte_stuffer_state_t states[NUM_LINKS]; - -void init_byte_stuffer_state(byte_stuffer_state_t* state) { - state->next_zero = 0; - state->data_pos = 0; - state->long_frame = false; -} - -void init_byte_stuffer(void) { - int i; - for (i=0;inext_zero == 0) { - state->next_zero = data; - state->long_frame = data == 0xFF; - state->data_pos = 0; - return; - } - - state->next_zero--; - if (data == 0) { - if (state->next_zero == 0) { - // The frame is completed - if (state->data_pos > 0) { - validator_recv_frame(link, state->data, state->data_pos); - } - } - else { - // The frame is invalid, so reset - init_byte_stuffer_state(state); - } - } - else { - if (state->data_pos == MAX_FRAME_SIZE) { - // We exceeded our maximum frame size - // therefore there's nothing else to do than reset to a new frame - state->next_zero = data; - state->long_frame = data == 0xFF; - state->data_pos = 0; - } - else if (state->next_zero == 0) { - if (state->long_frame) { - // This is part of a long frame, so continue - state->next_zero = data; - state->long_frame = data == 0xFF; - } - else { - // Special case for zeroes - state->next_zero = data; - state->data[state->data_pos++] = 0; - } - } - else { - state->data[state->data_pos++] = data; - } - } -} - -static void send_block(uint8_t link, uint8_t* start, uint8_t* end, uint8_t num_non_zero) { - send_data(link, &num_non_zero, 1); - if (end > start) { - send_data(link, start, end-start); - } -} - -void byte_stuffer_send_frame(uint8_t link, uint8_t* data, uint16_t size) { - const uint8_t zero = 0; - if (size > 0) { - uint16_t num_non_zero = 1; - uint8_t* end = data + size; - uint8_t* start = data; - while (data < end) { - if (num_non_zero == 0xFF) { - // There's more data after big non-zero block - // So send it, and start a new block - send_block(link, start, data, num_non_zero); - start = data; - num_non_zero = 1; - } - else { - if (*data == 0) { - // A zero encountered, so send the block - send_block(link, start, data, num_non_zero); - start = data + 1; - num_non_zero = 1; - } - else { - num_non_zero++; - } - ++data; - } - } - send_block(link, start, data, num_non_zero); - send_data(link, &zero, 1); - } -} diff --git a/quantum/serial_link/serial_link/protocol/byte_stuffer.h b/quantum/serial_link/serial_link/protocol/byte_stuffer.h deleted file mode 100644 index 2cc88beb4..000000000 --- a/quantum/serial_link/serial_link/protocol/byte_stuffer.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#ifndef SERIAL_LINK_BYTE_STUFFER_H -#define SERIAL_LINK_BYTE_STUFFER_H - -#include - -void init_byte_stuffer(void); -void byte_stuffer_recv_byte(uint8_t link, uint8_t data); -void byte_stuffer_send_frame(uint8_t link, uint8_t* data, uint16_t size); - -#endif diff --git a/quantum/serial_link/serial_link/protocol/frame_router.c b/quantum/serial_link/serial_link/protocol/frame_router.c deleted file mode 100644 index 04b8c2e75..000000000 --- a/quantum/serial_link/serial_link/protocol/frame_router.c +++ /dev/null @@ -1,69 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "serial_link/protocol/frame_router.h" -#include "serial_link/protocol/transport.h" -#include "serial_link/protocol/frame_validator.h" - -static bool is_master; - -void router_set_master(bool master) { - is_master = master; -} - -void route_incoming_frame(uint8_t link, uint8_t* data, uint16_t size){ - if (is_master) { - if (link == DOWN_LINK) { - transport_recv_frame(data[size-1], data, size - 1); - } - } - else { - if (link == UP_LINK) { - if (data[size-1] & 1) { - transport_recv_frame(0, data, size - 1); - } - data[size-1] >>= 1; - validator_send_frame(DOWN_LINK, data, size); - } - else { - data[size-1]++; - validator_send_frame(UP_LINK, data, size); - } - } -} - -void router_send_frame(uint8_t destination, uint8_t* data, uint16_t size) { - if (destination == 0) { - if (!is_master) { - data[size] = 1; - validator_send_frame(UP_LINK, data, size + 1); - } - } - else { - if (is_master) { - data[size] = destination; - validator_send_frame(DOWN_LINK, data, size + 1); - } - } -} diff --git a/quantum/serial_link/serial_link/protocol/frame_router.h b/quantum/serial_link/serial_link/protocol/frame_router.h deleted file mode 100644 index 712250ff3..000000000 --- a/quantum/serial_link/serial_link/protocol/frame_router.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#ifndef SERIAL_LINK_FRAME_ROUTER_H -#define SERIAL_LINK_FRAME_ROUTER_H - -#include -#include - -#define UP_LINK 0 -#define DOWN_LINK 1 - -void router_set_master(bool master); -void route_incoming_frame(uint8_t link, uint8_t* data, uint16_t size); -void router_send_frame(uint8_t destination, uint8_t* data, uint16_t size); - -#endif diff --git a/quantum/serial_link/serial_link/protocol/frame_validator.c b/quantum/serial_link/serial_link/protocol/frame_validator.c deleted file mode 100644 index 474f80ee8..000000000 --- a/quantum/serial_link/serial_link/protocol/frame_validator.c +++ /dev/null @@ -1,121 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "serial_link/protocol/frame_validator.h" -#include "serial_link/protocol/frame_router.h" -#include "serial_link/protocol/byte_stuffer.h" -#include - -const uint32_t poly8_lookup[256] = -{ - 0, 0x77073096, 0xEE0E612C, 0x990951BA, - 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, - 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, - 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, - 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, - 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, - 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, - 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, - 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, - 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, - 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, - 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, - 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, - 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, - 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, - 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, - 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, - 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, - 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, - 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, - 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, - 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, - 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, - 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, - 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, - 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, - 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, - 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, - 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, - 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, - 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, - 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, - 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, - 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, - 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, - 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, - 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, - 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, - 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, - 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, - 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, - 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, - 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, - 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, - 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, - 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, - 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, - 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, - 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, - 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, - 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, - 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, - 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, - 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, - 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, - 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, - 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, - 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, - 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, - 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, - 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, - 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, - 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, - 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D -}; - -static uint32_t crc32_byte(uint8_t *p, uint32_t bytelength) -{ - uint32_t crc = 0xffffffff; - while (bytelength-- !=0) crc = poly8_lookup[((uint8_t) crc ^ *(p++))] ^ (crc >> 8); - // return (~crc); also works - return (crc ^ 0xffffffff); -} - -void validator_recv_frame(uint8_t link, uint8_t* data, uint16_t size) { - if (size > 4) { - uint32_t frame_crc; - memcpy(&frame_crc, data + size -4, 4); - uint32_t expected_crc = crc32_byte(data, size - 4); - if (frame_crc == expected_crc) { - route_incoming_frame(link, data, size-4); - } - } -} - -void validator_send_frame(uint8_t link, uint8_t* data, uint16_t size) { - uint32_t crc = crc32_byte(data, size); - memcpy(data + size, &crc, 4); - byte_stuffer_send_frame(link, data, size + 4); -} diff --git a/quantum/serial_link/serial_link/protocol/frame_validator.h b/quantum/serial_link/serial_link/protocol/frame_validator.h deleted file mode 100644 index 4a910d510..000000000 --- a/quantum/serial_link/serial_link/protocol/frame_validator.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#ifndef SERIAL_LINK_FRAME_VALIDATOR_H -#define SERIAL_LINK_FRAME_VALIDATOR_H - -#include - -void validator_recv_frame(uint8_t link, uint8_t* data, uint16_t size); -// The buffer pointed to by the data needs 4 additional bytes -void validator_send_frame(uint8_t link, uint8_t* data, uint16_t size); - -#endif diff --git a/quantum/serial_link/serial_link/protocol/physical.h b/quantum/serial_link/serial_link/protocol/physical.h deleted file mode 100644 index 425e06cdd..000000000 --- a/quantum/serial_link/serial_link/protocol/physical.h +++ /dev/null @@ -1,30 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#ifndef SERIAL_LINK_PHYSICAL_H -#define SERIAL_LINK_PHYSICAL_H - -void send_data(uint8_t link, const uint8_t* data, uint16_t size); - -#endif diff --git a/quantum/serial_link/serial_link/protocol/transport.c b/quantum/serial_link/serial_link/protocol/transport.c deleted file mode 100644 index f418d11ce..000000000 --- a/quantum/serial_link/serial_link/protocol/transport.c +++ /dev/null @@ -1,124 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "serial_link/protocol/transport.h" -#include "serial_link/protocol/frame_router.h" -#include "serial_link/protocol/triple_buffered_object.h" -#include - -#define MAX_REMOTE_OBJECTS 16 -static remote_object_t* remote_objects[MAX_REMOTE_OBJECTS]; -static uint32_t num_remote_objects = 0; - -void add_remote_objects(remote_object_t** _remote_objects, uint32_t _num_remote_objects) { - unsigned int i; - for(i=0;i<_num_remote_objects;i++) { - remote_object_t* obj = _remote_objects[i]; - remote_objects[num_remote_objects++] = obj; - if (obj->object_type == MASTER_TO_ALL_SLAVES) { - triple_buffer_object_t* tb = (triple_buffer_object_t*)obj->buffer; - triple_buffer_init(tb); - uint8_t* start = obj->buffer + LOCAL_OBJECT_SIZE(obj->object_size); - tb = (triple_buffer_object_t*)start; - triple_buffer_init(tb); - } - else if(obj->object_type == MASTER_TO_SINGLE_SLAVE) { - uint8_t* start = obj->buffer; - unsigned int j; - for (j=0;jobject_size); - } - triple_buffer_object_t* tb = (triple_buffer_object_t*)start; - triple_buffer_init(tb); - } - else { - uint8_t* start = obj->buffer; - triple_buffer_object_t* tb = (triple_buffer_object_t*)start; - triple_buffer_init(tb); - start += LOCAL_OBJECT_SIZE(obj->object_size); - unsigned int j; - for (j=0;jobject_size); - } - } - } -} - -void transport_recv_frame(uint8_t from, uint8_t* data, uint16_t size) { - uint8_t id = data[size-1]; - if (id < num_remote_objects) { - remote_object_t* obj = remote_objects[id]; - if (obj->object_size == size - 1) { - uint8_t* start; - if (obj->object_type == MASTER_TO_ALL_SLAVES) { - start = obj->buffer + LOCAL_OBJECT_SIZE(obj->object_size); - } - else if(obj->object_type == SLAVE_TO_MASTER) { - start = obj->buffer + LOCAL_OBJECT_SIZE(obj->object_size); - start += (from - 1) * REMOTE_OBJECT_SIZE(obj->object_size); - } - else { - start = obj->buffer + NUM_SLAVES * LOCAL_OBJECT_SIZE(obj->object_size); - } - triple_buffer_object_t* tb = (triple_buffer_object_t*)start; - void* ptr = triple_buffer_begin_write_internal(obj->object_size, tb); - memcpy(ptr, data, size - 1); - triple_buffer_end_write_internal(tb); - } - } -} - -void update_transport(void) { - unsigned int i; - for(i=0;iobject_type == MASTER_TO_ALL_SLAVES || obj->object_type == SLAVE_TO_MASTER) { - triple_buffer_object_t* tb = (triple_buffer_object_t*)obj->buffer; - uint8_t* ptr = (uint8_t*)triple_buffer_read_internal(obj->object_size + LOCAL_OBJECT_EXTRA, tb); - if (ptr) { - ptr[obj->object_size] = i; - uint8_t dest = obj->object_type == MASTER_TO_ALL_SLAVES ? 0xFF : 0; - router_send_frame(dest, ptr, obj->object_size + 1); - } - } - else { - uint8_t* start = obj->buffer; - unsigned int j; - for (j=0;jobject_size + LOCAL_OBJECT_EXTRA, tb); - if (ptr) { - ptr[obj->object_size] = i; - uint8_t dest = j + 1; - router_send_frame(dest, ptr, obj->object_size + 1); - } - start += LOCAL_OBJECT_SIZE(obj->object_size); - } - } - } -} diff --git a/quantum/serial_link/serial_link/protocol/transport.h b/quantum/serial_link/serial_link/protocol/transport.h deleted file mode 100644 index 9a052d880..000000000 --- a/quantum/serial_link/serial_link/protocol/transport.h +++ /dev/null @@ -1,151 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#ifndef SERIAL_LINK_TRANSPORT_H -#define SERIAL_LINK_TRANSPORT_H - -#include "serial_link/protocol/triple_buffered_object.h" -#include "serial_link/system/serial_link.h" - -#define NUM_SLAVES 8 -#define LOCAL_OBJECT_EXTRA 16 - -// master -> slave = 1 local(target all), 1 remote object -// slave -> master = 1 local(target 0), multiple remote objects -// master -> single slave (multiple local, target id), 1 remote object -typedef enum { - MASTER_TO_ALL_SLAVES, - MASTER_TO_SINGLE_SLAVE, - SLAVE_TO_MASTER, -} remote_object_type; - -typedef struct { - remote_object_type object_type; - uint16_t object_size; - uint8_t buffer[] __attribute__((aligned(4))); -} remote_object_t; - -#define REMOTE_OBJECT_SIZE(objectsize) \ - (sizeof(triple_buffer_object_t) + objectsize * 3) -#define LOCAL_OBJECT_SIZE(objectsize) \ - (sizeof(triple_buffer_object_t) + (objectsize + LOCAL_OBJECT_EXTRA) * 3) - -#define REMOTE_OBJECT_HELPER(name, type, num_local, num_remote) \ -typedef struct { \ - remote_object_t object; \ - uint8_t buffer[ \ - num_remote * REMOTE_OBJECT_SIZE(sizeof(type)) + \ - num_local * LOCAL_OBJECT_SIZE(sizeof(type))]; \ -} remote_object_##name##_t; - -#define MASTER_TO_ALL_SLAVES_OBJECT(name, type) \ - REMOTE_OBJECT_HELPER(name, type, 1, 1) \ - remote_object_##name##_t remote_object_##name = { \ - .object = { \ - .object_type = MASTER_TO_ALL_SLAVES, \ - .object_size = sizeof(type), \ - } \ - }; \ - type* begin_write_##name(void) { \ - remote_object_t* obj = (remote_object_t*)&remote_object_##name; \ - triple_buffer_object_t* tb = (triple_buffer_object_t*)obj->buffer; \ - return (type*)triple_buffer_begin_write_internal(sizeof(type) + LOCAL_OBJECT_EXTRA, tb); \ - }\ - void end_write_##name(void) { \ - remote_object_t* obj = (remote_object_t*)&remote_object_##name; \ - triple_buffer_object_t* tb = (triple_buffer_object_t*)obj->buffer; \ - triple_buffer_end_write_internal(tb); \ - signal_data_written(); \ - }\ - type* read_##name(void) { \ - remote_object_t* obj = (remote_object_t*)&remote_object_##name; \ - uint8_t* start = obj->buffer + LOCAL_OBJECT_SIZE(obj->object_size);\ - triple_buffer_object_t* tb = (triple_buffer_object_t*)start; \ - return triple_buffer_read_internal(obj->object_size, tb); \ - } - -#define MASTER_TO_SINGLE_SLAVE_OBJECT(name, type) \ - REMOTE_OBJECT_HELPER(name, type, NUM_SLAVES, 1) \ - remote_object_##name##_t remote_object_##name = { \ - .object = { \ - .object_type = MASTER_TO_SINGLE_SLAVE, \ - .object_size = sizeof(type), \ - } \ - }; \ - type* begin_write_##name(uint8_t slave) { \ - remote_object_t* obj = (remote_object_t*)&remote_object_##name; \ - uint8_t* start = obj->buffer;\ - start += slave * LOCAL_OBJECT_SIZE(obj->object_size); \ - triple_buffer_object_t* tb = (triple_buffer_object_t*)start; \ - return (type*)triple_buffer_begin_write_internal(sizeof(type) + LOCAL_OBJECT_EXTRA, tb); \ - }\ - void end_write_##name(uint8_t slave) { \ - remote_object_t* obj = (remote_object_t*)&remote_object_##name; \ - uint8_t* start = obj->buffer;\ - start += slave * LOCAL_OBJECT_SIZE(obj->object_size); \ - triple_buffer_object_t* tb = (triple_buffer_object_t*)start; \ - triple_buffer_end_write_internal(tb); \ - signal_data_written(); \ - }\ - type* read_##name() { \ - remote_object_t* obj = (remote_object_t*)&remote_object_##name; \ - uint8_t* start = obj->buffer + NUM_SLAVES * LOCAL_OBJECT_SIZE(obj->object_size);\ - triple_buffer_object_t* tb = (triple_buffer_object_t*)start; \ - return triple_buffer_read_internal(obj->object_size, tb); \ - } - -#define SLAVE_TO_MASTER_OBJECT(name, type) \ - REMOTE_OBJECT_HELPER(name, type, 1, NUM_SLAVES) \ - remote_object_##name##_t remote_object_##name = { \ - .object = { \ - .object_type = SLAVE_TO_MASTER, \ - .object_size = sizeof(type), \ - } \ - }; \ - type* begin_write_##name(void) { \ - remote_object_t* obj = (remote_object_t*)&remote_object_##name; \ - triple_buffer_object_t* tb = (triple_buffer_object_t*)obj->buffer; \ - return (type*)triple_buffer_begin_write_internal(sizeof(type) + LOCAL_OBJECT_EXTRA, tb); \ - }\ - void end_write_##name(void) { \ - remote_object_t* obj = (remote_object_t*)&remote_object_##name; \ - triple_buffer_object_t* tb = (triple_buffer_object_t*)obj->buffer; \ - triple_buffer_end_write_internal(tb); \ - signal_data_written(); \ - }\ - type* read_##name(uint8_t slave) { \ - remote_object_t* obj = (remote_object_t*)&remote_object_##name; \ - uint8_t* start = obj->buffer + LOCAL_OBJECT_SIZE(obj->object_size);\ - start+=slave * REMOTE_OBJECT_SIZE(obj->object_size); \ - triple_buffer_object_t* tb = (triple_buffer_object_t*)start; \ - return triple_buffer_read_internal(obj->object_size, tb); \ - } - -#define REMOTE_OBJECT(name) (remote_object_t*)&remote_object_##name - -void add_remote_objects(remote_object_t** remote_objects, uint32_t num_remote_objects); -void transport_recv_frame(uint8_t from, uint8_t* data, uint16_t size); -void update_transport(void); - -#endif diff --git a/quantum/serial_link/serial_link/protocol/triple_buffered_object.c b/quantum/serial_link/serial_link/protocol/triple_buffered_object.c deleted file mode 100644 index e3e8989d3..000000000 --- a/quantum/serial_link/serial_link/protocol/triple_buffered_object.c +++ /dev/null @@ -1,78 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "serial_link/protocol/triple_buffered_object.h" -#include "serial_link/system/serial_link.h" -#include -#include - -#define GET_READ_INDEX() object->state & 3 -#define GET_WRITE_INDEX() (object->state >> 2) & 3 -#define GET_SHARED_INDEX() (object->state >> 4) & 3 -#define GET_DATA_AVAILABLE() (object->state >> 6) & 1 - -#define SET_READ_INDEX(i) object->state = ((object->state & ~3) | i) -#define SET_WRITE_INDEX(i) object->state = ((object->state & ~(3 << 2)) | (i << 2)) -#define SET_SHARED_INDEX(i) object->state = ((object->state & ~(3 << 4)) | (i << 4)) -#define SET_DATA_AVAILABLE(i) object->state = ((object->state & ~(1 << 6)) | (i << 6)) - -void triple_buffer_init(triple_buffer_object_t* object) { - object->state = 0; - SET_WRITE_INDEX(0); - SET_READ_INDEX(1); - SET_SHARED_INDEX(2); - SET_DATA_AVAILABLE(0); -} - -void* triple_buffer_read_internal(uint16_t object_size, triple_buffer_object_t* object) { - serial_link_lock(); - if (GET_DATA_AVAILABLE()) { - uint8_t shared_index = GET_SHARED_INDEX(); - uint8_t read_index = GET_READ_INDEX(); - SET_READ_INDEX(shared_index); - SET_SHARED_INDEX(read_index); - SET_DATA_AVAILABLE(false); - serial_link_unlock(); - return object->buffer + object_size * shared_index; - } - else { - serial_link_unlock(); - return NULL; - } -} - -void* triple_buffer_begin_write_internal(uint16_t object_size, triple_buffer_object_t* object) { - uint8_t write_index = GET_WRITE_INDEX(); - return object->buffer + object_size * write_index; -} - -void triple_buffer_end_write_internal(triple_buffer_object_t* object) { - serial_link_lock(); - uint8_t shared_index = GET_SHARED_INDEX(); - uint8_t write_index = GET_WRITE_INDEX(); - SET_SHARED_INDEX(write_index); - SET_WRITE_INDEX(shared_index); - SET_DATA_AVAILABLE(true); - serial_link_unlock(); -} diff --git a/quantum/serial_link/serial_link/protocol/triple_buffered_object.h b/quantum/serial_link/serial_link/protocol/triple_buffered_object.h deleted file mode 100644 index 2e57db3f5..000000000 --- a/quantum/serial_link/serial_link/protocol/triple_buffered_object.h +++ /dev/null @@ -1,51 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#ifndef SERIAL_LINK_TRIPLE_BUFFERED_OBJECT_H -#define SERIAL_LINK_TRIPLE_BUFFERED_OBJECT_H - -#include - -typedef struct { - uint8_t state; - uint8_t buffer[] __attribute__((aligned(4))); -}triple_buffer_object_t; - -void triple_buffer_init(triple_buffer_object_t* object); - -#define triple_buffer_begin_write(object) \ - (typeof(*object.buffer[0])*)triple_buffer_begin_write_internal(sizeof(*object.buffer[0]), (triple_buffer_object_t*)object) - -#define triple_buffer_end_write(object) \ - triple_buffer_end_write_internal((triple_buffer_object_t*)object) - -#define triple_buffer_read(object) \ - (typeof(*object.buffer[0])*)triple_buffer_read_internal(sizeof(*object.buffer[0]), (triple_buffer_object_t*)object) - -void* triple_buffer_begin_write_internal(uint16_t object_size, triple_buffer_object_t* object); -void triple_buffer_end_write_internal(triple_buffer_object_t* object); -void* triple_buffer_read_internal(uint16_t object_size, triple_buffer_object_t* object); - - -#endif diff --git a/quantum/serial_link/serial_link/system/serial_link.c b/quantum/serial_link/serial_link/system/serial_link.c deleted file mode 100644 index 75c7e77a7..000000000 --- a/quantum/serial_link/serial_link/system/serial_link.c +++ /dev/null @@ -1,265 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ -#include "report.h" -#include "host_driver.h" -#include "serial_link/system/serial_link.h" -#include "hal.h" -#include "serial_link/protocol/byte_stuffer.h" -#include "serial_link/protocol/transport.h" -#include "serial_link/protocol/frame_router.h" -#include "matrix.h" -#include -#include "print.h" -#include "config.h" - -static event_source_t new_data_event; -static bool serial_link_connected; -static bool is_master = false; - -static uint8_t keyboard_leds(void); -static void send_keyboard(report_keyboard_t *report); -static void send_mouse(report_mouse_t *report); -static void send_system(uint16_t data); -static void send_consumer(uint16_t data); - -host_driver_t serial_driver = { - keyboard_leds, - send_keyboard, - send_mouse, - send_system, - send_consumer -}; - -// Define these in your Config.h file -#ifndef SERIAL_LINK_BAUD -#error "Serial link baud is not set" -#endif - -#ifndef SERIAL_LINK_THREAD_PRIORITY -#error "Serial link thread priority not set" -#endif - -static SerialConfig config = { - .sc_speed = SERIAL_LINK_BAUD -}; - -//#define DEBUG_LINK_ERRORS - -static uint32_t read_from_serial(SerialDriver* driver, uint8_t link) { - const uint32_t buffer_size = 16; - uint8_t buffer[buffer_size]; - uint32_t bytes_read = sdAsynchronousRead(driver, buffer, buffer_size); - uint8_t* current = buffer; - uint8_t* end = current + bytes_read; - while(current < end) { - byte_stuffer_recv_byte(link, *current); - current++; - } - return bytes_read; -} - -static void print_error(char* str, eventflags_t flags, SerialDriver* driver) { -#ifdef DEBUG_LINK_ERRORS - if (flags & SD_PARITY_ERROR) { - print(str); - print(" Parity error\n"); - } - if (flags & SD_FRAMING_ERROR) { - print(str); - print(" Framing error\n"); - } - if (flags & SD_OVERRUN_ERROR) { - print(str); - uint32_t size = qSpaceI(&(driver->iqueue)); - xprintf(" Overrun error, queue size %d\n", size); - - } - if (flags & SD_NOISE_ERROR) { - print(str); - print(" Noise error\n"); - } - if (flags & SD_BREAK_DETECTED) { - print(str); - print(" Break detected\n"); - } -#else - (void)str; - (void)flags; - (void)driver; -#endif -} - -bool is_serial_link_master(void) { - return is_master; -} - -// TODO: Optimize the stack size, this is probably way too big -static THD_WORKING_AREA(serialThreadStack, 1024); -static THD_FUNCTION(serialThread, arg) { - (void)arg; - event_listener_t new_data_listener; - event_listener_t sd1_listener; - event_listener_t sd2_listener; - chEvtRegister(&new_data_event, &new_data_listener, 0); - eventflags_t events = CHN_INPUT_AVAILABLE - | SD_PARITY_ERROR | SD_FRAMING_ERROR | SD_OVERRUN_ERROR | SD_NOISE_ERROR | SD_BREAK_DETECTED; - chEvtRegisterMaskWithFlags(chnGetEventSource(&SD1), - &sd1_listener, - EVENT_MASK(1), - events); - chEvtRegisterMaskWithFlags(chnGetEventSource(&SD2), - &sd2_listener, - EVENT_MASK(2), - events); - bool need_wait = false; - while(true) { - eventflags_t flags1 = 0; - eventflags_t flags2 = 0; - if (need_wait) { - eventmask_t mask = chEvtWaitAnyTimeout(ALL_EVENTS, MS2ST(1000)); - if (mask & EVENT_MASK(1)) { - flags1 = chEvtGetAndClearFlags(&sd1_listener); - print_error("DOWNLINK", flags1, &SD1); - } - if (mask & EVENT_MASK(2)) { - flags2 = chEvtGetAndClearFlags(&sd2_listener); - print_error("UPLINK", flags2, &SD2); - } - } - - // Always stay as master, even if the USB goes into sleep mode - is_master |= usbGetDriverStateI(&USBD1) == USB_ACTIVE; - router_set_master(is_master); - - need_wait = true; - need_wait &= read_from_serial(&SD2, UP_LINK) == 0; - need_wait &= read_from_serial(&SD1, DOWN_LINK) == 0; - update_transport(); - } -} - -void send_data(uint8_t link, const uint8_t* data, uint16_t size) { - if (link == DOWN_LINK) { - sdWrite(&SD1, data, size); - } - else { - sdWrite(&SD2, data, size); - } -} - -static systime_t last_update = 0; - -typedef struct { - matrix_row_t rows[MATRIX_ROWS]; -} matrix_object_t; - -static matrix_object_t last_matrix = {}; - -SLAVE_TO_MASTER_OBJECT(keyboard_matrix, matrix_object_t); -MASTER_TO_ALL_SLAVES_OBJECT(serial_link_connected, bool); - -static remote_object_t* remote_objects[] = { - REMOTE_OBJECT(serial_link_connected), - REMOTE_OBJECT(keyboard_matrix), -}; - -void init_serial_link(void) { - serial_link_connected = false; - init_serial_link_hal(); - add_remote_objects(remote_objects, sizeof(remote_objects)/sizeof(remote_object_t*)); - init_byte_stuffer(); - sdStart(&SD1, &config); - sdStart(&SD2, &config); - chEvtObjectInit(&new_data_event); - (void)chThdCreateStatic(serialThreadStack, sizeof(serialThreadStack), - SERIAL_LINK_THREAD_PRIORITY, serialThread, NULL); -} - -void matrix_set_remote(matrix_row_t* rows, uint8_t index); - -void serial_link_update(void) { - if (read_serial_link_connected()) { - serial_link_connected = true; - } - - matrix_object_t matrix; - bool changed = false; - for(uint8_t i=0;i US2ST(1000)) { - last_update = current_time; - last_matrix = matrix; - matrix_object_t* m = begin_write_keyboard_matrix(); - for(uint8_t i=0;irows[i] = matrix.rows[i]; - } - end_write_keyboard_matrix(); - *begin_write_serial_link_connected() = true; - end_write_serial_link_connected(); - } - - matrix_object_t* m = read_keyboard_matrix(0); - if (m) { - matrix_set_remote(m->rows, 0); - } -} - -void signal_data_written(void) { - chEvtBroadcast(&new_data_event); -} - -bool is_serial_link_connected(void) { - return serial_link_connected; -} - -host_driver_t* get_serial_link_driver(void) { - return &serial_driver; -} - -// NOTE: The driver does nothing, because the master handles everything -uint8_t keyboard_leds(void) { - return 0; -} - -void send_keyboard(report_keyboard_t *report) { - (void)report; -} - -void send_mouse(report_mouse_t *report) { - (void)report; -} - -void send_system(uint16_t data) { - (void)data; -} - -void send_consumer(uint16_t data) { - (void)data; -} - diff --git a/quantum/serial_link/serial_link/system/serial_link.h b/quantum/serial_link/serial_link/system/serial_link.h deleted file mode 100644 index 351e03877..000000000 --- a/quantum/serial_link/serial_link/system/serial_link.h +++ /dev/null @@ -1,63 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#ifndef SERIAL_LINK_H -#define SERIAL_LINK_H - -#include "host_driver.h" -#include - -void init_serial_link(void); -void init_serial_link_hal(void); -bool is_serial_link_connected(void); -bool is_serial_link_master(void); -host_driver_t* get_serial_link_driver(void); -void serial_link_update(void); - -#if defined(PROTOCOL_CHIBIOS) -#include "ch.h" - -static inline void serial_link_lock(void) { - chSysLock(); -} - -static inline void serial_link_unlock(void) { - chSysUnlock(); -} - -void signal_data_written(void); - -#else - -inline void serial_link_lock(void) { -} - -inline void serial_link_unlock(void) { -} - -void signal_data_written(void); - -#endif - -#endif diff --git a/quantum/serial_link/serial_link/tests/Makefile b/quantum/serial_link/serial_link/tests/Makefile deleted file mode 100644 index 1b072c6f1..000000000 --- a/quantum/serial_link/serial_link/tests/Makefile +++ /dev/null @@ -1,61 +0,0 @@ -# The MIT License (MIT) -# -# Copyright (c) 2016 Fred Sundvik -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -CC = gcc -CFLAGS = -INCLUDES = -I. -I../../ -LDFLAGS = -L$(BUILDDIR)/cgreen/build-c/src -shared -LDLIBS = -lcgreen -UNITOBJ = $(BUILDDIR)/serialtest/unitobj -DEPDIR = $(BUILDDIR)/serialtest/unit.d -UNITTESTS = $(BUILDDIR)/serialtest/unittests -DEPFLAGS = -MT $@ -MMD -MP -MF $(DEPDIR)/$*.Td -EXT = .so -UNAME := $(shell uname) -ifneq (, $(findstring MINGW, $(UNAME))) - EXT = .dll -endif -ifneq (, $(findstring CYGWIN, $(UNAME))) - EXT = .dll -endif - -SRC = $(wildcard *.c) -TESTFILES = $(patsubst %.c, $(UNITTESTS)/%$(EXT), $(SRC)) -$(shell mkdir -p $(DEPDIR) >/dev/null) - -test: $(TESTFILES) - @$(BUILDDIR)/cgreen/build-c/tools/cgreen-runner --color $(TESTFILES) - -$(UNITTESTS)/%$(EXT): $(UNITOBJ)/%.o - @mkdir -p $(UNITTESTS) - $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) - -$(UNITOBJ)/%.o : %.c -$(UNITOBJ)/%.o: %.c $(DEPDIR)/%.d - @mkdir -p $(UNITOBJ) - $(CC) $(CFLAGS) $(DEPFLAGS) $(INCLUDES) -c $< -o $@ - @mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d - -$(DEPDIR)/%.d: ; -.PRECIOUS: $(DEPDIR)/%.d - --include $(patsubst %,$(DEPDIR)/%.d,$(basename $(SRC))) \ No newline at end of file diff --git a/quantum/serial_link/serial_link/tests/byte_stuffer_tests.c b/quantum/serial_link/serial_link/tests/byte_stuffer_tests.c deleted file mode 100644 index 64b170e8c..000000000 --- a/quantum/serial_link/serial_link/tests/byte_stuffer_tests.c +++ /dev/null @@ -1,506 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include -#include -#include "serial_link/protocol/byte_stuffer.h" -#include "serial_link/protocol/byte_stuffer.c" -#include "serial_link/protocol/frame_validator.h" -#include "serial_link/protocol/physical.h" - -static uint8_t sent_data[MAX_FRAME_SIZE*2]; -static uint16_t sent_data_size; - -Describe(ByteStuffer); -BeforeEach(ByteStuffer) { - init_byte_stuffer(); - sent_data_size = 0; -} -AfterEach(ByteStuffer) {} - -void validator_recv_frame(uint8_t link, uint8_t* data, uint16_t size) { - mock(data, size); -} - -void send_data(uint8_t link, const uint8_t* data, uint16_t size) { - memcpy(sent_data + sent_data_size, data, size); - sent_data_size += size; -} - -Ensure(ByteStuffer, receives_no_frame_for_a_single_zero_byte) { - never_expect(validator_recv_frame); - byte_stuffer_recv_byte(0, 0); -} - -Ensure(ByteStuffer, receives_no_frame_for_a_single_FF_byte) { - never_expect(validator_recv_frame); - byte_stuffer_recv_byte(0, 0xFF); -} - -Ensure(ByteStuffer, receives_no_frame_for_a_single_random_byte) { - never_expect(validator_recv_frame); - byte_stuffer_recv_byte(0, 0x4A); -} - -Ensure(ByteStuffer, receives_no_frame_for_a_zero_length_frame) { - never_expect(validator_recv_frame); - byte_stuffer_recv_byte(0, 1); - byte_stuffer_recv_byte(0, 0); -} - -Ensure(ByteStuffer, receives_single_byte_valid_frame) { - uint8_t expected[] = {0x37}; - expect(validator_recv_frame, - when(size, is_equal_to(1)), - when(data, is_equal_to_contents_of(expected, 1)) - ); - byte_stuffer_recv_byte(0, 2); - byte_stuffer_recv_byte(0, 0x37); - byte_stuffer_recv_byte(0, 0); -} - -Ensure(ByteStuffer, receives_three_bytes_valid_frame) { - uint8_t expected[] = {0x37, 0x99, 0xFF}; - expect(validator_recv_frame, - when(size, is_equal_to(3)), - when(data, is_equal_to_contents_of(expected, 3)) - ); - byte_stuffer_recv_byte(0, 4); - byte_stuffer_recv_byte(0, 0x37); - byte_stuffer_recv_byte(0, 0x99); - byte_stuffer_recv_byte(0, 0xFF); - byte_stuffer_recv_byte(0, 0); -} - -Ensure(ByteStuffer, receives_single_zero_valid_frame) { - uint8_t expected[] = {0}; - expect(validator_recv_frame, - when(size, is_equal_to(1)), - when(data, is_equal_to_contents_of(expected, 1)) - ); - byte_stuffer_recv_byte(0, 1); - byte_stuffer_recv_byte(0, 1); - byte_stuffer_recv_byte(0, 0); -} - -Ensure(ByteStuffer, receives_valid_frame_with_zeroes) { - uint8_t expected[] = {5, 0, 3, 0}; - expect(validator_recv_frame, - when(size, is_equal_to(4)), - when(data, is_equal_to_contents_of(expected, 4)) - ); - byte_stuffer_recv_byte(0, 2); - byte_stuffer_recv_byte(0, 5); - byte_stuffer_recv_byte(0, 2); - byte_stuffer_recv_byte(0, 3); - byte_stuffer_recv_byte(0, 1); - byte_stuffer_recv_byte(0, 0); -} - -Ensure(ByteStuffer, receives_two_valid_frames) { - uint8_t expected1[] = {5, 0}; - uint8_t expected2[] = {3}; - expect(validator_recv_frame, - when(size, is_equal_to(2)), - when(data, is_equal_to_contents_of(expected1, 2)) - ); - expect(validator_recv_frame, - when(size, is_equal_to(1)), - when(data, is_equal_to_contents_of(expected2, 1)) - ); - byte_stuffer_recv_byte(1, 2); - byte_stuffer_recv_byte(1, 5); - byte_stuffer_recv_byte(1, 1); - byte_stuffer_recv_byte(1, 0); - byte_stuffer_recv_byte(1, 2); - byte_stuffer_recv_byte(1, 3); - byte_stuffer_recv_byte(1, 0); -} - -Ensure(ByteStuffer, receives_valid_frame_after_unexpected_zero) { - uint8_t expected[] = {5, 7}; - expect(validator_recv_frame, - when(size, is_equal_to(2)), - when(data, is_equal_to_contents_of(expected, 2)) - ); - byte_stuffer_recv_byte(1, 3); - byte_stuffer_recv_byte(1, 1); - byte_stuffer_recv_byte(1, 0); - byte_stuffer_recv_byte(1, 3); - byte_stuffer_recv_byte(1, 5); - byte_stuffer_recv_byte(1, 7); - byte_stuffer_recv_byte(1, 0); -} - -Ensure(ByteStuffer, receives_valid_frame_after_unexpected_non_zero) { - uint8_t expected[] = {5, 7}; - expect(validator_recv_frame, - when(size, is_equal_to(2)), - when(data, is_equal_to_contents_of(expected, 2)) - ); - byte_stuffer_recv_byte(0, 2); - byte_stuffer_recv_byte(0, 9); - byte_stuffer_recv_byte(0, 4); // This should have been zero - byte_stuffer_recv_byte(0, 0); - byte_stuffer_recv_byte(0, 3); - byte_stuffer_recv_byte(0, 5); - byte_stuffer_recv_byte(0, 7); - byte_stuffer_recv_byte(0, 0); -} - -Ensure(ByteStuffer, receives_a_valid_frame_with_over254_non_zeroes_and_then_end_of_frame) { - uint8_t expected[254]; - int i; - for (i=0;i<254;i++) { - expected[i] = i + 1; - } - expect(validator_recv_frame, - when(size, is_equal_to(254)), - when(data, is_equal_to_contents_of(expected, 254)) - ); - byte_stuffer_recv_byte(0, 0xFF); - for (i=0;i<254;i++) { - byte_stuffer_recv_byte(0, i+1); - } - byte_stuffer_recv_byte(0, 0); -} - -Ensure(ByteStuffer, receives_a_valid_frame_with_over254_non_zeroes_next_byte_is_non_zero) { - uint8_t expected[255]; - int i; - for (i=0;i<254;i++) { - expected[i] = i + 1; - } - expected[254] = 7; - expect(validator_recv_frame, - when(size, is_equal_to(255)), - when(data, is_equal_to_contents_of(expected, 255)) - ); - byte_stuffer_recv_byte(0, 0xFF); - for (i=0;i<254;i++) { - byte_stuffer_recv_byte(0, i+1); - } - byte_stuffer_recv_byte(0, 2); - byte_stuffer_recv_byte(0, 7); - byte_stuffer_recv_byte(0, 0); -} - -Ensure(ByteStuffer, receives_a_valid_frame_with_over254_non_zeroes_next_byte_is_zero) { - uint8_t expected[255]; - int i; - for (i=0;i<254;i++) { - expected[i] = i + 1; - } - expected[254] = 0; - expect(validator_recv_frame, - when(size, is_equal_to(255)), - when(data, is_equal_to_contents_of(expected, 255)) - ); - byte_stuffer_recv_byte(0, 0xFF); - for (i=0;i<254;i++) { - byte_stuffer_recv_byte(0, i+1); - } - byte_stuffer_recv_byte(0, 1); - byte_stuffer_recv_byte(0, 1); - byte_stuffer_recv_byte(0, 0); -} - -Ensure(ByteStuffer, receives_two_long_frames_and_some_more) { - uint8_t expected[515]; - int i; - int j; - for (j=0;j<2;j++) { - for (i=0;i<254;i++) { - expected[i+254*j] = i + 1; - } - } - for (i=0;i<7;i++) { - expected[254*2+i] = i + 1; - } - expect(validator_recv_frame, - when(size, is_equal_to(515)), - when(data, is_equal_to_contents_of(expected, 510)) - ); - byte_stuffer_recv_byte(0, 0xFF); - for (i=0;i<254;i++) { - byte_stuffer_recv_byte(0, i+1); - } - byte_stuffer_recv_byte(0, 0xFF); - for (i=0;i<254;i++) { - byte_stuffer_recv_byte(0, i+1); - } - byte_stuffer_recv_byte(0, 8); - byte_stuffer_recv_byte(0, 1); - byte_stuffer_recv_byte(0, 2); - byte_stuffer_recv_byte(0, 3); - byte_stuffer_recv_byte(0, 4); - byte_stuffer_recv_byte(0, 5); - byte_stuffer_recv_byte(0, 6); - byte_stuffer_recv_byte(0, 7); - byte_stuffer_recv_byte(0, 0); -} - -Ensure(ByteStuffer, receives_an_all_zeros_frame_that_is_maximum_size) { - uint8_t expected[MAX_FRAME_SIZE] = {}; - expect(validator_recv_frame, - when(size, is_equal_to(MAX_FRAME_SIZE)), - when(data, is_equal_to_contents_of(expected, MAX_FRAME_SIZE)) - ); - int i; - byte_stuffer_recv_byte(0, 1); - for(i=0;i -#include -#include "serial_link/protocol/byte_stuffer.c" -#include "serial_link/protocol/frame_validator.c" -#include "serial_link/protocol/frame_router.c" -#include "serial_link/protocol/transport.h" - -static uint8_t received_data[256]; -static uint16_t received_data_size; - -typedef struct { - uint8_t sent_data[256]; - uint16_t sent_data_size; -} receive_buffer_t; - -typedef struct { - receive_buffer_t send_buffers[2]; -} router_buffer_t; - -router_buffer_t router_buffers[8]; - -router_buffer_t* current_router_buffer; - - -Describe(FrameRouter); -BeforeEach(FrameRouter) { - init_byte_stuffer(); - memset(router_buffers, 0, sizeof(router_buffers)); - current_router_buffer = 0; -} -AfterEach(FrameRouter) {} - -typedef struct { - uint32_t data; - uint8_t extra[16]; -} frame_buffer_t; - - -void send_data(uint8_t link, const uint8_t* data, uint16_t size) { - receive_buffer_t* buffer = ¤t_router_buffer->send_buffers[link]; - memcpy(buffer->sent_data + buffer->sent_data_size, data, size); - buffer->sent_data_size += size; -} - -static void receive_data(uint8_t link, uint8_t* data, uint16_t size) { - int i; - for(i=0;i to) { - receive_data(DOWN_LINK, - router_buffers[from].send_buffers[UP_LINK].sent_data, - router_buffers[from].send_buffers[UP_LINK].sent_data_size); - } - else if(to > from) { - receive_data(UP_LINK, - router_buffers[from].send_buffers[DOWN_LINK].sent_data, - router_buffers[from].send_buffers[DOWN_LINK].sent_data_size); - } -} - -void transport_recv_frame(uint8_t from, uint8_t* data, uint16_t size) { - mock(from, data, size); -} - - -Ensure(FrameRouter, master_broadcast_is_received_by_everyone) { - frame_buffer_t data; - data.data = 0xAB7055BB; - activate_router(0); - router_send_frame(0xFF, (uint8_t*)&data, 4); - assert_that(router_buffers[0].send_buffers[DOWN_LINK].sent_data_size, is_greater_than(0)); - assert_that(router_buffers[0].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); - - expect(transport_recv_frame, - when(from, is_equal_to(0)), - when(size, is_equal_to(4)), - when(data, is_equal_to_contents_of(&data.data, 4)) - ); - simulate_transport(0, 1); - assert_that(router_buffers[1].send_buffers[DOWN_LINK].sent_data_size, is_greater_than(0)); - assert_that(router_buffers[1].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); - - expect(transport_recv_frame, - when(from, is_equal_to(0)), - when(size, is_equal_to(4)), - when(data, is_equal_to_contents_of(&data.data, 4)) - ); - simulate_transport(1, 2); - assert_that(router_buffers[2].send_buffers[DOWN_LINK].sent_data_size, is_greater_than(0)); - assert_that(router_buffers[2].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); -} - -Ensure(FrameRouter, master_send_is_received_by_targets) { - frame_buffer_t data; - data.data = 0xAB7055BB; - activate_router(0); - router_send_frame((1 << 1) | (1 << 2), (uint8_t*)&data, 4); - assert_that(router_buffers[0].send_buffers[DOWN_LINK].sent_data_size, is_greater_than(0)); - assert_that(router_buffers[0].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); - - simulate_transport(0, 1); - assert_that(router_buffers[1].send_buffers[DOWN_LINK].sent_data_size, is_greater_than(0)); - assert_that(router_buffers[1].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); - - expect(transport_recv_frame, - when(from, is_equal_to(0)), - when(size, is_equal_to(4)), - when(data, is_equal_to_contents_of(&data.data, 4)) - ); - simulate_transport(1, 2); - assert_that(router_buffers[2].send_buffers[DOWN_LINK].sent_data_size, is_greater_than(0)); - assert_that(router_buffers[2].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); - - expect(transport_recv_frame, - when(from, is_equal_to(0)), - when(size, is_equal_to(4)), - when(data, is_equal_to_contents_of(&data.data, 4)) - ); - simulate_transport(2, 3); - assert_that(router_buffers[3].send_buffers[DOWN_LINK].sent_data_size, is_greater_than(0)); - assert_that(router_buffers[3].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); -} - -Ensure(FrameRouter, first_link_sends_to_master) { - frame_buffer_t data; - data.data = 0xAB7055BB; - activate_router(1); - router_send_frame(0, (uint8_t*)&data, 4); - assert_that(router_buffers[1].send_buffers[UP_LINK].sent_data_size, is_greater_than(0)); - assert_that(router_buffers[1].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0)); - - expect(transport_recv_frame, - when(from, is_equal_to(1)), - when(size, is_equal_to(4)), - when(data, is_equal_to_contents_of(&data.data, 4)) - ); - simulate_transport(1, 0); - assert_that(router_buffers[0].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0)); - assert_that(router_buffers[0].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); -} - -Ensure(FrameRouter, second_link_sends_to_master) { - frame_buffer_t data; - data.data = 0xAB7055BB; - activate_router(2); - router_send_frame(0, (uint8_t*)&data, 4); - assert_that(router_buffers[2].send_buffers[UP_LINK].sent_data_size, is_greater_than(0)); - assert_that(router_buffers[2].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0)); - - simulate_transport(2, 1); - assert_that(router_buffers[1].send_buffers[UP_LINK].sent_data_size, is_greater_than(0)); - assert_that(router_buffers[1].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0)); - - expect(transport_recv_frame, - when(from, is_equal_to(2)), - when(size, is_equal_to(4)), - when(data, is_equal_to_contents_of(&data.data, 4)) - ); - simulate_transport(1, 0); - assert_that(router_buffers[0].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0)); - assert_that(router_buffers[0].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); -} - -Ensure(FrameRouter, master_sends_to_master_does_nothing) { - frame_buffer_t data; - data.data = 0xAB7055BB; - activate_router(0); - router_send_frame(0, (uint8_t*)&data, 4); - assert_that(router_buffers[0].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); - assert_that(router_buffers[0].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0)); -} - -Ensure(FrameRouter, link_sends_to_other_link_does_nothing) { - frame_buffer_t data; - data.data = 0xAB7055BB; - activate_router(1); - router_send_frame(2, (uint8_t*)&data, 4); - assert_that(router_buffers[1].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); - assert_that(router_buffers[1].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0)); -} - -Ensure(FrameRouter, master_receives_on_uplink_does_nothing) { - frame_buffer_t data; - data.data = 0xAB7055BB; - activate_router(1); - router_send_frame(0, (uint8_t*)&data, 4); - assert_that(router_buffers[1].send_buffers[UP_LINK].sent_data_size, is_greater_than(0)); - assert_that(router_buffers[1].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0)); - - never_expect(transport_recv_frame); - activate_router(0); - receive_data(UP_LINK, - router_buffers[1].send_buffers[UP_LINK].sent_data, - router_buffers[1].send_buffers[UP_LINK].sent_data_size); - assert_that(router_buffers[0].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); - assert_that(router_buffers[0].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0)); -} diff --git a/quantum/serial_link/serial_link/tests/frame_validator_tests.c b/quantum/serial_link/serial_link/tests/frame_validator_tests.c deleted file mode 100644 index d20947e2c..000000000 --- a/quantum/serial_link/serial_link/tests/frame_validator_tests.c +++ /dev/null @@ -1,101 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include -#include -#include "serial_link/protocol/frame_validator.c" - -void route_incoming_frame(uint8_t link, uint8_t* data, uint16_t size) { - mock(data, size); -} - -void byte_stuffer_send_frame(uint8_t link, uint8_t* data, uint16_t size) { - mock(data, size); -} - -Describe(FrameValidator); -BeforeEach(FrameValidator) {} -AfterEach(FrameValidator) {} - -Ensure(FrameValidator, doesnt_validate_frames_under_5_bytes) { - never_expect(route_incoming_frame); - uint8_t data[] = {1, 2}; - validator_recv_frame(0, 0, 1); - validator_recv_frame(0, data, 2); - validator_recv_frame(0, data, 3); - validator_recv_frame(0, data, 4); -} - -Ensure(FrameValidator, validates_one_byte_frame_with_correct_crc) { - uint8_t data[] = {0x44, 0x04, 0x6A, 0xB3, 0xA3}; - expect(route_incoming_frame, - when(size, is_equal_to(1)), - when(data, is_equal_to_contents_of(data, 1)) - ); - validator_recv_frame(0, data, 5); -} - -Ensure(FrameValidator, does_not_validate_one_byte_frame_with_incorrect_crc) { - uint8_t data[] = {0x44, 0, 0, 0, 0}; - never_expect(route_incoming_frame); - validator_recv_frame(1, data, 5); -} - -Ensure(FrameValidator, validates_four_byte_frame_with_correct_crc) { - uint8_t data[] = {0x44, 0x10, 0xFF, 0x00, 0x74, 0x4E, 0x30, 0xBA}; - expect(route_incoming_frame, - when(size, is_equal_to(4)), - when(data, is_equal_to_contents_of(data, 4)) - ); - validator_recv_frame(1, data, 8); -} - -Ensure(FrameValidator, validates_five_byte_frame_with_correct_crc) { - uint8_t data[] = {1, 2, 3, 4, 5, 0xF4, 0x99, 0x0B, 0x47}; - expect(route_incoming_frame, - when(size, is_equal_to(5)), - when(data, is_equal_to_contents_of(data, 5)) - ); - validator_recv_frame(0, data, 9); -} - -Ensure(FrameValidator, sends_one_byte_with_correct_crc) { - uint8_t original[] = {0x44, 0, 0, 0, 0}; - uint8_t expected[] = {0x44, 0x04, 0x6A, 0xB3, 0xA3}; - expect(byte_stuffer_send_frame, - when(size, is_equal_to(sizeof(expected))), - when(data, is_equal_to_contents_of(expected, sizeof(expected))) - ); - validator_send_frame(0, original, 1); -} - -Ensure(FrameValidator, sends_five_bytes_with_correct_crc) { - uint8_t original[] = {1, 2, 3, 4, 5, 0, 0, 0, 0}; - uint8_t expected[] = {1, 2, 3, 4, 5, 0xF4, 0x99, 0x0B, 0x47}; - expect(byte_stuffer_send_frame, - when(size, is_equal_to(sizeof(expected))), - when(data, is_equal_to_contents_of(expected, sizeof(expected))) - ); - validator_send_frame(0, original, 5); -} diff --git a/quantum/serial_link/serial_link/tests/transport_tests.c b/quantum/serial_link/serial_link/tests/transport_tests.c deleted file mode 100644 index 358e1b9fd..000000000 --- a/quantum/serial_link/serial_link/tests/transport_tests.c +++ /dev/null @@ -1,168 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include -#include -#include "serial_link/protocol/transport.c" -#include "serial_link/protocol/triple_buffered_object.c" - -void signal_data_written(void) { - mock(); -} - -static uint8_t sent_data[2048]; -static uint16_t sent_data_size; - -void router_send_frame(uint8_t destination, uint8_t* data, uint16_t size) { - mock(destination); - memcpy(sent_data + sent_data_size, data, size); - sent_data_size += size; -} - -typedef struct { - uint32_t test; -} test_object1_t; - -typedef struct { - uint32_t test1; - uint32_t test2; -} test_object2_t; - -MASTER_TO_ALL_SLAVES_OBJECT(master_to_slave, test_object1_t); -MASTER_TO_SINGLE_SLAVE_OBJECT(master_to_single_slave, test_object1_t); -SLAVE_TO_MASTER_OBJECT(slave_to_master, test_object1_t); - -static remote_object_t* test_remote_objects[] = { - REMOTE_OBJECT(master_to_slave), - REMOTE_OBJECT(master_to_single_slave), - REMOTE_OBJECT(slave_to_master), -}; - -Describe(Transport); -BeforeEach(Transport) { - add_remote_objects(test_remote_objects, sizeof(test_remote_objects) / sizeof(remote_object_t*)); - sent_data_size = 0; -} -AfterEach(Transport) {} - -Ensure(Transport, write_to_local_signals_an_event) { - begin_write_master_to_slave(); - expect(signal_data_written); - end_write_master_to_slave(); - begin_write_slave_to_master(); - expect(signal_data_written); - end_write_slave_to_master(); - begin_write_master_to_single_slave(1); - expect(signal_data_written); - end_write_master_to_single_slave(1); -} - -Ensure(Transport, writes_from_master_to_all_slaves) { - update_transport(); - test_object1_t* obj = begin_write_master_to_slave(); - obj->test = 5; - expect(signal_data_written); - end_write_master_to_slave(); - expect(router_send_frame, - when(destination, is_equal_to(0xFF))); - update_transport(); - transport_recv_frame(0, sent_data, sent_data_size); - test_object1_t* obj2 = read_master_to_slave(); - assert_that(obj2, is_not_equal_to(NULL)); - assert_that(obj2->test, is_equal_to(5)); -} - -Ensure(Transport, writes_from_slave_to_master) { - update_transport(); - test_object1_t* obj = begin_write_slave_to_master(); - obj->test = 7; - expect(signal_data_written); - end_write_slave_to_master(); - expect(router_send_frame, - when(destination, is_equal_to(0))); - update_transport(); - transport_recv_frame(3, sent_data, sent_data_size); - test_object1_t* obj2 = read_slave_to_master(2); - assert_that(read_slave_to_master(0), is_equal_to(NULL)); - assert_that(obj2, is_not_equal_to(NULL)); - assert_that(obj2->test, is_equal_to(7)); -} - -Ensure(Transport, writes_from_master_to_single_slave) { - update_transport(); - test_object1_t* obj = begin_write_master_to_single_slave(3); - obj->test = 7; - expect(signal_data_written); - end_write_master_to_single_slave(3); - expect(router_send_frame, - when(destination, is_equal_to(4))); - update_transport(); - transport_recv_frame(0, sent_data, sent_data_size); - test_object1_t* obj2 = read_master_to_single_slave(); - assert_that(obj2, is_not_equal_to(NULL)); - assert_that(obj2->test, is_equal_to(7)); -} - -Ensure(Transport, ignores_object_with_invalid_id) { - update_transport(); - test_object1_t* obj = begin_write_master_to_single_slave(3); - obj->test = 7; - expect(signal_data_written); - end_write_master_to_single_slave(3); - expect(router_send_frame, - when(destination, is_equal_to(4))); - update_transport(); - sent_data[sent_data_size - 1] = 44; - transport_recv_frame(0, sent_data, sent_data_size); - test_object1_t* obj2 = read_master_to_single_slave(); - assert_that(obj2, is_equal_to(NULL)); -} - -Ensure(Transport, ignores_object_with_size_too_small) { - update_transport(); - test_object1_t* obj = begin_write_master_to_slave(); - obj->test = 7; - expect(signal_data_written); - end_write_master_to_slave(); - expect(router_send_frame); - update_transport(); - sent_data[sent_data_size - 2] = 0; - transport_recv_frame(0, sent_data, sent_data_size - 1); - test_object1_t* obj2 = read_master_to_slave(); - assert_that(obj2, is_equal_to(NULL)); -} - -Ensure(Transport, ignores_object_with_size_too_big) { - update_transport(); - test_object1_t* obj = begin_write_master_to_slave(); - obj->test = 7; - expect(signal_data_written); - end_write_master_to_slave(); - expect(router_send_frame); - update_transport(); - sent_data[sent_data_size + 21] = 0; - transport_recv_frame(0, sent_data, sent_data_size + 22); - test_object1_t* obj2 = read_master_to_slave(); - assert_that(obj2, is_equal_to(NULL)); -} diff --git a/quantum/serial_link/serial_link/tests/triple_buffered_object_tests.c b/quantum/serial_link/serial_link/tests/triple_buffered_object_tests.c deleted file mode 100644 index 6f7c82b46..000000000 --- a/quantum/serial_link/serial_link/tests/triple_buffered_object_tests.c +++ /dev/null @@ -1,82 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include -#include "serial_link/protocol/triple_buffered_object.c" - -typedef struct { - uint8_t state; - uint32_t buffer[3]; -}test_object_t; - -test_object_t test_object; - -Describe(TripleBufferedObject); -BeforeEach(TripleBufferedObject) { - triple_buffer_init((triple_buffer_object_t*)&test_object); -} -AfterEach(TripleBufferedObject) {} - - -Ensure(TripleBufferedObject, writes_and_reads_object) { - *triple_buffer_begin_write(&test_object) = 0x3456ABCC; - triple_buffer_end_write(&test_object); - assert_that(*triple_buffer_read(&test_object), is_equal_to(0x3456ABCC)); -} - -Ensure(TripleBufferedObject, does_not_read_empty) { - assert_that(triple_buffer_read(&test_object), is_equal_to(NULL)); -} - -Ensure(TripleBufferedObject, writes_twice_and_reads_object) { - *triple_buffer_begin_write(&test_object) = 0x3456ABCC; - triple_buffer_end_write(&test_object); - *triple_buffer_begin_write(&test_object) = 0x44778899; - triple_buffer_end_write(&test_object); - assert_that(*triple_buffer_read(&test_object), is_equal_to(0x44778899)); -} - -Ensure(TripleBufferedObject, performs_another_write_in_the_middle_of_read) { - *triple_buffer_begin_write(&test_object) = 1; - triple_buffer_end_write(&test_object); - uint32_t* read = triple_buffer_read(&test_object); - *triple_buffer_begin_write(&test_object) = 2; - triple_buffer_end_write(&test_object); - assert_that(*read, is_equal_to(1)); - assert_that(*triple_buffer_read(&test_object), is_equal_to(2)); - assert_that(triple_buffer_read(&test_object), is_equal_to(NULL)); -} - -Ensure(TripleBufferedObject, performs_two_writes_in_the_middle_of_read) { - *triple_buffer_begin_write(&test_object) = 1; - triple_buffer_end_write(&test_object); - uint32_t* read = triple_buffer_read(&test_object); - *triple_buffer_begin_write(&test_object) = 2; - triple_buffer_end_write(&test_object); - *triple_buffer_begin_write(&test_object) = 3; - triple_buffer_end_write(&test_object); - assert_that(*read, is_equal_to(1)); - assert_that(*triple_buffer_read(&test_object), is_equal_to(3)); - assert_that(triple_buffer_read(&test_object), is_equal_to(NULL)); -} diff --git a/quantum/serial_link/serial_link_tests.mk b/quantum/serial_link/serial_link_tests.mk deleted file mode 100644 index e292f582a..000000000 --- a/quantum/serial_link/serial_link_tests.mk +++ /dev/null @@ -1,34 +0,0 @@ -# The MIT License (MIT) -# -# Copyright (c) 2016 Fred Sundvik -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -CGREEN_LIB = $(BUILDDIR)/cgreen/build-c/src/libcgreen.a - -CGREEN_DIR = "$(CURDIR)/$(SERIAL_DIR)/cgreen/cgreen" -CGREEN_BUILD_DIR = "$(CURDIR)/$(BUILDDIR)/cgreen" -export CGREEN_DIR -export CGREEN_BUILD_DIR -$(CGREEN_LIB): - @make -C $(SERIAL_DIR)/cgreen - -.PHONY serialtest: -serialtest : $(CGREEN_LIB) - @make -C $(SERIAL_DIR)/serial_link/tests BUILDDIR=../../../$(BUILDDIR) \ No newline at end of file diff --git a/quantum/serial_link/system/serial_link.c b/quantum/serial_link/system/serial_link.c new file mode 100644 index 000000000..75c7e77a7 --- /dev/null +++ b/quantum/serial_link/system/serial_link.c @@ -0,0 +1,265 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016 Fred Sundvik + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ +#include "report.h" +#include "host_driver.h" +#include "serial_link/system/serial_link.h" +#include "hal.h" +#include "serial_link/protocol/byte_stuffer.h" +#include "serial_link/protocol/transport.h" +#include "serial_link/protocol/frame_router.h" +#include "matrix.h" +#include +#include "print.h" +#include "config.h" + +static event_source_t new_data_event; +static bool serial_link_connected; +static bool is_master = false; + +static uint8_t keyboard_leds(void); +static void send_keyboard(report_keyboard_t *report); +static void send_mouse(report_mouse_t *report); +static void send_system(uint16_t data); +static void send_consumer(uint16_t data); + +host_driver_t serial_driver = { + keyboard_leds, + send_keyboard, + send_mouse, + send_system, + send_consumer +}; + +// Define these in your Config.h file +#ifndef SERIAL_LINK_BAUD +#error "Serial link baud is not set" +#endif + +#ifndef SERIAL_LINK_THREAD_PRIORITY +#error "Serial link thread priority not set" +#endif + +static SerialConfig config = { + .sc_speed = SERIAL_LINK_BAUD +}; + +//#define DEBUG_LINK_ERRORS + +static uint32_t read_from_serial(SerialDriver* driver, uint8_t link) { + const uint32_t buffer_size = 16; + uint8_t buffer[buffer_size]; + uint32_t bytes_read = sdAsynchronousRead(driver, buffer, buffer_size); + uint8_t* current = buffer; + uint8_t* end = current + bytes_read; + while(current < end) { + byte_stuffer_recv_byte(link, *current); + current++; + } + return bytes_read; +} + +static void print_error(char* str, eventflags_t flags, SerialDriver* driver) { +#ifdef DEBUG_LINK_ERRORS + if (flags & SD_PARITY_ERROR) { + print(str); + print(" Parity error\n"); + } + if (flags & SD_FRAMING_ERROR) { + print(str); + print(" Framing error\n"); + } + if (flags & SD_OVERRUN_ERROR) { + print(str); + uint32_t size = qSpaceI(&(driver->iqueue)); + xprintf(" Overrun error, queue size %d\n", size); + + } + if (flags & SD_NOISE_ERROR) { + print(str); + print(" Noise error\n"); + } + if (flags & SD_BREAK_DETECTED) { + print(str); + print(" Break detected\n"); + } +#else + (void)str; + (void)flags; + (void)driver; +#endif +} + +bool is_serial_link_master(void) { + return is_master; +} + +// TODO: Optimize the stack size, this is probably way too big +static THD_WORKING_AREA(serialThreadStack, 1024); +static THD_FUNCTION(serialThread, arg) { + (void)arg; + event_listener_t new_data_listener; + event_listener_t sd1_listener; + event_listener_t sd2_listener; + chEvtRegister(&new_data_event, &new_data_listener, 0); + eventflags_t events = CHN_INPUT_AVAILABLE + | SD_PARITY_ERROR | SD_FRAMING_ERROR | SD_OVERRUN_ERROR | SD_NOISE_ERROR | SD_BREAK_DETECTED; + chEvtRegisterMaskWithFlags(chnGetEventSource(&SD1), + &sd1_listener, + EVENT_MASK(1), + events); + chEvtRegisterMaskWithFlags(chnGetEventSource(&SD2), + &sd2_listener, + EVENT_MASK(2), + events); + bool need_wait = false; + while(true) { + eventflags_t flags1 = 0; + eventflags_t flags2 = 0; + if (need_wait) { + eventmask_t mask = chEvtWaitAnyTimeout(ALL_EVENTS, MS2ST(1000)); + if (mask & EVENT_MASK(1)) { + flags1 = chEvtGetAndClearFlags(&sd1_listener); + print_error("DOWNLINK", flags1, &SD1); + } + if (mask & EVENT_MASK(2)) { + flags2 = chEvtGetAndClearFlags(&sd2_listener); + print_error("UPLINK", flags2, &SD2); + } + } + + // Always stay as master, even if the USB goes into sleep mode + is_master |= usbGetDriverStateI(&USBD1) == USB_ACTIVE; + router_set_master(is_master); + + need_wait = true; + need_wait &= read_from_serial(&SD2, UP_LINK) == 0; + need_wait &= read_from_serial(&SD1, DOWN_LINK) == 0; + update_transport(); + } +} + +void send_data(uint8_t link, const uint8_t* data, uint16_t size) { + if (link == DOWN_LINK) { + sdWrite(&SD1, data, size); + } + else { + sdWrite(&SD2, data, size); + } +} + +static systime_t last_update = 0; + +typedef struct { + matrix_row_t rows[MATRIX_ROWS]; +} matrix_object_t; + +static matrix_object_t last_matrix = {}; + +SLAVE_TO_MASTER_OBJECT(keyboard_matrix, matrix_object_t); +MASTER_TO_ALL_SLAVES_OBJECT(serial_link_connected, bool); + +static remote_object_t* remote_objects[] = { + REMOTE_OBJECT(serial_link_connected), + REMOTE_OBJECT(keyboard_matrix), +}; + +void init_serial_link(void) { + serial_link_connected = false; + init_serial_link_hal(); + add_remote_objects(remote_objects, sizeof(remote_objects)/sizeof(remote_object_t*)); + init_byte_stuffer(); + sdStart(&SD1, &config); + sdStart(&SD2, &config); + chEvtObjectInit(&new_data_event); + (void)chThdCreateStatic(serialThreadStack, sizeof(serialThreadStack), + SERIAL_LINK_THREAD_PRIORITY, serialThread, NULL); +} + +void matrix_set_remote(matrix_row_t* rows, uint8_t index); + +void serial_link_update(void) { + if (read_serial_link_connected()) { + serial_link_connected = true; + } + + matrix_object_t matrix; + bool changed = false; + for(uint8_t i=0;i US2ST(1000)) { + last_update = current_time; + last_matrix = matrix; + matrix_object_t* m = begin_write_keyboard_matrix(); + for(uint8_t i=0;irows[i] = matrix.rows[i]; + } + end_write_keyboard_matrix(); + *begin_write_serial_link_connected() = true; + end_write_serial_link_connected(); + } + + matrix_object_t* m = read_keyboard_matrix(0); + if (m) { + matrix_set_remote(m->rows, 0); + } +} + +void signal_data_written(void) { + chEvtBroadcast(&new_data_event); +} + +bool is_serial_link_connected(void) { + return serial_link_connected; +} + +host_driver_t* get_serial_link_driver(void) { + return &serial_driver; +} + +// NOTE: The driver does nothing, because the master handles everything +uint8_t keyboard_leds(void) { + return 0; +} + +void send_keyboard(report_keyboard_t *report) { + (void)report; +} + +void send_mouse(report_mouse_t *report) { + (void)report; +} + +void send_system(uint16_t data) { + (void)data; +} + +void send_consumer(uint16_t data) { + (void)data; +} + diff --git a/quantum/serial_link/system/serial_link.h b/quantum/serial_link/system/serial_link.h new file mode 100644 index 000000000..351e03877 --- /dev/null +++ b/quantum/serial_link/system/serial_link.h @@ -0,0 +1,63 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016 Fred Sundvik + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#ifndef SERIAL_LINK_H +#define SERIAL_LINK_H + +#include "host_driver.h" +#include + +void init_serial_link(void); +void init_serial_link_hal(void); +bool is_serial_link_connected(void); +bool is_serial_link_master(void); +host_driver_t* get_serial_link_driver(void); +void serial_link_update(void); + +#if defined(PROTOCOL_CHIBIOS) +#include "ch.h" + +static inline void serial_link_lock(void) { + chSysLock(); +} + +static inline void serial_link_unlock(void) { + chSysUnlock(); +} + +void signal_data_written(void); + +#else + +inline void serial_link_lock(void) { +} + +inline void serial_link_unlock(void) { +} + +void signal_data_written(void); + +#endif + +#endif diff --git a/quantum/serial_link/tests/Makefile b/quantum/serial_link/tests/Makefile new file mode 100644 index 000000000..1b072c6f1 --- /dev/null +++ b/quantum/serial_link/tests/Makefile @@ -0,0 +1,61 @@ +# The MIT License (MIT) +# +# Copyright (c) 2016 Fred Sundvik +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +CC = gcc +CFLAGS = +INCLUDES = -I. -I../../ +LDFLAGS = -L$(BUILDDIR)/cgreen/build-c/src -shared +LDLIBS = -lcgreen +UNITOBJ = $(BUILDDIR)/serialtest/unitobj +DEPDIR = $(BUILDDIR)/serialtest/unit.d +UNITTESTS = $(BUILDDIR)/serialtest/unittests +DEPFLAGS = -MT $@ -MMD -MP -MF $(DEPDIR)/$*.Td +EXT = .so +UNAME := $(shell uname) +ifneq (, $(findstring MINGW, $(UNAME))) + EXT = .dll +endif +ifneq (, $(findstring CYGWIN, $(UNAME))) + EXT = .dll +endif + +SRC = $(wildcard *.c) +TESTFILES = $(patsubst %.c, $(UNITTESTS)/%$(EXT), $(SRC)) +$(shell mkdir -p $(DEPDIR) >/dev/null) + +test: $(TESTFILES) + @$(BUILDDIR)/cgreen/build-c/tools/cgreen-runner --color $(TESTFILES) + +$(UNITTESTS)/%$(EXT): $(UNITOBJ)/%.o + @mkdir -p $(UNITTESTS) + $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) + +$(UNITOBJ)/%.o : %.c +$(UNITOBJ)/%.o: %.c $(DEPDIR)/%.d + @mkdir -p $(UNITOBJ) + $(CC) $(CFLAGS) $(DEPFLAGS) $(INCLUDES) -c $< -o $@ + @mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d + +$(DEPDIR)/%.d: ; +.PRECIOUS: $(DEPDIR)/%.d + +-include $(patsubst %,$(DEPDIR)/%.d,$(basename $(SRC))) \ No newline at end of file diff --git a/quantum/serial_link/tests/byte_stuffer_tests.c b/quantum/serial_link/tests/byte_stuffer_tests.c new file mode 100644 index 000000000..64b170e8c --- /dev/null +++ b/quantum/serial_link/tests/byte_stuffer_tests.c @@ -0,0 +1,506 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016 Fred Sundvik + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include +#include +#include "serial_link/protocol/byte_stuffer.h" +#include "serial_link/protocol/byte_stuffer.c" +#include "serial_link/protocol/frame_validator.h" +#include "serial_link/protocol/physical.h" + +static uint8_t sent_data[MAX_FRAME_SIZE*2]; +static uint16_t sent_data_size; + +Describe(ByteStuffer); +BeforeEach(ByteStuffer) { + init_byte_stuffer(); + sent_data_size = 0; +} +AfterEach(ByteStuffer) {} + +void validator_recv_frame(uint8_t link, uint8_t* data, uint16_t size) { + mock(data, size); +} + +void send_data(uint8_t link, const uint8_t* data, uint16_t size) { + memcpy(sent_data + sent_data_size, data, size); + sent_data_size += size; +} + +Ensure(ByteStuffer, receives_no_frame_for_a_single_zero_byte) { + never_expect(validator_recv_frame); + byte_stuffer_recv_byte(0, 0); +} + +Ensure(ByteStuffer, receives_no_frame_for_a_single_FF_byte) { + never_expect(validator_recv_frame); + byte_stuffer_recv_byte(0, 0xFF); +} + +Ensure(ByteStuffer, receives_no_frame_for_a_single_random_byte) { + never_expect(validator_recv_frame); + byte_stuffer_recv_byte(0, 0x4A); +} + +Ensure(ByteStuffer, receives_no_frame_for_a_zero_length_frame) { + never_expect(validator_recv_frame); + byte_stuffer_recv_byte(0, 1); + byte_stuffer_recv_byte(0, 0); +} + +Ensure(ByteStuffer, receives_single_byte_valid_frame) { + uint8_t expected[] = {0x37}; + expect(validator_recv_frame, + when(size, is_equal_to(1)), + when(data, is_equal_to_contents_of(expected, 1)) + ); + byte_stuffer_recv_byte(0, 2); + byte_stuffer_recv_byte(0, 0x37); + byte_stuffer_recv_byte(0, 0); +} + +Ensure(ByteStuffer, receives_three_bytes_valid_frame) { + uint8_t expected[] = {0x37, 0x99, 0xFF}; + expect(validator_recv_frame, + when(size, is_equal_to(3)), + when(data, is_equal_to_contents_of(expected, 3)) + ); + byte_stuffer_recv_byte(0, 4); + byte_stuffer_recv_byte(0, 0x37); + byte_stuffer_recv_byte(0, 0x99); + byte_stuffer_recv_byte(0, 0xFF); + byte_stuffer_recv_byte(0, 0); +} + +Ensure(ByteStuffer, receives_single_zero_valid_frame) { + uint8_t expected[] = {0}; + expect(validator_recv_frame, + when(size, is_equal_to(1)), + when(data, is_equal_to_contents_of(expected, 1)) + ); + byte_stuffer_recv_byte(0, 1); + byte_stuffer_recv_byte(0, 1); + byte_stuffer_recv_byte(0, 0); +} + +Ensure(ByteStuffer, receives_valid_frame_with_zeroes) { + uint8_t expected[] = {5, 0, 3, 0}; + expect(validator_recv_frame, + when(size, is_equal_to(4)), + when(data, is_equal_to_contents_of(expected, 4)) + ); + byte_stuffer_recv_byte(0, 2); + byte_stuffer_recv_byte(0, 5); + byte_stuffer_recv_byte(0, 2); + byte_stuffer_recv_byte(0, 3); + byte_stuffer_recv_byte(0, 1); + byte_stuffer_recv_byte(0, 0); +} + +Ensure(ByteStuffer, receives_two_valid_frames) { + uint8_t expected1[] = {5, 0}; + uint8_t expected2[] = {3}; + expect(validator_recv_frame, + when(size, is_equal_to(2)), + when(data, is_equal_to_contents_of(expected1, 2)) + ); + expect(validator_recv_frame, + when(size, is_equal_to(1)), + when(data, is_equal_to_contents_of(expected2, 1)) + ); + byte_stuffer_recv_byte(1, 2); + byte_stuffer_recv_byte(1, 5); + byte_stuffer_recv_byte(1, 1); + byte_stuffer_recv_byte(1, 0); + byte_stuffer_recv_byte(1, 2); + byte_stuffer_recv_byte(1, 3); + byte_stuffer_recv_byte(1, 0); +} + +Ensure(ByteStuffer, receives_valid_frame_after_unexpected_zero) { + uint8_t expected[] = {5, 7}; + expect(validator_recv_frame, + when(size, is_equal_to(2)), + when(data, is_equal_to_contents_of(expected, 2)) + ); + byte_stuffer_recv_byte(1, 3); + byte_stuffer_recv_byte(1, 1); + byte_stuffer_recv_byte(1, 0); + byte_stuffer_recv_byte(1, 3); + byte_stuffer_recv_byte(1, 5); + byte_stuffer_recv_byte(1, 7); + byte_stuffer_recv_byte(1, 0); +} + +Ensure(ByteStuffer, receives_valid_frame_after_unexpected_non_zero) { + uint8_t expected[] = {5, 7}; + expect(validator_recv_frame, + when(size, is_equal_to(2)), + when(data, is_equal_to_contents_of(expected, 2)) + ); + byte_stuffer_recv_byte(0, 2); + byte_stuffer_recv_byte(0, 9); + byte_stuffer_recv_byte(0, 4); // This should have been zero + byte_stuffer_recv_byte(0, 0); + byte_stuffer_recv_byte(0, 3); + byte_stuffer_recv_byte(0, 5); + byte_stuffer_recv_byte(0, 7); + byte_stuffer_recv_byte(0, 0); +} + +Ensure(ByteStuffer, receives_a_valid_frame_with_over254_non_zeroes_and_then_end_of_frame) { + uint8_t expected[254]; + int i; + for (i=0;i<254;i++) { + expected[i] = i + 1; + } + expect(validator_recv_frame, + when(size, is_equal_to(254)), + when(data, is_equal_to_contents_of(expected, 254)) + ); + byte_stuffer_recv_byte(0, 0xFF); + for (i=0;i<254;i++) { + byte_stuffer_recv_byte(0, i+1); + } + byte_stuffer_recv_byte(0, 0); +} + +Ensure(ByteStuffer, receives_a_valid_frame_with_over254_non_zeroes_next_byte_is_non_zero) { + uint8_t expected[255]; + int i; + for (i=0;i<254;i++) { + expected[i] = i + 1; + } + expected[254] = 7; + expect(validator_recv_frame, + when(size, is_equal_to(255)), + when(data, is_equal_to_contents_of(expected, 255)) + ); + byte_stuffer_recv_byte(0, 0xFF); + for (i=0;i<254;i++) { + byte_stuffer_recv_byte(0, i+1); + } + byte_stuffer_recv_byte(0, 2); + byte_stuffer_recv_byte(0, 7); + byte_stuffer_recv_byte(0, 0); +} + +Ensure(ByteStuffer, receives_a_valid_frame_with_over254_non_zeroes_next_byte_is_zero) { + uint8_t expected[255]; + int i; + for (i=0;i<254;i++) { + expected[i] = i + 1; + } + expected[254] = 0; + expect(validator_recv_frame, + when(size, is_equal_to(255)), + when(data, is_equal_to_contents_of(expected, 255)) + ); + byte_stuffer_recv_byte(0, 0xFF); + for (i=0;i<254;i++) { + byte_stuffer_recv_byte(0, i+1); + } + byte_stuffer_recv_byte(0, 1); + byte_stuffer_recv_byte(0, 1); + byte_stuffer_recv_byte(0, 0); +} + +Ensure(ByteStuffer, receives_two_long_frames_and_some_more) { + uint8_t expected[515]; + int i; + int j; + for (j=0;j<2;j++) { + for (i=0;i<254;i++) { + expected[i+254*j] = i + 1; + } + } + for (i=0;i<7;i++) { + expected[254*2+i] = i + 1; + } + expect(validator_recv_frame, + when(size, is_equal_to(515)), + when(data, is_equal_to_contents_of(expected, 510)) + ); + byte_stuffer_recv_byte(0, 0xFF); + for (i=0;i<254;i++) { + byte_stuffer_recv_byte(0, i+1); + } + byte_stuffer_recv_byte(0, 0xFF); + for (i=0;i<254;i++) { + byte_stuffer_recv_byte(0, i+1); + } + byte_stuffer_recv_byte(0, 8); + byte_stuffer_recv_byte(0, 1); + byte_stuffer_recv_byte(0, 2); + byte_stuffer_recv_byte(0, 3); + byte_stuffer_recv_byte(0, 4); + byte_stuffer_recv_byte(0, 5); + byte_stuffer_recv_byte(0, 6); + byte_stuffer_recv_byte(0, 7); + byte_stuffer_recv_byte(0, 0); +} + +Ensure(ByteStuffer, receives_an_all_zeros_frame_that_is_maximum_size) { + uint8_t expected[MAX_FRAME_SIZE] = {}; + expect(validator_recv_frame, + when(size, is_equal_to(MAX_FRAME_SIZE)), + when(data, is_equal_to_contents_of(expected, MAX_FRAME_SIZE)) + ); + int i; + byte_stuffer_recv_byte(0, 1); + for(i=0;i +#include +#include "serial_link/protocol/byte_stuffer.c" +#include "serial_link/protocol/frame_validator.c" +#include "serial_link/protocol/frame_router.c" +#include "serial_link/protocol/transport.h" + +static uint8_t received_data[256]; +static uint16_t received_data_size; + +typedef struct { + uint8_t sent_data[256]; + uint16_t sent_data_size; +} receive_buffer_t; + +typedef struct { + receive_buffer_t send_buffers[2]; +} router_buffer_t; + +router_buffer_t router_buffers[8]; + +router_buffer_t* current_router_buffer; + + +Describe(FrameRouter); +BeforeEach(FrameRouter) { + init_byte_stuffer(); + memset(router_buffers, 0, sizeof(router_buffers)); + current_router_buffer = 0; +} +AfterEach(FrameRouter) {} + +typedef struct { + uint32_t data; + uint8_t extra[16]; +} frame_buffer_t; + + +void send_data(uint8_t link, const uint8_t* data, uint16_t size) { + receive_buffer_t* buffer = ¤t_router_buffer->send_buffers[link]; + memcpy(buffer->sent_data + buffer->sent_data_size, data, size); + buffer->sent_data_size += size; +} + +static void receive_data(uint8_t link, uint8_t* data, uint16_t size) { + int i; + for(i=0;i to) { + receive_data(DOWN_LINK, + router_buffers[from].send_buffers[UP_LINK].sent_data, + router_buffers[from].send_buffers[UP_LINK].sent_data_size); + } + else if(to > from) { + receive_data(UP_LINK, + router_buffers[from].send_buffers[DOWN_LINK].sent_data, + router_buffers[from].send_buffers[DOWN_LINK].sent_data_size); + } +} + +void transport_recv_frame(uint8_t from, uint8_t* data, uint16_t size) { + mock(from, data, size); +} + + +Ensure(FrameRouter, master_broadcast_is_received_by_everyone) { + frame_buffer_t data; + data.data = 0xAB7055BB; + activate_router(0); + router_send_frame(0xFF, (uint8_t*)&data, 4); + assert_that(router_buffers[0].send_buffers[DOWN_LINK].sent_data_size, is_greater_than(0)); + assert_that(router_buffers[0].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); + + expect(transport_recv_frame, + when(from, is_equal_to(0)), + when(size, is_equal_to(4)), + when(data, is_equal_to_contents_of(&data.data, 4)) + ); + simulate_transport(0, 1); + assert_that(router_buffers[1].send_buffers[DOWN_LINK].sent_data_size, is_greater_than(0)); + assert_that(router_buffers[1].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); + + expect(transport_recv_frame, + when(from, is_equal_to(0)), + when(size, is_equal_to(4)), + when(data, is_equal_to_contents_of(&data.data, 4)) + ); + simulate_transport(1, 2); + assert_that(router_buffers[2].send_buffers[DOWN_LINK].sent_data_size, is_greater_than(0)); + assert_that(router_buffers[2].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); +} + +Ensure(FrameRouter, master_send_is_received_by_targets) { + frame_buffer_t data; + data.data = 0xAB7055BB; + activate_router(0); + router_send_frame((1 << 1) | (1 << 2), (uint8_t*)&data, 4); + assert_that(router_buffers[0].send_buffers[DOWN_LINK].sent_data_size, is_greater_than(0)); + assert_that(router_buffers[0].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); + + simulate_transport(0, 1); + assert_that(router_buffers[1].send_buffers[DOWN_LINK].sent_data_size, is_greater_than(0)); + assert_that(router_buffers[1].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); + + expect(transport_recv_frame, + when(from, is_equal_to(0)), + when(size, is_equal_to(4)), + when(data, is_equal_to_contents_of(&data.data, 4)) + ); + simulate_transport(1, 2); + assert_that(router_buffers[2].send_buffers[DOWN_LINK].sent_data_size, is_greater_than(0)); + assert_that(router_buffers[2].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); + + expect(transport_recv_frame, + when(from, is_equal_to(0)), + when(size, is_equal_to(4)), + when(data, is_equal_to_contents_of(&data.data, 4)) + ); + simulate_transport(2, 3); + assert_that(router_buffers[3].send_buffers[DOWN_LINK].sent_data_size, is_greater_than(0)); + assert_that(router_buffers[3].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); +} + +Ensure(FrameRouter, first_link_sends_to_master) { + frame_buffer_t data; + data.data = 0xAB7055BB; + activate_router(1); + router_send_frame(0, (uint8_t*)&data, 4); + assert_that(router_buffers[1].send_buffers[UP_LINK].sent_data_size, is_greater_than(0)); + assert_that(router_buffers[1].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0)); + + expect(transport_recv_frame, + when(from, is_equal_to(1)), + when(size, is_equal_to(4)), + when(data, is_equal_to_contents_of(&data.data, 4)) + ); + simulate_transport(1, 0); + assert_that(router_buffers[0].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0)); + assert_that(router_buffers[0].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); +} + +Ensure(FrameRouter, second_link_sends_to_master) { + frame_buffer_t data; + data.data = 0xAB7055BB; + activate_router(2); + router_send_frame(0, (uint8_t*)&data, 4); + assert_that(router_buffers[2].send_buffers[UP_LINK].sent_data_size, is_greater_than(0)); + assert_that(router_buffers[2].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0)); + + simulate_transport(2, 1); + assert_that(router_buffers[1].send_buffers[UP_LINK].sent_data_size, is_greater_than(0)); + assert_that(router_buffers[1].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0)); + + expect(transport_recv_frame, + when(from, is_equal_to(2)), + when(size, is_equal_to(4)), + when(data, is_equal_to_contents_of(&data.data, 4)) + ); + simulate_transport(1, 0); + assert_that(router_buffers[0].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0)); + assert_that(router_buffers[0].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); +} + +Ensure(FrameRouter, master_sends_to_master_does_nothing) { + frame_buffer_t data; + data.data = 0xAB7055BB; + activate_router(0); + router_send_frame(0, (uint8_t*)&data, 4); + assert_that(router_buffers[0].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); + assert_that(router_buffers[0].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0)); +} + +Ensure(FrameRouter, link_sends_to_other_link_does_nothing) { + frame_buffer_t data; + data.data = 0xAB7055BB; + activate_router(1); + router_send_frame(2, (uint8_t*)&data, 4); + assert_that(router_buffers[1].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); + assert_that(router_buffers[1].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0)); +} + +Ensure(FrameRouter, master_receives_on_uplink_does_nothing) { + frame_buffer_t data; + data.data = 0xAB7055BB; + activate_router(1); + router_send_frame(0, (uint8_t*)&data, 4); + assert_that(router_buffers[1].send_buffers[UP_LINK].sent_data_size, is_greater_than(0)); + assert_that(router_buffers[1].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0)); + + never_expect(transport_recv_frame); + activate_router(0); + receive_data(UP_LINK, + router_buffers[1].send_buffers[UP_LINK].sent_data, + router_buffers[1].send_buffers[UP_LINK].sent_data_size); + assert_that(router_buffers[0].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); + assert_that(router_buffers[0].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0)); +} diff --git a/quantum/serial_link/tests/frame_validator_tests.c b/quantum/serial_link/tests/frame_validator_tests.c new file mode 100644 index 000000000..d20947e2c --- /dev/null +++ b/quantum/serial_link/tests/frame_validator_tests.c @@ -0,0 +1,101 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016 Fred Sundvik + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include +#include +#include "serial_link/protocol/frame_validator.c" + +void route_incoming_frame(uint8_t link, uint8_t* data, uint16_t size) { + mock(data, size); +} + +void byte_stuffer_send_frame(uint8_t link, uint8_t* data, uint16_t size) { + mock(data, size); +} + +Describe(FrameValidator); +BeforeEach(FrameValidator) {} +AfterEach(FrameValidator) {} + +Ensure(FrameValidator, doesnt_validate_frames_under_5_bytes) { + never_expect(route_incoming_frame); + uint8_t data[] = {1, 2}; + validator_recv_frame(0, 0, 1); + validator_recv_frame(0, data, 2); + validator_recv_frame(0, data, 3); + validator_recv_frame(0, data, 4); +} + +Ensure(FrameValidator, validates_one_byte_frame_with_correct_crc) { + uint8_t data[] = {0x44, 0x04, 0x6A, 0xB3, 0xA3}; + expect(route_incoming_frame, + when(size, is_equal_to(1)), + when(data, is_equal_to_contents_of(data, 1)) + ); + validator_recv_frame(0, data, 5); +} + +Ensure(FrameValidator, does_not_validate_one_byte_frame_with_incorrect_crc) { + uint8_t data[] = {0x44, 0, 0, 0, 0}; + never_expect(route_incoming_frame); + validator_recv_frame(1, data, 5); +} + +Ensure(FrameValidator, validates_four_byte_frame_with_correct_crc) { + uint8_t data[] = {0x44, 0x10, 0xFF, 0x00, 0x74, 0x4E, 0x30, 0xBA}; + expect(route_incoming_frame, + when(size, is_equal_to(4)), + when(data, is_equal_to_contents_of(data, 4)) + ); + validator_recv_frame(1, data, 8); +} + +Ensure(FrameValidator, validates_five_byte_frame_with_correct_crc) { + uint8_t data[] = {1, 2, 3, 4, 5, 0xF4, 0x99, 0x0B, 0x47}; + expect(route_incoming_frame, + when(size, is_equal_to(5)), + when(data, is_equal_to_contents_of(data, 5)) + ); + validator_recv_frame(0, data, 9); +} + +Ensure(FrameValidator, sends_one_byte_with_correct_crc) { + uint8_t original[] = {0x44, 0, 0, 0, 0}; + uint8_t expected[] = {0x44, 0x04, 0x6A, 0xB3, 0xA3}; + expect(byte_stuffer_send_frame, + when(size, is_equal_to(sizeof(expected))), + when(data, is_equal_to_contents_of(expected, sizeof(expected))) + ); + validator_send_frame(0, original, 1); +} + +Ensure(FrameValidator, sends_five_bytes_with_correct_crc) { + uint8_t original[] = {1, 2, 3, 4, 5, 0, 0, 0, 0}; + uint8_t expected[] = {1, 2, 3, 4, 5, 0xF4, 0x99, 0x0B, 0x47}; + expect(byte_stuffer_send_frame, + when(size, is_equal_to(sizeof(expected))), + when(data, is_equal_to_contents_of(expected, sizeof(expected))) + ); + validator_send_frame(0, original, 5); +} diff --git a/quantum/serial_link/tests/transport_tests.c b/quantum/serial_link/tests/transport_tests.c new file mode 100644 index 000000000..358e1b9fd --- /dev/null +++ b/quantum/serial_link/tests/transport_tests.c @@ -0,0 +1,168 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016 Fred Sundvik + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include +#include +#include "serial_link/protocol/transport.c" +#include "serial_link/protocol/triple_buffered_object.c" + +void signal_data_written(void) { + mock(); +} + +static uint8_t sent_data[2048]; +static uint16_t sent_data_size; + +void router_send_frame(uint8_t destination, uint8_t* data, uint16_t size) { + mock(destination); + memcpy(sent_data + sent_data_size, data, size); + sent_data_size += size; +} + +typedef struct { + uint32_t test; +} test_object1_t; + +typedef struct { + uint32_t test1; + uint32_t test2; +} test_object2_t; + +MASTER_TO_ALL_SLAVES_OBJECT(master_to_slave, test_object1_t); +MASTER_TO_SINGLE_SLAVE_OBJECT(master_to_single_slave, test_object1_t); +SLAVE_TO_MASTER_OBJECT(slave_to_master, test_object1_t); + +static remote_object_t* test_remote_objects[] = { + REMOTE_OBJECT(master_to_slave), + REMOTE_OBJECT(master_to_single_slave), + REMOTE_OBJECT(slave_to_master), +}; + +Describe(Transport); +BeforeEach(Transport) { + add_remote_objects(test_remote_objects, sizeof(test_remote_objects) / sizeof(remote_object_t*)); + sent_data_size = 0; +} +AfterEach(Transport) {} + +Ensure(Transport, write_to_local_signals_an_event) { + begin_write_master_to_slave(); + expect(signal_data_written); + end_write_master_to_slave(); + begin_write_slave_to_master(); + expect(signal_data_written); + end_write_slave_to_master(); + begin_write_master_to_single_slave(1); + expect(signal_data_written); + end_write_master_to_single_slave(1); +} + +Ensure(Transport, writes_from_master_to_all_slaves) { + update_transport(); + test_object1_t* obj = begin_write_master_to_slave(); + obj->test = 5; + expect(signal_data_written); + end_write_master_to_slave(); + expect(router_send_frame, + when(destination, is_equal_to(0xFF))); + update_transport(); + transport_recv_frame(0, sent_data, sent_data_size); + test_object1_t* obj2 = read_master_to_slave(); + assert_that(obj2, is_not_equal_to(NULL)); + assert_that(obj2->test, is_equal_to(5)); +} + +Ensure(Transport, writes_from_slave_to_master) { + update_transport(); + test_object1_t* obj = begin_write_slave_to_master(); + obj->test = 7; + expect(signal_data_written); + end_write_slave_to_master(); + expect(router_send_frame, + when(destination, is_equal_to(0))); + update_transport(); + transport_recv_frame(3, sent_data, sent_data_size); + test_object1_t* obj2 = read_slave_to_master(2); + assert_that(read_slave_to_master(0), is_equal_to(NULL)); + assert_that(obj2, is_not_equal_to(NULL)); + assert_that(obj2->test, is_equal_to(7)); +} + +Ensure(Transport, writes_from_master_to_single_slave) { + update_transport(); + test_object1_t* obj = begin_write_master_to_single_slave(3); + obj->test = 7; + expect(signal_data_written); + end_write_master_to_single_slave(3); + expect(router_send_frame, + when(destination, is_equal_to(4))); + update_transport(); + transport_recv_frame(0, sent_data, sent_data_size); + test_object1_t* obj2 = read_master_to_single_slave(); + assert_that(obj2, is_not_equal_to(NULL)); + assert_that(obj2->test, is_equal_to(7)); +} + +Ensure(Transport, ignores_object_with_invalid_id) { + update_transport(); + test_object1_t* obj = begin_write_master_to_single_slave(3); + obj->test = 7; + expect(signal_data_written); + end_write_master_to_single_slave(3); + expect(router_send_frame, + when(destination, is_equal_to(4))); + update_transport(); + sent_data[sent_data_size - 1] = 44; + transport_recv_frame(0, sent_data, sent_data_size); + test_object1_t* obj2 = read_master_to_single_slave(); + assert_that(obj2, is_equal_to(NULL)); +} + +Ensure(Transport, ignores_object_with_size_too_small) { + update_transport(); + test_object1_t* obj = begin_write_master_to_slave(); + obj->test = 7; + expect(signal_data_written); + end_write_master_to_slave(); + expect(router_send_frame); + update_transport(); + sent_data[sent_data_size - 2] = 0; + transport_recv_frame(0, sent_data, sent_data_size - 1); + test_object1_t* obj2 = read_master_to_slave(); + assert_that(obj2, is_equal_to(NULL)); +} + +Ensure(Transport, ignores_object_with_size_too_big) { + update_transport(); + test_object1_t* obj = begin_write_master_to_slave(); + obj->test = 7; + expect(signal_data_written); + end_write_master_to_slave(); + expect(router_send_frame); + update_transport(); + sent_data[sent_data_size + 21] = 0; + transport_recv_frame(0, sent_data, sent_data_size + 22); + test_object1_t* obj2 = read_master_to_slave(); + assert_that(obj2, is_equal_to(NULL)); +} diff --git a/quantum/serial_link/tests/triple_buffered_object_tests.c b/quantum/serial_link/tests/triple_buffered_object_tests.c new file mode 100644 index 000000000..6f7c82b46 --- /dev/null +++ b/quantum/serial_link/tests/triple_buffered_object_tests.c @@ -0,0 +1,82 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016 Fred Sundvik + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include +#include "serial_link/protocol/triple_buffered_object.c" + +typedef struct { + uint8_t state; + uint32_t buffer[3]; +}test_object_t; + +test_object_t test_object; + +Describe(TripleBufferedObject); +BeforeEach(TripleBufferedObject) { + triple_buffer_init((triple_buffer_object_t*)&test_object); +} +AfterEach(TripleBufferedObject) {} + + +Ensure(TripleBufferedObject, writes_and_reads_object) { + *triple_buffer_begin_write(&test_object) = 0x3456ABCC; + triple_buffer_end_write(&test_object); + assert_that(*triple_buffer_read(&test_object), is_equal_to(0x3456ABCC)); +} + +Ensure(TripleBufferedObject, does_not_read_empty) { + assert_that(triple_buffer_read(&test_object), is_equal_to(NULL)); +} + +Ensure(TripleBufferedObject, writes_twice_and_reads_object) { + *triple_buffer_begin_write(&test_object) = 0x3456ABCC; + triple_buffer_end_write(&test_object); + *triple_buffer_begin_write(&test_object) = 0x44778899; + triple_buffer_end_write(&test_object); + assert_that(*triple_buffer_read(&test_object), is_equal_to(0x44778899)); +} + +Ensure(TripleBufferedObject, performs_another_write_in_the_middle_of_read) { + *triple_buffer_begin_write(&test_object) = 1; + triple_buffer_end_write(&test_object); + uint32_t* read = triple_buffer_read(&test_object); + *triple_buffer_begin_write(&test_object) = 2; + triple_buffer_end_write(&test_object); + assert_that(*read, is_equal_to(1)); + assert_that(*triple_buffer_read(&test_object), is_equal_to(2)); + assert_that(triple_buffer_read(&test_object), is_equal_to(NULL)); +} + +Ensure(TripleBufferedObject, performs_two_writes_in_the_middle_of_read) { + *triple_buffer_begin_write(&test_object) = 1; + triple_buffer_end_write(&test_object); + uint32_t* read = triple_buffer_read(&test_object); + *triple_buffer_begin_write(&test_object) = 2; + triple_buffer_end_write(&test_object); + *triple_buffer_begin_write(&test_object) = 3; + triple_buffer_end_write(&test_object); + assert_that(*read, is_equal_to(1)); + assert_that(*triple_buffer_read(&test_object), is_equal_to(3)); + assert_that(triple_buffer_read(&test_object), is_equal_to(NULL)); +} -- cgit v1.2.3-24-g4f1b From f727801bc69b3db28f84b7b8986756193bbfd21e Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Wed, 6 Jul 2016 20:17:16 +0300 Subject: Delete .gitmodules from visualizer --- quantum/visualizer/.gitmodules | 3 --- quantum/visualizer/ugfx | 1 - 2 files changed, 4 deletions(-) delete mode 100644 quantum/visualizer/.gitmodules delete mode 160000 quantum/visualizer/ugfx (limited to 'quantum') diff --git a/quantum/visualizer/.gitmodules b/quantum/visualizer/.gitmodules deleted file mode 100644 index b320458c0..000000000 --- a/quantum/visualizer/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "ugfx"] - path = ugfx - url = https://bitbucket.org/fredizzimo/ugfx.git diff --git a/quantum/visualizer/ugfx b/quantum/visualizer/ugfx deleted file mode 160000 index e221a6906..000000000 --- a/quantum/visualizer/ugfx +++ /dev/null @@ -1 +0,0 @@ -Subproject commit e221a690616e20f87e0b0088baffdbd5427be862 -- cgit v1.2.3-24-g4f1b From 70797bb8f21c72cba15b314b2d0a6684bfedc369 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Thu, 7 Jul 2016 00:20:20 +0300 Subject: Makefile changes and files to compile Visualizer --- quantum/visualizer/visualizer.c | 2 -- quantum/visualizer/visualizer.h | 2 -- quantum/visualizer/visualizer.mk | 22 +++++++++++----------- 3 files changed, 11 insertions(+), 15 deletions(-) (limited to 'quantum') diff --git a/quantum/visualizer/visualizer.c b/quantum/visualizer/visualizer.c index c24073405..abca22d85 100644 --- a/quantum/visualizer/visualizer.c +++ b/quantum/visualizer/visualizer.c @@ -29,9 +29,7 @@ SOFTWARE. #include "ch.h" #endif -#ifdef LCD_ENABLE #include "gfx.h" -#endif #ifdef LCD_BACKLIGHT_ENABLE #include "lcd_backlight.h" diff --git a/quantum/visualizer/visualizer.h b/quantum/visualizer/visualizer.h index 45cfa9aa9..53e250725 100644 --- a/quantum/visualizer/visualizer.h +++ b/quantum/visualizer/visualizer.h @@ -28,9 +28,7 @@ SOFTWARE. #include #include -#ifdef LCD_ENABLE #include "gfx.h" -#endif #ifdef LCD_BACKLIGHT_ENABLE #include "lcd_backlight.h" diff --git a/quantum/visualizer/visualizer.mk b/quantum/visualizer/visualizer.mk index 56525ffd9..b5dfad8e1 100644 --- a/quantum/visualizer/visualizer.mk +++ b/quantum/visualizer/visualizer.mk @@ -20,14 +20,14 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -GFXLIB = $(VISUALIZER_DIR)/ugfx SRC += $(VISUALIZER_DIR)/visualizer.c -UINCDIR += $(GFXINC) $(VISUALIZER_DIR) +EXTRAINCDIRS += $(GFXINC) $(VISUALIZER_DIR) +GFXLIB = $(LIB_PATH)/ugfx +VPATH += $(VISUALIZER_PATH) ifdef LCD_ENABLE -UDEFS += -DLCD_ENABLE +OPT_DEFS += -DLCD_ENABLE ULIBS += -lm -USE_UGFX = yes endif ifdef LCD_BACKLIGHT_ENABLE @@ -35,21 +35,21 @@ SRC += $(VISUALIZER_DIR)/lcd_backlight.c ifndef EMULATOR SRC += lcd_backlight_hal.c endif -UDEFS += -DLCD_BACKLIGHT_ENABLE +OPT_DEFS += -DLCD_BACKLIGHT_ENABLE endif ifdef LED_ENABLE SRC += $(VISUALIZER_DIR)/led_test.c UDEFS += -DLED_ENABLE -USE_UGFX = yes endif -ifdef USE_UGFX include $(GFXLIB)/gfx.mk -SRC += $(GFXSRC) -UDEFS += $(patsubst %,-D%,$(patsubst -D%,%,$(GFXDEFS))) -ULIBS += $(patsubst %,-l%,$(patsubst -l%,%,$(GFXLIBS))) -endif +#SERIAL_SRC = $(wildcard $(SERIAL_PATH)/protocol/*.c) +#SERIAL_SRC += $(wildcard $(SERIAL_PATH)/system/*.c) +#SRC += $(patsubst $(QUANTUM_PATH)/%,%,$(SERIAL_SRC)) +#SRC += $(GFXSRC) +OPT_DEFS += $(patsubst %,-D%,$(patsubst -D%,%,$(GFXDEFS))) +#ULIBS += $(patsubst %,-l%,$(patsubst -l%,%,$(GFXLIBS))) ifndef VISUALIZER_USER VISUALIZER_USER = visualizer_user.c -- cgit v1.2.3-24-g4f1b From a4bf46f9b1d0a0be0cecb2cd0f0d941aa7c71bd3 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Wed, 6 Jul 2016 22:48:19 -0400 Subject: default keymap, reset sorted out for now, added serial to makefile --- quantum/quantum.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'quantum') diff --git a/quantum/quantum.c b/quantum/quantum.c index d59bd5a3f..d8e43a465 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -89,7 +89,7 @@ bool process_record_quantum(keyrecord_t *record) { shutdown_user(); #endif wait_ms(250); - #ifdef ATREUS_ASTAR + #ifdef CATERINA_BOOTLOADER *(uint16_t *)0x0800 = 0x7777; // these two are a-star-specific #endif bootloader_jump(); -- cgit v1.2.3-24-g4f1b From 07d0d5cbe48d7afaf0bc8c9916d40179ec51cb42 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Thu, 7 Jul 2016 12:46:10 +0300 Subject: Makefile fixes and update of Visualizer --- quantum/visualizer/led_test.c | 4 ++-- quantum/visualizer/visualizer.mk | 8 +++----- 2 files changed, 5 insertions(+), 7 deletions(-) (limited to 'quantum') diff --git a/quantum/visualizer/led_test.c b/quantum/visualizer/led_test.c index c2ea30b55..a9abace8d 100644 --- a/quantum/visualizer/led_test.c +++ b/quantum/visualizer/led_test.c @@ -89,8 +89,8 @@ static uint8_t crossfade_start_frame[NUM_ROWS][NUM_COLS]; static uint8_t crossfade_end_frame[NUM_ROWS][NUM_COLS]; static uint8_t compute_gradient_color(float t, float index, float num) { - const float two_pi = 2.0f * PI; - float normalized_index = (1.0f - index / (num - 1)) * two_pi; + const float two_pi = M_2_PI; + float normalized_index = (1.0f - index / (num - 1.0f)) * two_pi; float x = t * two_pi + normalized_index; float v = 0.5 * (cosf(x) + 1.0f); return (uint8_t)(255.0f * v); diff --git a/quantum/visualizer/visualizer.mk b/quantum/visualizer/visualizer.mk index b5dfad8e1..149968de7 100644 --- a/quantum/visualizer/visualizer.mk +++ b/quantum/visualizer/visualizer.mk @@ -25,6 +25,8 @@ EXTRAINCDIRS += $(GFXINC) $(VISUALIZER_DIR) GFXLIB = $(LIB_PATH)/ugfx VPATH += $(VISUALIZER_PATH) +OPT_DEFS += -DVISUALIZER_ENABLE + ifdef LCD_ENABLE OPT_DEFS += -DLCD_ENABLE ULIBS += -lm @@ -44,12 +46,8 @@ UDEFS += -DLED_ENABLE endif include $(GFXLIB)/gfx.mk -#SERIAL_SRC = $(wildcard $(SERIAL_PATH)/protocol/*.c) -#SERIAL_SRC += $(wildcard $(SERIAL_PATH)/system/*.c) -#SRC += $(patsubst $(QUANTUM_PATH)/%,%,$(SERIAL_SRC)) -#SRC += $(GFXSRC) +SRC += $(patsubst $(TOP_DIR)/%,%,$(GFXSRC)) OPT_DEFS += $(patsubst %,-D%,$(patsubst -D%,%,$(GFXDEFS))) -#ULIBS += $(patsubst %,-l%,$(patsubst -l%,%,$(GFXLIBS))) ifndef VISUALIZER_USER VISUALIZER_USER = visualizer_user.c -- cgit v1.2.3-24-g4f1b From 7229751ba9d402b2a6c9dc1b7b29385b5162fe41 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Thu, 7 Jul 2016 14:01:20 +0300 Subject: Fix visualizer crash at startup Visualizer and serial link initialized in the wrong order. The LED_ENABLED define wasn't set properly uGfx is always initialized --- quantum/visualizer/visualizer.c | 2 -- quantum/visualizer/visualizer.mk | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'quantum') diff --git a/quantum/visualizer/visualizer.c b/quantum/visualizer/visualizer.c index abca22d85..dfa2ff4ee 100644 --- a/quantum/visualizer/visualizer.c +++ b/quantum/visualizer/visualizer.c @@ -456,9 +456,7 @@ static DECLARE_THREAD_FUNCTION(visualizerThread, arg) { } void visualizer_init(void) { -#ifdef LCD_ENABLE gfxInit(); -#endif #ifdef LCD_BACKLIGHT_ENABLE lcd_backlight_init(); diff --git a/quantum/visualizer/visualizer.mk b/quantum/visualizer/visualizer.mk index 149968de7..379496fb6 100644 --- a/quantum/visualizer/visualizer.mk +++ b/quantum/visualizer/visualizer.mk @@ -42,7 +42,7 @@ endif ifdef LED_ENABLE SRC += $(VISUALIZER_DIR)/led_test.c -UDEFS += -DLED_ENABLE +OPT_DEFS += -DLED_ENABLE endif include $(GFXLIB)/gfx.mk -- cgit v1.2.3-24-g4f1b From dae7c9bfb3325412c542fbbe4342c9c8e0fc1904 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Thu, 7 Jul 2016 14:12:56 +0300 Subject: Fix the SERIAL_LINK_ENABLE macro in Visualizer Rename from USE_SERIAL_LINK -> SERIAL_LINK_ENABLE --- quantum/visualizer/visualizer.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'quantum') diff --git a/quantum/visualizer/visualizer.c b/quantum/visualizer/visualizer.c index dfa2ff4ee..54f6faaa4 100644 --- a/quantum/visualizer/visualizer.c +++ b/quantum/visualizer/visualizer.c @@ -43,7 +43,7 @@ SOFTWARE. #include "nodebug.h" #endif -#ifdef USE_SERIAL_LINK +#ifdef SERIAL_LINK_ENABLE #include "serial_link/protocol/transport.h" #include "serial_link/system/serial_link.h" #endif @@ -73,7 +73,7 @@ static bool visualizer_enabled = false; #define MAX_SIMULTANEOUS_ANIMATIONS 4 static keyframe_animation_t* animations[MAX_SIMULTANEOUS_ANIMATIONS] = {}; -#ifdef USE_SERIAL_LINK +#ifdef SERIAL_LINK_ENABLE MASTER_TO_ALL_SLAVES_OBJECT(current_status, visualizer_keyboard_status_t); static remote_object_t* remote_objects[] = { @@ -462,7 +462,7 @@ void visualizer_init(void) { lcd_backlight_init(); #endif -#ifdef USE_SERIAL_LINK +#ifdef SERIAL_LINK_ENABLE add_remote_objects(remote_objects, sizeof(remote_objects) / sizeof(remote_object_t*) ); #endif @@ -486,7 +486,7 @@ void update_status(bool changed) { geventSendEvent(listener); } } -#ifdef USE_SERIAL_LINK +#ifdef SERIAL_LINK_ENABLE static systime_t last_update = 0; systime_t current_update = chVTGetSystemTimeX(); systime_t delta = current_update - last_update; @@ -506,7 +506,7 @@ void visualizer_update(uint32_t default_state, uint32_t state, uint32_t leds) { // Alternatively a mutex could be used instead of the volatile variables bool changed = false; -#ifdef USE_SERIAL_LINK +#ifdef SERIAL_LINK_ENABLE if (is_serial_link_connected ()) { visualizer_keyboard_status_t* new_status = read_current_status(); if (new_status) { -- cgit v1.2.3-24-g4f1b From aaac254ebce2005272e7385488b5690bbbe6d7c8 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Thu, 7 Jul 2016 14:29:53 +0300 Subject: Delete lcd_backlight_hal.c The functionality can now be found in the infinity_erogodox.c file instead. --- quantum/visualizer/visualizer.mk | 3 --- 1 file changed, 3 deletions(-) (limited to 'quantum') diff --git a/quantum/visualizer/visualizer.mk b/quantum/visualizer/visualizer.mk index 379496fb6..449957d63 100644 --- a/quantum/visualizer/visualizer.mk +++ b/quantum/visualizer/visualizer.mk @@ -34,9 +34,6 @@ endif ifdef LCD_BACKLIGHT_ENABLE SRC += $(VISUALIZER_DIR)/lcd_backlight.c -ifndef EMULATOR -SRC += lcd_backlight_hal.c -endif OPT_DEFS += -DLCD_BACKLIGHT_ENABLE endif -- cgit v1.2.3-24-g4f1b From caedec92d2c22480313c43a364408fb920c55364 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Thu, 7 Jul 2016 14:42:16 +0300 Subject: Move the visualizer_user file to keymap folder Also rename it to visualizer.c --- quantum/visualizer/visualizer.mk | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'quantum') diff --git a/quantum/visualizer/visualizer.mk b/quantum/visualizer/visualizer.mk index 449957d63..2f4a41d66 100644 --- a/quantum/visualizer/visualizer.mk +++ b/quantum/visualizer/visualizer.mk @@ -46,10 +46,15 @@ include $(GFXLIB)/gfx.mk SRC += $(patsubst $(TOP_DIR)/%,%,$(GFXSRC)) OPT_DEFS += $(patsubst %,-D%,$(patsubst -D%,%,$(GFXDEFS))) -ifndef VISUALIZER_USER -VISUALIZER_USER = visualizer_user.c +ifneq ("$(wildcard $(KEYMAP_PATH)/visualizer.c)","") + SRC += keyboards/$(KEYBOARD)/keymaps/$(KEYMAP)/visualizer.c +else + ifeq ("$(wildcard $(SUBPROJECT_PATH)/keymaps/$(KEYMAP)/visualizer.c)","") +$(error "$(KEYMAP_PATH)/visualizer.c" does not exist) + else + SRC += keyboards/$(KEYBOARD)/$(SUBPROJECT)/keymaps/$(KEYMAP)/visualizer.c + endif endif -SRC += $(VISUALIZER_USER) ifdef EMULATOR UINCDIR += $(TMK_DIR)/common -- cgit v1.2.3-24-g4f1b From 589df84d6cd19ad7d776cc19bcddade1cd178ddc Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Thu, 7 Jul 2016 09:58:44 -0400 Subject: corrects quantum template --- quantum/template/template.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'quantum') diff --git a/quantum/template/template.c b/quantum/template/template.c index dcc4b0a22..3057557ea 100644 --- a/quantum/template/template.c +++ b/quantum/template/template.c @@ -18,7 +18,7 @@ bool process_record_kb(uint16_t keycode, keyrecord_t *record) { // put your per-action keyboard code here // runs for every action, just before processing by the firmware - return process_action_user(record); + return process_record_user(record); } void led_set_kb(uint8_t usb_led) { -- cgit v1.2.3-24-g4f1b From 57e08eb8badc5db2fb44d2df684f32ea48cce411 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Thu, 7 Jul 2016 11:33:32 -0400 Subject: updates rgblight implementation, makes non-timer stuff compatible with audio --- quantum/light_ws2812.c | 25 +++++++++++++++++-------- quantum/rgblight.c | 23 +++++++++++++++++++---- quantum/rgblight.h | 7 +++++-- 3 files changed, 41 insertions(+), 14 deletions(-) (limited to 'quantum') diff --git a/quantum/light_ws2812.c b/quantum/light_ws2812.c index f20043067..401845e85 100755 --- a/quantum/light_ws2812.c +++ b/quantum/light_ws2812.c @@ -19,12 +19,16 @@ // Setleds for standard RGB void inline ws2812_setleds(struct cRGB *ledarray, uint16_t leds) { - ws2812_setleds_pin(ledarray,leds, _BV(ws2812_pin)); + // ws2812_setleds_pin(ledarray,leds, _BV(ws2812_pin)); + ws2812_setleds_pin(ledarray,leds, _BV(RGB_DI_PIN & 0xF)); } void inline ws2812_setleds_pin(struct cRGB *ledarray, uint16_t leds, uint8_t pinmask) { - ws2812_DDRREG |= pinmask; // Enable DDR + // ws2812_DDRREG |= pinmask; // Enable DDR + // new universal format (DDR) + _SFR_IO8((RGB_DI_PIN >> 4) + 1) |= pinmask; + ws2812_sendarray_mask((uint8_t*)ledarray,leds+leds+leds,pinmask); _delay_us(50); } @@ -32,14 +36,17 @@ void inline ws2812_setleds_pin(struct cRGB *ledarray, uint16_t leds, uint8_t pin // Setleds for SK6812RGBW void inline ws2812_setleds_rgbw(struct cRGBW *ledarray, uint16_t leds) { - ws2812_DDRREG |= _BV(ws2812_pin); // Enable DDR - ws2812_sendarray_mask((uint8_t*)ledarray,leds<<2,_BV(ws2812_pin)); + // ws2812_DDRREG |= _BV(ws2812_pin); // Enable DDR + // new universal format (DDR) + _SFR_IO8((RGB_DI_PIN >> 4) + 1) |= _BV(RGB_DI_PIN & 0xF); + + ws2812_sendarray_mask((uint8_t*)ledarray,leds<<2,_BV(RGB_DI_PIN & 0xF)); _delay_us(80); } void ws2812_sendarray(uint8_t *data,uint16_t datlen) { - ws2812_sendarray_mask(data,datlen,_BV(ws2812_pin)); + ws2812_sendarray_mask(data,datlen,_BV(RGB_DI_PIN & 0xF)); } /* @@ -108,8 +115,10 @@ void inline ws2812_sendarray_mask(uint8_t *data,uint16_t datlen,uint8_t maskhi) uint8_t curbyte,ctr,masklo; uint8_t sreg_prev; - masklo =~maskhi&ws2812_PORTREG; - maskhi |= ws2812_PORTREG; + // masklo =~maskhi&ws2812_PORTREG; + // maskhi |= ws2812_PORTREG; + masklo =~maskhi&_SFR_IO8((RGB_DI_PIN >> 4) + 2); + maskhi |= _SFR_IO8((RGB_DI_PIN >> 4) + 2); sreg_prev=SREG; cli(); @@ -173,7 +182,7 @@ w_nop16 " dec %0 \n\t" // '1' [+2] '0' [+2] " brne loop%=\n\t" // '1' [+3] '0' [+4] : "=&d" (ctr) - : "r" (curbyte), "I" (_SFR_IO_ADDR(ws2812_PORTREG)), "r" (maskhi), "r" (masklo) + : "r" (curbyte), "I" (_SFR_IO_ADDR(_SFR_IO8((RGB_DI_PIN >> 4) + 2))), "r" (maskhi), "r" (masklo) ); } diff --git a/quantum/rgblight.c b/quantum/rgblight.c index c29ffedc3..b1b0f035d 100644 --- a/quantum/rgblight.c +++ b/quantum/rgblight.c @@ -146,7 +146,9 @@ void rgblight_init(void) { } eeconfig_debug_rgblight(); // display current eeprom values - rgblight_timer_init(); // setup the timer + #if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER) + rgblight_timer_init(); // setup the timer + #endif if (rgblight_config.enable) { rgblight_mode(rgblight_config.mode); @@ -192,14 +194,19 @@ void rgblight_mode(uint8_t mode) { eeconfig_update_rgblight(rgblight_config.raw); xprintf("rgblight mode: %u\n", rgblight_config.mode); if (rgblight_config.mode == 1) { - rgblight_timer_disable(); + #if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER) + rgblight_timer_disable(); + #endif } else if (rgblight_config.mode >=2 && rgblight_config.mode <=23) { // MODE 2-5, breathing // MODE 6-8, rainbow mood // MODE 9-14, rainbow swirl // MODE 15-20, snake // MODE 21-23, knight - rgblight_timer_enable(); + + #if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER) + rgblight_timer_enable(); + #endif } rgblight_sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val); } @@ -211,7 +218,10 @@ void rgblight_toggle(void) { if (rgblight_config.enable) { rgblight_mode(rgblight_config.mode); } else { - rgblight_timer_disable(); + + #if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER) + rgblight_timer_disable(); + #endif _delay_ms(50); rgblight_set(); } @@ -328,6 +338,9 @@ void rgblight_set(void) { } } + +#if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER) + // Animation timer -- AVR Timer3 void rgblight_timer_init(void) { static uint8_t rgblight_timer_is_init = 0; @@ -503,3 +516,5 @@ void rgblight_effect_knight(uint8_t interval) { } } + +#endif \ No newline at end of file diff --git a/quantum/rgblight.h b/quantum/rgblight.h index 64f92523e..def26c428 100644 --- a/quantum/rgblight.h +++ b/quantum/rgblight.h @@ -1,8 +1,11 @@ #ifndef RGBLIGHT_H #define RGBLIGHT_H -#ifndef RGBLIGHT_MODES -#define RGBLIGHT_MODES 23 + +#if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER) + #define RGBLIGHT_MODES 23 +#else + #define RGBLIGHT_MODES 1 #endif #ifndef RGBLIGHT_EFFECT_SNAKE_LENGTH -- cgit v1.2.3-24-g4f1b From c1dfb636ef61159456bdb24f4fee3f27e5babbeb Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Thu, 7 Jul 2016 12:22:10 -0400 Subject: fixes quantum template (actually) --- quantum/template/template.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'quantum') diff --git a/quantum/template/template.c b/quantum/template/template.c index 3057557ea..5ef349583 100644 --- a/quantum/template/template.c +++ b/quantum/template/template.c @@ -18,7 +18,7 @@ bool process_record_kb(uint16_t keycode, keyrecord_t *record) { // put your per-action keyboard code here // runs for every action, just before processing by the firmware - return process_record_user(record); + return process_record_user(keycode, record); } void led_set_kb(uint8_t usb_led) { -- cgit v1.2.3-24-g4f1b From 9870082a06386eba8c0c5f22da90d0256ef6244b Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Thu, 7 Jul 2016 19:48:39 +0300 Subject: Fix the range for consumer keys --- quantum/keymap_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'quantum') diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c index 76872ac59..d0a8312c1 100644 --- a/quantum/keymap_common.c +++ b/quantum/keymap_common.c @@ -62,7 +62,7 @@ action_t action_for_key(uint8_t layer, keypos_t key) case KC_SYSTEM_POWER ... KC_SYSTEM_WAKE: action.code = ACTION_USAGE_SYSTEM(KEYCODE2SYSTEM(keycode)); break; - case KC_AUDIO_MUTE ... KC_WWW_FAVORITES: + case KC_AUDIO_MUTE ... KC_MEDIA_REWIND: action.code = ACTION_USAGE_CONSUMER(KEYCODE2CONSUMER(keycode)); break; case KC_MS_UP ... KC_MS_ACCEL2: -- cgit v1.2.3-24-g4f1b From 50c686587ed49d8079ba1b11d45ceb6a55d6cd4b Mon Sep 17 00:00:00 2001 From: TerryMathews Date: Thu, 7 Jul 2016 23:34:33 -0400 Subject: Create keycodes for RGB control functions Moves RGB controls out of the macro function and assigns them their own keycodes: RGB_TOG (toggle on/off) RGB_MOD (mode step) RGB_HUI (increase hue) RGB_HUD (decrease hue) RGB_SAI (increase saturation) RGB_SAD (decrease saturation) RGB_VAI (increase brightness) RGB_VAD (decrease brightness) --- quantum/keymap.h | 10 ++++++++++ quantum/quantum.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) (limited to 'quantum') diff --git a/quantum/keymap.h b/quantum/keymap.h index 73f99f821..a15865183 100644 --- a/quantum/keymap.h +++ b/quantum/keymap.h @@ -156,6 +156,16 @@ enum quantum_keycodes { BL_INC, BL_TOGG, BL_STEP, + + // RGB functionality + RGB_TOG, + RGB_MOD, + RGB_HUI, + RGB_HUD, + RGB_SAI, + RGB_SAD, + RGB_VAI, + RGB_VAD, // Left shift, open paren KC_LSPO, diff --git a/quantum/quantum.c b/quantum/quantum.c index d8e43a465..5c0b53e22 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -103,6 +103,56 @@ bool process_record_quantum(keyrecord_t *record) { return false; } break; + #ifdef RGBLIGHT_ENABLE + case RGB_TOG: + if (record->event.pressed) { + rgblight_toggle(); + return false; + } + break; + case RGB_MOD: + if (record->event.pressed) { + rgblight_step(); + return false; + } + break; + case RGB_HUI: + if (record->event.pressed) { + rgblight_increase_hue(); + return false; + } + break; + case RGB_HUD: + if (record->event.pressed) { + rgblight_decrease_hue(); + return false; + } + break; + case RGB_SAI: + if (record->event.pressed) { + rgblight_increase_sat(); + return false; + } + break; + case RGB_SAD: + if (record->event.pressed) { + rgblight_decrease_sat(); + return false; + } + break; + case RGB_VAI: + if (record->event.pressed) { + rgblight_increase_val(); + return false; + } + break; + case RGB_VAD: + if (record->event.pressed) { + rgblight_decrease_val(); + return false; + } + break; + #endif case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_UNSWAP_ALT_GUI: if (record->event.pressed) { // MAGIC actions (BOOTMAGIC without the boot) -- cgit v1.2.3-24-g4f1b From f7a86822266603b8ffd21e9f89ec1de8d4950791 Mon Sep 17 00:00:00 2001 From: TerryMathews Date: Fri, 8 Jul 2016 03:32:28 -0400 Subject: Move return out of event if block According to Jack, this makes the return case not be processed. Doesn't break anything in the firmware. --- quantum/quantum.c | 52 ++++++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) (limited to 'quantum') diff --git a/quantum/quantum.c b/quantum/quantum.c index 5c0b53e22..09daa4712 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -93,65 +93,65 @@ bool process_record_quantum(keyrecord_t *record) { *(uint16_t *)0x0800 = 0x7777; // these two are a-star-specific #endif bootloader_jump(); - return false; } + return false; break; case DEBUG: if (record->event.pressed) { print("\nDEBUG: enabled.\n"); debug_enable = true; - return false; } + return false; break; #ifdef RGBLIGHT_ENABLE case RGB_TOG: if (record->event.pressed) { rgblight_toggle(); - return false; - } - break; + } + return false; + break; case RGB_MOD: if (record->event.pressed) { rgblight_step(); - return false; - } - break; + } + return false; + break; case RGB_HUI: if (record->event.pressed) { rgblight_increase_hue(); - return false; - } - break; + } + return false; + break; case RGB_HUD: if (record->event.pressed) { rgblight_decrease_hue(); - return false; - } - break; + } + return false; + break; case RGB_SAI: if (record->event.pressed) { rgblight_increase_sat(); - return false; - } - break; + } + return false; + break; case RGB_SAD: if (record->event.pressed) { rgblight_decrease_sat(); - return false; - } - break; + } + return false; + break; case RGB_VAI: if (record->event.pressed) { rgblight_increase_val(); - return false; - } - break; + } + return false; + break; case RGB_VAD: if (record->event.pressed) { rgblight_decrease_val(); - return false; - } - break; + } + return false; + break; #endif case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_UNSWAP_ALT_GUI: if (record->event.pressed) { -- cgit v1.2.3-24-g4f1b From b12fe6abb25db1feca6a7649097a8d1cb67a063f Mon Sep 17 00:00:00 2001 From: Smilliam Date: Sun, 10 Jul 2016 19:04:01 -0700 Subject: Made rollover behavior for space cadet optional --- quantum/quantum.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'quantum') diff --git a/quantum/quantum.c b/quantum/quantum.c index 71c3c723b..d91b8f2d0 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -162,10 +162,12 @@ bool process_record_quantum(keyrecord_t *record) { register_mods(MOD_BIT(KC_LSFT)); } else { - if (get_mods() & MOD_BIT(KC_RSFT)) { - shift_interrupted[0] = true; - shift_interrupted[1] = true; - } + #ifdef DISABLE_SPACE_CADET_ROLLOVER + if (get_mods() & MOD_BIT(KC_RSFT)) { + shift_interrupted[0] = true; + shift_interrupted[1] = true; + } + #endif if (!shift_interrupted[0]) { register_code(LSPO_KEY); unregister_code(LSPO_KEY); @@ -182,10 +184,12 @@ bool process_record_quantum(keyrecord_t *record) { register_mods(MOD_BIT(KC_RSFT)); } else { - if (get_mods() & MOD_BIT(KC_LSFT)) { - shift_interrupted[0] = true; - shift_interrupted[1] = true; - } + #ifdef DISABLE_SPACE_CADET_ROLLOVER + if (get_mods() & MOD_BIT(KC_LSFT)) { + shift_interrupted[0] = true; + shift_interrupted[1] = true; + } + #endif if (!shift_interrupted[1]) { register_code(RSPC_KEY); unregister_code(RSPC_KEY); -- cgit v1.2.3-24-g4f1b From a28a6e5b79c819e5f9323f62686498eca3ef399f Mon Sep 17 00:00:00 2001 From: Pavlos Vinieratos Date: Wed, 13 Jul 2016 16:38:02 +0200 Subject: extract reset keyboard into a function that makes it easy to call reset_keyboard() from a function in a keymap --- quantum/quantum.c | 24 ++++++++++++++---------- quantum/quantum.h | 2 ++ 2 files changed, 16 insertions(+), 10 deletions(-) (limited to 'quantum') diff --git a/quantum/quantum.c b/quantum/quantum.c index d5b9753b7..bc2da510f 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -15,6 +15,19 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { return true; } +void reset_keyboard(void) { + clear_keyboard(); +#ifdef AUDIO_ENABLE + stop_all_notes(); + shutdown_user(); +#endif + wait_ms(250); +#ifdef CATERINA_BOOTLOADER + *(uint16_t *)0x0800 = 0x7777; // these two are a-star-specific +#endif + bootloader_jump(); +} + // Shift / paren setup #ifndef LSPO_KEY @@ -83,16 +96,7 @@ bool process_record_quantum(keyrecord_t *record) { switch(keycode) { case RESET: if (record->event.pressed) { - clear_keyboard(); - #ifdef AUDIO_ENABLE - stop_all_notes(); - shutdown_user(); - #endif - wait_ms(250); - #ifdef CATERINA_BOOTLOADER - *(uint16_t *)0x0800 = 0x7777; // these two are a-star-specific - #endif - bootloader_jump(); + reset_keyboard(); } return false; break; diff --git a/quantum/quantum.h b/quantum/quantum.h index 3a0b74202..7ebfb24e3 100644 --- a/quantum/quantum.h +++ b/quantum/quantum.h @@ -77,6 +77,8 @@ bool process_action_kb(keyrecord_t *record); bool process_record_kb(uint16_t keycode, keyrecord_t *record); bool process_record_user(uint16_t keycode, keyrecord_t *record); +void reset_keyboard(void); + void startup_user(void); void shutdown_user(void); -- cgit v1.2.3-24-g4f1b From 010dd1308420e25b327fa4d5d6b13f67a849408b Mon Sep 17 00:00:00 2001 From: "Jonathan A. Kollasch" Date: Thu, 14 Jul 2016 11:04:25 -0500 Subject: keymap_extras: add newline at end of files --- quantum/keymap_extras/keymap_french.h | 2 +- quantum/keymap_extras/keymap_uk.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'quantum') diff --git a/quantum/keymap_extras/keymap_french.h b/quantum/keymap_extras/keymap_french.h index 2a44c80b1..4fd1f61ae 100644 --- a/quantum/keymap_extras/keymap_french.h +++ b/quantum/keymap_extras/keymap_french.h @@ -80,4 +80,4 @@ #define FR_EURO ALGR(KC_E) #define FR_BULT ALGR(FR_DLR) -#endif \ No newline at end of file +#endif diff --git a/quantum/keymap_extras/keymap_uk.h b/quantum/keymap_extras/keymap_uk.h index 5c5d95179..1458d64a9 100644 --- a/quantum/keymap_extras/keymap_uk.h +++ b/quantum/keymap_extras/keymap_uk.h @@ -33,4 +33,4 @@ #define UK_AACT ALGR(KC_A) -#endif \ No newline at end of file +#endif -- cgit v1.2.3-24-g4f1b From 25938a09a6bfb2624bc96841b53897eda532e293 Mon Sep 17 00:00:00 2001 From: "Jonathan A. Kollasch" Date: Thu, 14 Jul 2016 11:13:35 -0500 Subject: extra_keymaps: use RALT() instead of 0x1400 for AltGr --- quantum/keymap_extras/keymap_fr_ch.h | 2 +- quantum/keymap_extras/keymap_french.h | 2 +- quantum/keymap_extras/keymap_german.h | 2 +- quantum/keymap_extras/keymap_german_ch.h | 2 +- quantum/keymap_extras/keymap_nordic.h | 2 +- quantum/keymap_extras/keymap_spanish.h | 2 +- quantum/keymap_extras/keymap_uk.h | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) (limited to 'quantum') diff --git a/quantum/keymap_extras/keymap_fr_ch.h b/quantum/keymap_extras/keymap_fr_ch.h index 3fd971357..87d4bb24c 100644 --- a/quantum/keymap_extras/keymap_fr_ch.h +++ b/quantum/keymap_extras/keymap_fr_ch.h @@ -4,7 +4,7 @@ #include "keymap.h" // Alt gr -#define ALGR(kc) kc | 0x1400 +#define ALGR(kc) RALT(kc) #define FR_CH_ALGR KC_RALT // normal characters diff --git a/quantum/keymap_extras/keymap_french.h b/quantum/keymap_extras/keymap_french.h index 4fd1f61ae..834c69650 100644 --- a/quantum/keymap_extras/keymap_french.h +++ b/quantum/keymap_extras/keymap_french.h @@ -4,7 +4,7 @@ #include "keymap.h" // Alt gr -#define ALGR(kc) kc | 0x1400 +#define ALGR(kc) RALT(kc) #define NO_ALGR KC_RALT // Normal characters diff --git a/quantum/keymap_extras/keymap_german.h b/quantum/keymap_extras/keymap_german.h index 3f9ae8bad..7e2e0ed44 100644 --- a/quantum/keymap_extras/keymap_german.h +++ b/quantum/keymap_extras/keymap_german.h @@ -4,7 +4,7 @@ #include "keymap.h" // Alt gr -#define ALGR(kc) kc | 0x1400 +#define ALGR(kc) RALT(kc) #define DE_ALGR KC_RALT // normal characters diff --git a/quantum/keymap_extras/keymap_german_ch.h b/quantum/keymap_extras/keymap_german_ch.h index 6a782bcd7..b66d582a4 100644 --- a/quantum/keymap_extras/keymap_german_ch.h +++ b/quantum/keymap_extras/keymap_german_ch.h @@ -4,7 +4,7 @@ #include "keymap.h" // Alt gr -#define ALGR(kc) kc | 0x1400 +#define ALGR(kc) RALT(kc) #define CH_ALGR KC_RALT // normal characters diff --git a/quantum/keymap_extras/keymap_nordic.h b/quantum/keymap_extras/keymap_nordic.h index 3acb8b698..f8cf4e2e4 100644 --- a/quantum/keymap_extras/keymap_nordic.h +++ b/quantum/keymap_extras/keymap_nordic.h @@ -4,7 +4,7 @@ #include "keymap.h" // Alt gr -#define ALGR(kc) kc | 0x1400 +#define ALGR(kc) RALT(kc) #define NO_ALGR KC_RALT // Normal characters diff --git a/quantum/keymap_extras/keymap_spanish.h b/quantum/keymap_extras/keymap_spanish.h index af76e39fc..4ba568af2 100644 --- a/quantum/keymap_extras/keymap_spanish.h +++ b/quantum/keymap_extras/keymap_spanish.h @@ -4,7 +4,7 @@ #include "keymap.h" // Alt gr -#define ALGR(kc) kc | 0x1400 +#define ALGR(kc) RALT(kc) #define NO_ALGR KC_RALT // Normal characters diff --git a/quantum/keymap_extras/keymap_uk.h b/quantum/keymap_extras/keymap_uk.h index 1458d64a9..00c87afc3 100644 --- a/quantum/keymap_extras/keymap_uk.h +++ b/quantum/keymap_extras/keymap_uk.h @@ -4,7 +4,7 @@ #include "keymap.h" // Alt gr -#define ALGR(kc) kc | 0x1400 +#define ALGR(kc) RALT(kc) #define NO_ALGR KC_RALT // Normal characters -- cgit v1.2.3-24-g4f1b From 4278d8861526ed285d9d00badcdc8c121454be60 Mon Sep 17 00:00:00 2001 From: "Jonathan A. Kollasch" Date: Thu, 14 Jul 2016 11:32:43 -0500 Subject: keymap_dvorak.h: add missing shifted keys, fix whitespace --- quantum/keymap_extras/keymap_dvorak.h | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'quantum') diff --git a/quantum/keymap_extras/keymap_dvorak.h b/quantum/keymap_extras/keymap_dvorak.h index e855056e8..17f205977 100644 --- a/quantum/keymap_extras/keymap_dvorak.h +++ b/quantum/keymap_extras/keymap_dvorak.h @@ -18,18 +18,19 @@ #define DV_LBRC KC_MINS #define DV_RBRC KC_EQL -#define DV_QUOT KC_Q +#define DV_QUOT KC_Q #define DV_COMM KC_W #define DV_DOT KC_E #define DV_P KC_R #define DV_Y KC_T #define DV_F KC_Y #define DV_G KC_U -#define DV_C KC_I +#define DV_C KC_I #define DV_R KC_O #define DV_L KC_P #define DV_SLSH KC_LBRC #define DV_EQL KC_RBRC +#define DV_BSLS KC_BSLS #define DV_A KC_A #define DV_O KC_S @@ -68,7 +69,13 @@ #define DV_RPRN LSFT(DV_0) #define DV_LCBR LSFT(DV_LBRC) #define DV_RCBR LSFT(DV_RBRC) -#define DV_UNDS LSFT(DV_MINS) -#define DV_PLUS LSFT(DV_EQL) + +#define DV_QUES LSFT(DV_SLSH) +#define DV_PLUS LSFT(DV_EQL) +#define DV_PIPE LSFT(DV_BSLS) + +#define DV_UNDS LSFT(DV_MINS) + +#define DV_COLN LSFT(DV_SCLN) #endif -- cgit v1.2.3-24-g4f1b From 1a7e954f9fc4d250ba1ae46e3bfc168aca2b5cce Mon Sep 17 00:00:00 2001 From: Pavlos Vinieratos Date: Wed, 13 Jul 2016 00:20:28 +0200 Subject: in case its NULL --- quantum/process_keycode/process_tap_dance.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'quantum') diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c index 9b172e1b6..186889bc2 100644 --- a/quantum/process_keycode/process_tap_dance.c +++ b/quantum/process_keycode/process_tap_dance.c @@ -22,7 +22,9 @@ static void _process_tap_dance_action_pair (qk_tap_dance_state_t *state, static void _process_tap_dance_action_fn (qk_tap_dance_state_t *state, qk_tap_dance_user_fn_t fn) { - fn(state); + if (fn) { + fn(state); + } } void process_tap_dance_action (uint16_t keycode) -- cgit v1.2.3-24-g4f1b From f3b56701ed7e6c622dc48e429780124ba5fde172 Mon Sep 17 00:00:00 2001 From: Pavlos Vinieratos Date: Wed, 13 Jul 2016 16:47:45 +0200 Subject: add an `anyway` and a `reset` callback when using tap dance, we have the `regular` callback that is called on the last tap. this commit adds an `anyway` callback that is called on every tap, and a `reset` callback that is called on reset of the tap dance taps. --- quantum/process_keycode/process_tap_dance.c | 36 ++++++++++++++++++++++++++++- quantum/process_keycode/process_tap_dance.h | 28 ++++++++++++++++++---- 2 files changed, 59 insertions(+), 5 deletions(-) (limited to 'quantum') diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c index 186889bc2..40fba2a6a 100644 --- a/quantum/process_keycode/process_tap_dance.c +++ b/quantum/process_keycode/process_tap_dance.c @@ -40,7 +40,24 @@ void process_tap_dance_action (uint16_t keycode) action.pair.kc1, action.pair.kc2); break; case QK_TAP_DANCE_TYPE_FN: - _process_tap_dance_action_fn (&qk_tap_dance_state, action.fn); + _process_tap_dance_action_fn (&qk_tap_dance_state, action.fn.regular); + break; + + default: + break; + } +} + +void process_tap_dance_action_anyway (uint16_t keycode) +{ + uint16_t idx = keycode - QK_TAP_DANCE; + qk_tap_dance_action_t action; + + action = tap_dance_actions[idx]; + + switch (action.type) { + case QK_TAP_DANCE_TYPE_FN: + _process_tap_dance_action_fn (&qk_tap_dance_state, action.fn.anyway); break; default: @@ -53,6 +70,7 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { switch(keycode) { case QK_TAP_DANCE ... QK_TAP_DANCE_MAX: + process_tap_dance_action_anyway (qk_tap_dance_state.keycode); if (qk_tap_dance_state.keycode && qk_tap_dance_state.keycode != keycode) { process_tap_dance_action (qk_tap_dance_state.keycode); } else { @@ -68,6 +86,7 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { default: if (qk_tap_dance_state.keycode) { + //process_tap_dance_action_anyway (qk_tap_dance_state.keycode); process_tap_dance_action (qk_tap_dance_state.keycode); reset_tap_dance (&qk_tap_dance_state); @@ -87,6 +106,21 @@ void matrix_scan_tap_dance () { } void reset_tap_dance (qk_tap_dance_state_t *state) { + uint16_t idx = state->keycode - QK_TAP_DANCE; + qk_tap_dance_action_t action; + + action = tap_dance_actions[idx]; + switch (action.type) { + case QK_TAP_DANCE_TYPE_FN: + if (action.fn.reset) { + action.fn.reset(); + } + break; + + default: + break; + } + state->keycode = 0; state->count = 0; } diff --git a/quantum/process_keycode/process_tap_dance.h b/quantum/process_keycode/process_tap_dance.h index b9d7c7fcf..bf925df0f 100644 --- a/quantum/process_keycode/process_tap_dance.h +++ b/quantum/process_keycode/process_tap_dance.h @@ -22,6 +22,7 @@ typedef enum } qk_tap_dance_type_t; typedef void (*qk_tap_dance_user_fn_t) (qk_tap_dance_state_t *state); +typedef void (*qk_tap_dance_user_fn_reset_t) (void); typedef struct { @@ -31,18 +32,37 @@ typedef struct uint16_t kc1; uint16_t kc2; } pair; - qk_tap_dance_user_fn_t fn; + struct { + qk_tap_dance_user_fn_t regular; + qk_tap_dance_user_fn_t anyway; + qk_tap_dance_user_fn_reset_t reset; + } fn; }; } qk_tap_dance_action_t; #define ACTION_TAP_DANCE_DOUBLE(kc1, kc2) { \ - .type = QK_TAP_DANCE_TYPE_PAIR, \ - .pair = { kc1, kc2 } \ + .type = QK_TAP_DANCE_TYPE_PAIR, \ + .pair = { kc1, kc2 } \ } #define ACTION_TAP_DANCE_FN(user_fn) { \ .type = QK_TAP_DANCE_TYPE_FN, \ - .fn = user_fn \ + .fn = { user_fn, NULL, NULL } \ + } + +#define ACTION_TAP_DANCE_FN_ANYWAY(user_fn, user_fn_anyway) { \ + .type = QK_TAP_DANCE_TYPE_FN, \ + .fn = { user_fn, user_fn_anyway, NULL } \ + } + +#define ACTION_TAP_DANCE_FN_RESET(user_fn, user_fn_reset) { \ + .type = QK_TAP_DANCE_TYPE_FN, \ + .fn = { user_fn, NULL, user_fn_reset } \ + } + +#define ACTION_TAP_DANCE_FN_ANYWAY_RESET(user_fn, user_fn_anyway, user_fn_reset) { \ + .type = QK_TAP_DANCE_TYPE_FN, \ + .fn = { user_fn, user_fn_anyway, user_fn_reset } \ } extern const qk_tap_dance_action_t tap_dance_actions[]; -- cgit v1.2.3-24-g4f1b From d3091faf363afc8fef73ddf4948f872439b0e827 Mon Sep 17 00:00:00 2001 From: Pavlos Vinieratos Date: Fri, 15 Jul 2016 23:54:08 +0200 Subject: change naming, and remove extraneous definition --- quantum/process_keycode/process_tap_dance.c | 32 ++++++++++++++--------------- quantum/process_keycode/process_tap_dance.h | 27 ++++++++---------------- 2 files changed, 23 insertions(+), 36 deletions(-) (limited to 'quantum') diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c index 40fba2a6a..93b326b5f 100644 --- a/quantum/process_keycode/process_tap_dance.c +++ b/quantum/process_keycode/process_tap_dance.c @@ -27,7 +27,7 @@ static void _process_tap_dance_action_fn (qk_tap_dance_state_t *state, } } -void process_tap_dance_action (uint16_t keycode) +void process_tap_dance_action_on_each_tap (uint16_t keycode) { uint16_t idx = keycode - QK_TAP_DANCE; qk_tap_dance_action_t action; @@ -35,12 +35,8 @@ void process_tap_dance_action (uint16_t keycode) action = tap_dance_actions[idx]; switch (action.type) { - case QK_TAP_DANCE_TYPE_PAIR: - _process_tap_dance_action_pair (&qk_tap_dance_state, - action.pair.kc1, action.pair.kc2); - break; case QK_TAP_DANCE_TYPE_FN: - _process_tap_dance_action_fn (&qk_tap_dance_state, action.fn.regular); + _process_tap_dance_action_fn (&qk_tap_dance_state, action.fn.on_each_tap); break; default: @@ -48,7 +44,7 @@ void process_tap_dance_action (uint16_t keycode) } } -void process_tap_dance_action_anyway (uint16_t keycode) +void process_tap_dance_action_on_dance_finished (uint16_t keycode) { uint16_t idx = keycode - QK_TAP_DANCE; qk_tap_dance_action_t action; @@ -56,8 +52,12 @@ void process_tap_dance_action_anyway (uint16_t keycode) action = tap_dance_actions[idx]; switch (action.type) { + case QK_TAP_DANCE_TYPE_PAIR: + _process_tap_dance_action_pair (&qk_tap_dance_state, + action.pair.kc1, action.pair.kc2); + break; case QK_TAP_DANCE_TYPE_FN: - _process_tap_dance_action_fn (&qk_tap_dance_state, action.fn.anyway); + _process_tap_dance_action_fn (&qk_tap_dance_state, action.fn.on_dance_finished); break; default: @@ -70,9 +70,9 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { switch(keycode) { case QK_TAP_DANCE ... QK_TAP_DANCE_MAX: - process_tap_dance_action_anyway (qk_tap_dance_state.keycode); + process_tap_dance_action_on_each_tap (qk_tap_dance_state.keycode); if (qk_tap_dance_state.keycode && qk_tap_dance_state.keycode != keycode) { - process_tap_dance_action (qk_tap_dance_state.keycode); + process_tap_dance_action_on_dance_finished (qk_tap_dance_state.keycode); } else { r = false; } @@ -85,10 +85,9 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { break; default: + process_tap_dance_action_on_each_tap (qk_tap_dance_state.keycode); if (qk_tap_dance_state.keycode) { - //process_tap_dance_action_anyway (qk_tap_dance_state.keycode); - process_tap_dance_action (qk_tap_dance_state.keycode); - + process_tap_dance_action_on_dance_finished (qk_tap_dance_state.keycode); reset_tap_dance (&qk_tap_dance_state); } break; @@ -99,8 +98,7 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { void matrix_scan_tap_dance () { if (qk_tap_dance_state.keycode && timer_elapsed (qk_tap_dance_state.timer) > TAPPING_TERM) { - process_tap_dance_action (qk_tap_dance_state.keycode); - + process_tap_dance_action_on_dance_finished (qk_tap_dance_state.keycode); reset_tap_dance (&qk_tap_dance_state); } } @@ -112,8 +110,8 @@ void reset_tap_dance (qk_tap_dance_state_t *state) { action = tap_dance_actions[idx]; switch (action.type) { case QK_TAP_DANCE_TYPE_FN: - if (action.fn.reset) { - action.fn.reset(); + if (action.fn.on_reset) { + action.fn.on_reset(state); } break; diff --git a/quantum/process_keycode/process_tap_dance.h b/quantum/process_keycode/process_tap_dance.h index bf925df0f..7b820584a 100644 --- a/quantum/process_keycode/process_tap_dance.h +++ b/quantum/process_keycode/process_tap_dance.h @@ -22,7 +22,6 @@ typedef enum } qk_tap_dance_type_t; typedef void (*qk_tap_dance_user_fn_t) (qk_tap_dance_state_t *state); -typedef void (*qk_tap_dance_user_fn_reset_t) (void); typedef struct { @@ -33,9 +32,9 @@ typedef struct uint16_t kc2; } pair; struct { - qk_tap_dance_user_fn_t regular; - qk_tap_dance_user_fn_t anyway; - qk_tap_dance_user_fn_reset_t reset; + qk_tap_dance_user_fn_t on_each_tap; + qk_tap_dance_user_fn_t on_dance_finished; + qk_tap_dance_user_fn_t on_reset; } fn; }; } qk_tap_dance_action_t; @@ -45,24 +44,14 @@ typedef struct .pair = { kc1, kc2 } \ } -#define ACTION_TAP_DANCE_FN(user_fn) { \ +#define ACTION_TAP_DANCE_FN(user_fn) { \ .type = QK_TAP_DANCE_TYPE_FN, \ - .fn = { user_fn, NULL, NULL } \ + .fn = { NULL, user_fn, NULL } \ } -#define ACTION_TAP_DANCE_FN_ANYWAY(user_fn, user_fn_anyway) { \ - .type = QK_TAP_DANCE_TYPE_FN, \ - .fn = { user_fn, user_fn_anyway, NULL } \ - } - -#define ACTION_TAP_DANCE_FN_RESET(user_fn, user_fn_reset) { \ - .type = QK_TAP_DANCE_TYPE_FN, \ - .fn = { user_fn, NULL, user_fn_reset } \ - } - -#define ACTION_TAP_DANCE_FN_ANYWAY_RESET(user_fn, user_fn_anyway, user_fn_reset) { \ - .type = QK_TAP_DANCE_TYPE_FN, \ - .fn = { user_fn, user_fn_anyway, user_fn_reset } \ +#define ACTION_TAP_DANCE_FN_ADVANCED(user_fn_on_each_tap, user_fn_on_dance_finished, user_fn_on_reset) { \ + .type = QK_TAP_DANCE_TYPE_FN, \ + .fn = { user_fn_on_each_tap, user_fn_on_dance_finished, user_fn_on_reset } \ } extern const qk_tap_dance_action_t tap_dance_actions[]; -- cgit v1.2.3-24-g4f1b From dda2fd6ff3984ed96f8275c661b47a0484f9ee18 Mon Sep 17 00:00:00 2001 From: Pavlos Vinieratos Date: Mon, 18 Jul 2016 23:34:02 +0200 Subject: in the default case, it should be called if there is actually a tap dance happening, and in the normal case, it should be called when the tap down is happening. --- quantum/process_keycode/process_tap_dance.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'quantum') diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c index 93b326b5f..bab6bb81b 100644 --- a/quantum/process_keycode/process_tap_dance.c +++ b/quantum/process_keycode/process_tap_dance.c @@ -70,7 +70,6 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { switch(keycode) { case QK_TAP_DANCE ... QK_TAP_DANCE_MAX: - process_tap_dance_action_on_each_tap (qk_tap_dance_state.keycode); if (qk_tap_dance_state.keycode && qk_tap_dance_state.keycode != keycode) { process_tap_dance_action_on_dance_finished (qk_tap_dance_state.keycode); } else { @@ -81,12 +80,13 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { qk_tap_dance_state.keycode = keycode; qk_tap_dance_state.timer = timer_read (); qk_tap_dance_state.count++; + process_tap_dance_action_on_each_tap (qk_tap_dance_state.keycode); } break; default: - process_tap_dance_action_on_each_tap (qk_tap_dance_state.keycode); if (qk_tap_dance_state.keycode) { + process_tap_dance_action_on_each_tap (qk_tap_dance_state.keycode); process_tap_dance_action_on_dance_finished (qk_tap_dance_state.keycode); reset_tap_dance (&qk_tap_dance_state); } -- cgit v1.2.3-24-g4f1b From d5daec2a58019ebdb9804787e0f786e4fc3c05b9 Mon Sep 17 00:00:00 2001 From: Pavlos Vinieratos Date: Tue, 19 Jul 2016 18:00:59 +0200 Subject: on_each_tap_fn is called on tap down and tap up --- quantum/process_keycode/process_tap_dance.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'quantum') diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c index bab6bb81b..58192413f 100644 --- a/quantum/process_keycode/process_tap_dance.c +++ b/quantum/process_keycode/process_tap_dance.c @@ -70,6 +70,7 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { switch(keycode) { case QK_TAP_DANCE ... QK_TAP_DANCE_MAX: + process_tap_dance_action_on_each_tap (qk_tap_dance_state.keycode); if (qk_tap_dance_state.keycode && qk_tap_dance_state.keycode != keycode) { process_tap_dance_action_on_dance_finished (qk_tap_dance_state.keycode); } else { @@ -80,7 +81,6 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { qk_tap_dance_state.keycode = keycode; qk_tap_dance_state.timer = timer_read (); qk_tap_dance_state.count++; - process_tap_dance_action_on_each_tap (qk_tap_dance_state.keycode); } break; -- cgit v1.2.3-24-g4f1b From 4e6a8627d8ebd7af942f68142d1a959d60361d90 Mon Sep 17 00:00:00 2001 From: Pavlos Vinieratos Date: Tue, 19 Jul 2016 18:02:13 +0200 Subject: add a couple of comments --- quantum/process_keycode/process_tap_dance.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'quantum') diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c index 58192413f..b9b836df2 100644 --- a/quantum/process_keycode/process_tap_dance.c +++ b/quantum/process_keycode/process_tap_dance.c @@ -86,6 +86,7 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { default: if (qk_tap_dance_state.keycode) { + // if we are here, the tap dance was interrupted by a different key process_tap_dance_action_on_each_tap (qk_tap_dance_state.keycode); process_tap_dance_action_on_dance_finished (qk_tap_dance_state.keycode); reset_tap_dance (&qk_tap_dance_state); @@ -98,6 +99,7 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { void matrix_scan_tap_dance () { if (qk_tap_dance_state.keycode && timer_elapsed (qk_tap_dance_state.timer) > TAPPING_TERM) { + // if we are here, the tap dance was timed out process_tap_dance_action_on_dance_finished (qk_tap_dance_state.keycode); reset_tap_dance (&qk_tap_dance_state); } -- cgit v1.2.3-24-g4f1b From 70e42489dec375e558d8e81ed5ebfb69b4f3dbd9 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 20 Jul 2016 10:22:52 +0200 Subject: tap-dance: Support for holding keys With this change, tap dance will now store the pressed state of the tap-dance key, and allow one to make an action sooner, while the key is still held, and only unregister when the key is released. The registration must happen in the `on_dance_finished` callback, while unregistering goes to `on_reset`. The surrounding code makes sure not to call either multiple times. Signed-off-by: Gergely Nagy --- quantum/process_keycode/process_tap_dance.c | 11 ++++++++++- quantum/process_keycode/process_tap_dance.h | 2 ++ 2 files changed, 12 insertions(+), 1 deletion(-) (limited to 'quantum') diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c index b9b836df2..097440405 100644 --- a/quantum/process_keycode/process_tap_dance.c +++ b/quantum/process_keycode/process_tap_dance.c @@ -73,10 +73,14 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { process_tap_dance_action_on_each_tap (qk_tap_dance_state.keycode); if (qk_tap_dance_state.keycode && qk_tap_dance_state.keycode != keycode) { process_tap_dance_action_on_dance_finished (qk_tap_dance_state.keycode); + } else if (qk_tap_dance_state.active && qk_tap_dance_state.pressed) { + reset_tap_dance (&qk_tap_dance_state); } else { r = false; } + qk_tap_dance_state.active = true; + qk_tap_dance_state.pressed = record->event.pressed; if (record->event.pressed) { qk_tap_dance_state.keycode = keycode; qk_tap_dance_state.timer = timer_read (); @@ -90,6 +94,7 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { process_tap_dance_action_on_each_tap (qk_tap_dance_state.keycode); process_tap_dance_action_on_dance_finished (qk_tap_dance_state.keycode); reset_tap_dance (&qk_tap_dance_state); + qk_tap_dance_state.active = false; } break; } @@ -98,7 +103,7 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { } void matrix_scan_tap_dance () { - if (qk_tap_dance_state.keycode && timer_elapsed (qk_tap_dance_state.timer) > TAPPING_TERM) { + if (qk_tap_dance_state.active && timer_elapsed (qk_tap_dance_state.timer) > TAPPING_TERM) { // if we are here, the tap dance was timed out process_tap_dance_action_on_dance_finished (qk_tap_dance_state.keycode); reset_tap_dance (&qk_tap_dance_state); @@ -109,6 +114,9 @@ void reset_tap_dance (qk_tap_dance_state_t *state) { uint16_t idx = state->keycode - QK_TAP_DANCE; qk_tap_dance_action_t action; + if (state->pressed) + return; + action = tap_dance_actions[idx]; switch (action.type) { case QK_TAP_DANCE_TYPE_FN: @@ -123,4 +131,5 @@ void reset_tap_dance (qk_tap_dance_state_t *state) { state->keycode = 0; state->count = 0; + state->active = false; } diff --git a/quantum/process_keycode/process_tap_dance.h b/quantum/process_keycode/process_tap_dance.h index 7b820584a..d457db9b3 100644 --- a/quantum/process_keycode/process_tap_dance.h +++ b/quantum/process_keycode/process_tap_dance.h @@ -11,6 +11,8 @@ typedef struct uint8_t count; uint16_t keycode; uint16_t timer; + bool active:1; + bool pressed:1; } qk_tap_dance_state_t; #define TD(n) (QK_TAP_DANCE + n) -- cgit v1.2.3-24-g4f1b From ce8cc9219fca5dde077f1142d03d011b38d27479 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 20 Jul 2016 11:34:45 +0200 Subject: tap-dance: Support user_data for the callbacks Refactored the code a little, so all callbacks now receive a `user_data` pointer, which can be anything. As an example, the key pairs from `ACTION_TAP_DANCE_DOUBLE` now use this, and custom, built-in functions. This makes it easier to extend the tap dance functionality, and also simplifies the code a little. Signed-off-by: Gergely Nagy --- quantum/process_keycode/process_tap_dance.c | 61 ++++++++++------------------- quantum/process_keycode/process_tap_dance.h | 41 +++++++++---------- 2 files changed, 38 insertions(+), 64 deletions(-) (limited to 'quantum') diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c index 097440405..94b6af130 100644 --- a/quantum/process_keycode/process_tap_dance.c +++ b/quantum/process_keycode/process_tap_dance.c @@ -2,28 +2,32 @@ static qk_tap_dance_state_t qk_tap_dance_state; -static void _process_tap_dance_action_pair (qk_tap_dance_state_t *state, - uint16_t kc1, uint16_t kc2) { - uint16_t kc; +void qk_tap_dance_pair_finished (qk_tap_dance_state_t *state, void *user_data) { + qk_tap_dance_pair_t *pair = (qk_tap_dance_pair_t *)user_data; - if (state->count == 0) - return; - - kc = (state->count == 1) ? kc1 : kc2; + if (state->count == 1) { + register_code (pair->kc1); + } else if (state->count == 2) { + register_code (pair->kc2); + } +} - register_code (kc); - unregister_code (kc); +void qk_tap_dance_pair_reset (qk_tap_dance_state_t *state, void *user_data) { + qk_tap_dance_pair_t *pair = (qk_tap_dance_pair_t *)user_data; - if (state->count >= 2) { - reset_tap_dance (state); + if (state->count == 1) { + unregister_code (pair->kc1); + } else if (state->count == 2) { + unregister_code (pair->kc2); } } static void _process_tap_dance_action_fn (qk_tap_dance_state_t *state, + void *user_data, qk_tap_dance_user_fn_t fn) { if (fn) { - fn(state); + fn(state, user_data); } } @@ -34,14 +38,7 @@ void process_tap_dance_action_on_each_tap (uint16_t keycode) action = tap_dance_actions[idx]; - switch (action.type) { - case QK_TAP_DANCE_TYPE_FN: - _process_tap_dance_action_fn (&qk_tap_dance_state, action.fn.on_each_tap); - break; - - default: - break; - } + _process_tap_dance_action_fn (&qk_tap_dance_state, action.user_data, action.fn.on_each_tap); } void process_tap_dance_action_on_dance_finished (uint16_t keycode) @@ -51,18 +48,7 @@ void process_tap_dance_action_on_dance_finished (uint16_t keycode) action = tap_dance_actions[idx]; - switch (action.type) { - case QK_TAP_DANCE_TYPE_PAIR: - _process_tap_dance_action_pair (&qk_tap_dance_state, - action.pair.kc1, action.pair.kc2); - break; - case QK_TAP_DANCE_TYPE_FN: - _process_tap_dance_action_fn (&qk_tap_dance_state, action.fn.on_dance_finished); - break; - - default: - break; - } + _process_tap_dance_action_fn (&qk_tap_dance_state, action.user_data, action.fn.on_dance_finished); } bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { @@ -118,15 +104,8 @@ void reset_tap_dance (qk_tap_dance_state_t *state) { return; action = tap_dance_actions[idx]; - switch (action.type) { - case QK_TAP_DANCE_TYPE_FN: - if (action.fn.on_reset) { - action.fn.on_reset(state); - } - break; - - default: - break; + if (action.fn.on_reset) { + action.fn.on_reset(state, action.user_data); } state->keycode = 0; diff --git a/quantum/process_keycode/process_tap_dance.h b/quantum/process_keycode/process_tap_dance.h index d457db9b3..e2c74efe9 100644 --- a/quantum/process_keycode/process_tap_dance.h +++ b/quantum/process_keycode/process_tap_dance.h @@ -17,42 +17,34 @@ typedef struct #define TD(n) (QK_TAP_DANCE + n) -typedef enum -{ - QK_TAP_DANCE_TYPE_PAIR, - QK_TAP_DANCE_TYPE_FN, -} qk_tap_dance_type_t; - -typedef void (*qk_tap_dance_user_fn_t) (qk_tap_dance_state_t *state); +typedef void (*qk_tap_dance_user_fn_t) (qk_tap_dance_state_t *state, void *user_data); typedef struct { - qk_tap_dance_type_t type; - union { - struct { - uint16_t kc1; - uint16_t kc2; - } pair; - struct { - qk_tap_dance_user_fn_t on_each_tap; - qk_tap_dance_user_fn_t on_dance_finished; - qk_tap_dance_user_fn_t on_reset; - } fn; - }; + struct { + qk_tap_dance_user_fn_t on_each_tap; + qk_tap_dance_user_fn_t on_dance_finished; + qk_tap_dance_user_fn_t on_reset; + } fn; + void *user_data; } qk_tap_dance_action_t; +typedef struct +{ + uint16_t kc1; + uint16_t kc2; +} qk_tap_dance_pair_t; + #define ACTION_TAP_DANCE_DOUBLE(kc1, kc2) { \ - .type = QK_TAP_DANCE_TYPE_PAIR, \ - .pair = { kc1, kc2 } \ + .fn = { NULL, qk_tap_dance_pair_finished, qk_tap_dance_pair_reset }, \ + .user_data = (void *)&((qk_tap_dance_pair_t) { kc1, kc2 }) \ } #define ACTION_TAP_DANCE_FN(user_fn) { \ - .type = QK_TAP_DANCE_TYPE_FN, \ .fn = { NULL, user_fn, NULL } \ } #define ACTION_TAP_DANCE_FN_ADVANCED(user_fn_on_each_tap, user_fn_on_dance_finished, user_fn_on_reset) { \ - .type = QK_TAP_DANCE_TYPE_FN, \ .fn = { user_fn_on_each_tap, user_fn_on_dance_finished, user_fn_on_reset } \ } @@ -64,6 +56,9 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record); void matrix_scan_tap_dance (void); void reset_tap_dance (qk_tap_dance_state_t *state); +void qk_tap_dance_pair_finished (qk_tap_dance_state_t *state, void *user_data); +void qk_tap_dance_pair_reset (qk_tap_dance_state_t *state, void *user_data); + #else #define TD(n) KC_NO -- cgit v1.2.3-24-g4f1b From 44e16ffc80620b61eaa17aedcfdd8233d9c99bd9 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 20 Jul 2016 11:49:59 +0200 Subject: tap-dance: Code cleanup Removes a number of duplicated code, by passing actions around instead of keycodes, so the various dance action functions do not have to look up the action, but the caller does that for them. Signed-off-by: Gergely Nagy --- quantum/process_keycode/process_tap_dance.c | 45 +++++++++++++++-------------- 1 file changed, 24 insertions(+), 21 deletions(-) (limited to 'quantum') diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c index 94b6af130..d240dc2e6 100644 --- a/quantum/process_keycode/process_tap_dance.c +++ b/quantum/process_keycode/process_tap_dance.c @@ -22,7 +22,7 @@ void qk_tap_dance_pair_reset (qk_tap_dance_state_t *state, void *user_data) { } } -static void _process_tap_dance_action_fn (qk_tap_dance_state_t *state, +static inline void _process_tap_dance_action_fn (qk_tap_dance_state_t *state, void *user_data, qk_tap_dance_user_fn_t fn) { @@ -31,34 +31,33 @@ static void _process_tap_dance_action_fn (qk_tap_dance_state_t *state, } } -void process_tap_dance_action_on_each_tap (uint16_t keycode) +static inline void process_tap_dance_action_on_each_tap (qk_tap_dance_action_t action) { - uint16_t idx = keycode - QK_TAP_DANCE; - qk_tap_dance_action_t action; - - action = tap_dance_actions[idx]; - _process_tap_dance_action_fn (&qk_tap_dance_state, action.user_data, action.fn.on_each_tap); } -void process_tap_dance_action_on_dance_finished (uint16_t keycode) +static inline void process_tap_dance_action_on_dance_finished (qk_tap_dance_action_t action) { - uint16_t idx = keycode - QK_TAP_DANCE; - qk_tap_dance_action_t action; - - action = tap_dance_actions[idx]; - _process_tap_dance_action_fn (&qk_tap_dance_state, action.user_data, action.fn.on_dance_finished); } +static inline void process_tap_dance_action_on_reset (qk_tap_dance_action_t action) +{ + _process_tap_dance_action_fn (&qk_tap_dance_state, action.user_data, action.fn.on_reset); +} + bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { bool r = true; + uint16_t idx = keycode - QK_TAP_DANCE; + qk_tap_dance_action_t action; switch(keycode) { case QK_TAP_DANCE ... QK_TAP_DANCE_MAX: - process_tap_dance_action_on_each_tap (qk_tap_dance_state.keycode); + action = tap_dance_actions[idx]; + + process_tap_dance_action_on_each_tap (action); if (qk_tap_dance_state.keycode && qk_tap_dance_state.keycode != keycode) { - process_tap_dance_action_on_dance_finished (qk_tap_dance_state.keycode); + process_tap_dance_action_on_dance_finished (action); } else if (qk_tap_dance_state.active && qk_tap_dance_state.pressed) { reset_tap_dance (&qk_tap_dance_state); } else { @@ -77,8 +76,11 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { default: if (qk_tap_dance_state.keycode) { // if we are here, the tap dance was interrupted by a different key - process_tap_dance_action_on_each_tap (qk_tap_dance_state.keycode); - process_tap_dance_action_on_dance_finished (qk_tap_dance_state.keycode); + idx = qk_tap_dance_state.keycode - QK_TAP_DANCE; + action = tap_dance_actions[idx]; + + process_tap_dance_action_on_each_tap (action); + process_tap_dance_action_on_dance_finished (action); reset_tap_dance (&qk_tap_dance_state); qk_tap_dance_state.active = false; } @@ -91,7 +93,10 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { void matrix_scan_tap_dance () { if (qk_tap_dance_state.active && timer_elapsed (qk_tap_dance_state.timer) > TAPPING_TERM) { // if we are here, the tap dance was timed out - process_tap_dance_action_on_dance_finished (qk_tap_dance_state.keycode); + uint16_t idx = qk_tap_dance_state.keycode - QK_TAP_DANCE; + qk_tap_dance_action_t action = tap_dance_actions[idx]; + + process_tap_dance_action_on_dance_finished (action); reset_tap_dance (&qk_tap_dance_state); } } @@ -104,9 +109,7 @@ void reset_tap_dance (qk_tap_dance_state_t *state) { return; action = tap_dance_actions[idx]; - if (action.fn.on_reset) { - action.fn.on_reset(state, action.user_data); - } + process_tap_dance_action_on_reset (action); state->keycode = 0; state->count = 0; -- cgit v1.2.3-24-g4f1b From 7b4d30ee50aa534a973473c715924964991739f0 Mon Sep 17 00:00:00 2001 From: Vivien Alger Date: Sun, 24 Jul 2016 10:57:49 +0200 Subject: Fix some errors in bepo mapping --- quantum/keymap_extras/keymap_bepo.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'quantum') diff --git a/quantum/keymap_extras/keymap_bepo.h b/quantum/keymap_extras/keymap_bepo.h index 4c3096054..e5ef39552 100644 --- a/quantum/keymap_extras/keymap_bepo.h +++ b/quantum/keymap_extras/keymap_bepo.h @@ -118,7 +118,7 @@ // Fourth row #define BP_COLON LSFT(BP_DOT) // : #define BP_COLN BP_COLON -#define BP_QUESTION LSFT(BP_QUOTE) // ? +#define BP_QUESTION LSFT(BP_APOS) // ? #define BP_QEST BP_QUESTION // Space bar @@ -183,7 +183,7 @@ // Third row #define BP_AE_LIGATURE ALTGR(BP_A) // æ #define BP_AE BP_AE_LIGATURE -#define BP_U_GRAVE AGR(BP_U) // ù +#define BP_U_GRAVE ALTGR(BP_U) // ù #define BP_UGRV BP_U_GRAVE #define BP_DEAD_TREMA ALTGR(BP_I) // dead ¨ (trema/umlaut/diaresis) #define BP_DTRM BP_DEAD_TREMA -- cgit v1.2.3-24-g4f1b From 3ea738e450e9326b0d3ee4192da881cffb4c13c1 Mon Sep 17 00:00:00 2001 From: Robert Dale Date: Sun, 24 Jul 2016 10:00:39 -0400 Subject: ensure there's a recording to play before playing; also enables the LGUI button to play a tone --- quantum/process_keycode/process_music.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'quantum') diff --git a/quantum/process_keycode/process_music.c b/quantum/process_keycode/process_music.c index c8f3ddb90..2d52e47a7 100644 --- a/quantum/process_keycode/process_music.c +++ b/quantum/process_keycode/process_music.c @@ -6,6 +6,7 @@ int offset = 7; // music sequencer static bool music_sequence_recording = false; +static bool music_sequence_recorded = false; static bool music_sequence_playing = false; static float music_sequence[16] = {0}; static uint8_t music_sequence_count = 0; @@ -77,6 +78,7 @@ bool process_music(uint16_t keycode, keyrecord_t *record) { if (keycode == KC_LCTL && record->event.pressed) { // Start recording stop_all_notes(); music_sequence_recording = true; + music_sequence_recorded = false; music_sequence_playing = false; music_sequence_count = 0; return false; @@ -84,12 +86,15 @@ bool process_music(uint16_t keycode, keyrecord_t *record) { if (keycode == KC_LALT && record->event.pressed) { // Stop recording/playing stop_all_notes(); + if (music_sequence_recording) { // was recording + music_sequence_recorded = true; + } music_sequence_recording = false; music_sequence_playing = false; return false; } - if (keycode == KC_LGUI && record->event.pressed) { // Start playing + if (keycode == KC_LGUI && record->event.pressed && music_sequence_recorded) { // Start playing stop_all_notes(); music_sequence_recording = false; music_sequence_playing = true; -- cgit v1.2.3-24-g4f1b From 8b94e26d7c3b30cc57d710a11e5651d15e8e3b20 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Sun, 24 Jul 2016 22:07:43 -0400 Subject: Fixes midi functionality --- quantum/keymap_common.c | 2 +- quantum/process_keycode/process_midi.c | 24 ++++++++++++------------ 2 files changed, 13 insertions(+), 13 deletions(-) (limited to 'quantum') diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c index d0a8312c1..833e5a8f8 100644 --- a/quantum/keymap_common.c +++ b/quantum/keymap_common.c @@ -30,7 +30,7 @@ along with this program. If not, see . #include "quantum.h" #ifdef MIDI_ENABLE - #include "keymap_midi.h" + #include "process_midi.h" #endif extern keymap_config_t keymap_config; diff --git a/quantum/process_keycode/process_midi.c b/quantum/process_keycode/process_midi.c index d6ab9c626..8784e64f3 100644 --- a/quantum/process_keycode/process_midi.c +++ b/quantum/process_keycode/process_midi.c @@ -1,8 +1,8 @@ #include "process_midi.h" bool midi_activated = false; -uint8_t starting_note = 0x0C; -int offset = 7; +uint8_t midi_starting_note = 0x0C; +int midi_offset = 7; bool process_midi(uint16_t keycode, keyrecord_t *record) { if (keycode == MI_ON && record->event.pressed) { @@ -20,42 +20,42 @@ bool process_midi(uint16_t keycode, keyrecord_t *record) { if (midi_activated) { if (record->event.key.col == (MATRIX_COLS - 1) && record->event.key.row == (MATRIX_ROWS - 1)) { if (record->event.pressed) { - starting_note++; // Change key + midi_starting_note++; // Change key midi_send_cc(&midi_device, 0, 0x7B, 0); } return false; } if (record->event.key.col == (MATRIX_COLS - 2) && record->event.key.row == (MATRIX_ROWS - 1)) { if (record->event.pressed) { - starting_note--; // Change key + midi_starting_note--; // Change key midi_send_cc(&midi_device, 0, 0x7B, 0); } return false; } if (record->event.key.col == (MATRIX_COLS - 3) && record->event.key.row == (MATRIX_ROWS - 1) && record->event.pressed) { - offset++; // Change scale + midi_offset++; // Change scale midi_send_cc(&midi_device, 0, 0x7B, 0); return false; } if (record->event.key.col == (MATRIX_COLS - 4) && record->event.key.row == (MATRIX_ROWS - 1) && record->event.pressed) { - offset--; // Change scale + midi_offset--; // Change scale midi_send_cc(&midi_device, 0, 0x7B, 0); return false; } // basic - // uint8_t note = (starting_note + SCALE[record->event.key.col + offset])+12*(MATRIX_ROWS - record->event.key.row); + // uint8_t note = (midi_starting_note + SCALE[record->event.key.col + midi_offset])+12*(MATRIX_ROWS - record->event.key.row); // advanced - // uint8_t note = (starting_note + record->event.key.col + offset)+12*(MATRIX_ROWS - record->event.key.row); + // uint8_t note = (midi_starting_note + record->event.key.col + midi_offset)+12*(MATRIX_ROWS - record->event.key.row); // guitar - uint8_t note = (starting_note + record->event.key.col + offset)+5*(MATRIX_ROWS - record->event.key.row); + uint8_t note = (midi_starting_note + record->event.key.col + midi_offset)+5*(MATRIX_ROWS - record->event.key.row); // violin - // uint8_t note = (starting_note + record->event.key.col + offset)+7*(MATRIX_ROWS - record->event.key.row); + // uint8_t note = (midi_starting_note + record->event.key.col + midi_offset)+7*(MATRIX_ROWS - record->event.key.row); if (record->event.pressed) { - // midi_send_noteon(&midi_device, record->event.key.row, starting_note + SCALE[record->event.key.col], 127); + // midi_send_noteon(&midi_device, record->event.key.row, midi_starting_note + SCALE[record->event.key.col], 127); midi_send_noteon(&midi_device, 0, note, 127); } else { - // midi_send_noteoff(&midi_device, record->event.key.row, starting_note + SCALE[record->event.key.col], 127); + // midi_send_noteoff(&midi_device, record->event.key.row, midi_starting_note + SCALE[record->event.key.col], 127); midi_send_noteoff(&midi_device, 0, note, 127); } -- cgit v1.2.3-24-g4f1b From b6fa762234fb5a3590d0ff91ffdf5aa3ae322c8f Mon Sep 17 00:00:00 2001 From: Andreas Lindhé Date: Mon, 25 Jul 2016 11:29:54 +0200 Subject: Fix misspelled command in Norwegian helper --- quantum/keymap_extras/keymap_norwegian.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'quantum') diff --git a/quantum/keymap_extras/keymap_norwegian.h b/quantum/keymap_extras/keymap_norwegian.h index 018bfeae5..5c4e8c495 100644 --- a/quantum/keymap_extras/keymap_norwegian.h +++ b/quantum/keymap_extras/keymap_norwegian.h @@ -13,7 +13,7 @@ #undef NO_BSLS #define NO_BSLS KC_EQL // '\' #undef NO_CIRC -#define NO_CIRC LSFT(C_RBRC) // ^ +#define NO_CIRC LSFT(KC_RBRC) // ^ #undef NO_GRV #define NO_GRV LSFT(NO_BSLS) // #undef NO_OSLH -- cgit v1.2.3-24-g4f1b From 283ebbe14298fe75128765fa42c46f02534fb761 Mon Sep 17 00:00:00 2001 From: Andreas Lindhé Date: Mon, 25 Jul 2016 12:50:27 +0200 Subject: Change Nordic ampersand code to match the English Changed from "NO_AMP" to "NO_AMPR" since the KC one is "KC_AMPR" --- quantum/keymap_extras/keymap_nordic.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'quantum') diff --git a/quantum/keymap_extras/keymap_nordic.h b/quantum/keymap_extras/keymap_nordic.h index f8cf4e2e4..da5c82975 100644 --- a/quantum/keymap_extras/keymap_nordic.h +++ b/quantum/keymap_extras/keymap_nordic.h @@ -25,7 +25,7 @@ #define NO_SECT LSFT(NO_HALF) #define NO_QUO2 LSFT(KC_2) #define NO_BULT LSFT(KC_4) -#define NO_AMP LSFT(KC_6) +#define NO_AMPR LSFT(KC_6) #define NO_SLSH LSFT(KC_7) #define NO_LPRN LSFT(KC_8) #define NO_RPRN LSFT(KC_9) -- cgit v1.2.3-24-g4f1b From 3a860c4bc210857f03ef9fae5043d6d5736d140d Mon Sep 17 00:00:00 2001 From: Jordi Orlando <0xdec@users.noreply.github.com> Date: Tue, 26 Jul 2016 14:43:45 -0500 Subject: Clean up rgblight.c Fix formatting issues, clarify comments --- quantum/rgblight.c | 731 +++++++++++++++++++++++++++-------------------------- 1 file changed, 377 insertions(+), 354 deletions(-) (limited to 'quantum') diff --git a/quantum/rgblight.c b/quantum/rgblight.c index b1b0f035d..1b3c576d1 100644 --- a/quantum/rgblight.c +++ b/quantum/rgblight.c @@ -7,24 +7,41 @@ #include "debug.h" const uint8_t DIM_CURVE[] PROGMEM = { - 0, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, - 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, - 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, - 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, - 15, 15, 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 20, - 20, 20, 21, 21, 22, 22, 22, 23, 23, 24, 24, 25, 25, 25, 26, 26, - 27, 27, 28, 28, 29, 29, 30, 30, 31, 32, 32, 33, 33, 34, 35, 35, - 36, 36, 37, 38, 38, 39, 40, 40, 41, 42, 43, 43, 44, 45, 46, 47, - 48, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, 66, 68, 69, 70, 71, 73, 74, 75, 76, 78, 79, 81, 82, - 83, 85, 86, 88, 90, 91, 93, 94, 96, 98, 99, 101, 103, 105, 107, 109, - 110, 112, 114, 116, 118, 121, 123, 125, 127, 129, 132, 134, 136, 139, 141, 144, - 146, 149, 151, 154, 157, 159, 162, 165, 168, 171, 174, 177, 180, 183, 186, 190, - 193, 196, 200, 203, 207, 211, 214, 218, 222, 226, 230, 234, 238, 242, 248, 255, + 0, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, + 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, + 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, + 15, 15, 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 20, + 20, 20, 21, 21, 22, 22, 22, 23, 23, 24, 24, 25, 25, 25, 26, 26, + 27, 27, 28, 28, 29, 29, 30, 30, 31, 32, 32, 33, 33, 34, 35, 35, + 36, 36, 37, 38, 38, 39, 40, 40, 41, 42, 43, 43, 44, 45, 46, 47, + 48, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 68, 69, 70, 71, 73, 74, 75, 76, 78, 79, 81, 82, + 83, 85, 86, 88, 90, 91, 93, 94, 96, 98, 99, 101, 103, 105, 107, 109, + 110, 112, 114, 116, 118, 121, 123, 125, 127, 129, 132, 134, 136, 139, 141, 144, + 146, 149, 151, 154, 157, 159, 162, 165, 168, 171, 174, 177, 180, 183, 186, 190, + 193, 196, 200, 203, 207, 211, 214, 218, 222, 226, 230, 234, 238, 242, 248, 255 +}; +const uint8_t RGBLED_BREATHING_TABLE[] PROGMEM = { + 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 5, 5, 6, 7, 9, + 10, 11, 12, 14, 15, 17, 18, 20, 21, 23, 25, 27, 29, 31, 33, 35, + 37, 40, 42, 44, 47, 49, 52, 54, 57, 59, 62, 65, 67, 70, 73, 76, + 79, 82, 85, 88, 90, 93, 97, 100, 103, 106, 109, 112, 115, 118, 121, 124, + 127, 131, 134, 137, 140, 143, 146, 149, 152, 155, 158, 162, 165, 167, 170, 173, + 176, 179, 182, 185, 188, 190, 193, 196, 198, 201, 203, 206, 208, 211, 213, 215, + 218, 220, 222, 224, 226, 228, 230, 232, 234, 235, 237, 238, 240, 241, 243, 244, + 245, 246, 248, 249, 250, 250, 251, 252, 253, 253, 254, 254, 254, 255, 255, 255, + 255, 255, 255, 255, 254, 254, 254, 253, 253, 252, 251, 250, 250, 249, 248, 246, + 245, 244, 243, 241, 240, 238, 237, 235, 234, 232, 230, 228, 226, 224, 222, 220, + 218, 215, 213, 211, 208, 206, 203, 201, 198, 196, 193, 190, 188, 185, 182, 179, + 176, 173, 170, 167, 165, 162, 158, 155, 152, 149, 146, 143, 140, 137, 134, 131, + 128, 124, 121, 118, 115, 112, 109, 106, 103, 100, 97, 93, 90, 88, 85, 82, + 79, 76, 73, 70, 67, 65, 62, 59, 57, 54, 52, 49, 47, 44, 42, 40, + 37, 35, 33, 31, 29, 27, 25, 23, 21, 20, 18, 17, 15, 14, 12, 11, + 10, 9, 7, 6, 5, 5, 4, 3, 2, 2, 1, 1, 1, 0, 0, 0 }; -const uint8_t RGBLED_BREATHING_TABLE[] PROGMEM = {0,0,0,0,1,1,1,2,2,3,4,5,5,6,7,9,10,11,12,14,15,17,18,20,21,23,25,27,29,31,33,35,37,40,42,44,47,49,52,54,57,59,62,65,67,70,73,76,79,82,85,88,90,93,97,100,103,106,109,112,115,118,121,124,127,131,134,137,140,143,146,149,152,155,158,162,165,167,170,173,176,179,182,185,188,190,193,196,198,201,203,206,208,211,213,215,218,220,222,224,226,228,230,232,234,235,237,238,240,241,243,244,245,246,248,249,250,250,251,252,253,253,254,254,254,255,255,255,255,255,255,255,254,254,254,253,253,252,251,250,250,249,248,246,245,244,243,241,240,238,237,235,234,232,230,228,226,224,222,220,218,215,213,211,208,206,203,201,198,196,193,190,188,185,182,179,176,173,170,167,165,162,158,155,152,149,146,143,140,137,134,131,128,124,121,118,115,112,109,106,103,100,97,93,90,88,85,82,79,76,73,70,67,65,62,59,57,54,52,49,47,44,42,40,37,35,33,31,29,27,25,23,21,20,18,17,15,14,12,11,10,9,7,6,5,5,4,3,2,2,1,1,1,0,0,0}; const uint8_t RGBLED_BREATHING_INTERVALS[] PROGMEM = {30, 20, 10, 5}; const uint8_t RGBLED_RAINBOW_MOOD_INTERVALS[] PROGMEM = {120, 60, 30}; const uint8_t RGBLED_RAINBOW_SWIRL_INTERVALS[] PROGMEM = {100, 50, 20}; @@ -38,62 +55,56 @@ uint8_t rgblight_inited = 0; void sethsv(uint16_t hue, uint8_t sat, uint8_t val, struct cRGB *led1) { - /* convert hue, saturation and brightness ( HSB/HSV ) to RGB - The DIM_CURVE is used only on brightness/value and on saturation (inverted). - This looks the most natural. - */ + /* Convert hue, saturation and brightness ( HSB/HSV ) to RGB. The DIM_CURVE is + used only on brightness/value and on saturation (inverted). This looks the + most natural. */ uint8_t r = 0, g = 0, b = 0; val = pgm_read_byte(&DIM_CURVE[val]); - sat = 255 - pgm_read_byte(&DIM_CURVE[255 - sat]); - - uint8_t base; - - if (sat == 0) { // Acromatic color (gray). Hue doesn't mind. - r = val; - g = val; - b = val; - } else { - base = ((255 - sat) * val) >> 8; - - switch (hue / 60) { - case 0: - r = val; - g = (((val - base)*hue) / 60) + base; - b = base; - break; - - case 1: - r = (((val - base)*(60 - (hue % 60))) / 60) + base; - g = val; - b = base; - break; - - case 2: - r = base; - g = val; - b = (((val - base)*(hue % 60)) / 60) + base; - break; - - case 3: - r = base; - g = (((val - base)*(60 - (hue % 60))) / 60) + base; - b = val; - break; - - case 4: - r = (((val - base)*(hue % 60)) / 60) + base; - g = base; - b = val; - break; - - case 5: - r = val; - g = base; - b = (((val - base)*(60 - (hue % 60))) / 60) + base; - break; - } - } + sat = 255 - pgm_read_byte(&DIM_CURVE[255 - sat]); + + uint8_t base; + + if (sat == 0) { // Acromatic color (gray). Hue doesn't mind. + r = val; + g = val; + b = val; + } else { + base = ((255 - sat) * val) >> 8; + + switch (hue / 60) { + case 0: + r = val; + g = (((val - base) * hue) / 60) + base; + b = base; + break; + case 1: + r = (((val - base) * (60 - (hue % 60))) / 60) + base; + g = val; + b = base; + break; + case 2: + r = base; + g = val; + b = (((val - base) * (hue % 60)) / 60) + base; + break; + case 3: + r = base; + g = (((val - base) * (60 - (hue % 60))) / 60) + base; + b = val; + break; + case 4: + r = (((val - base) * (hue % 60)) / 60) + base; + g = base; + b = val; + break; + case 5: + r = val; + g = base; + b = (((val - base) * (60 - (hue % 60))) / 60) + base; + break; + } + } setrgb(r,g,b, led1); } @@ -111,44 +122,44 @@ void eeconfig_update_rgblight(uint32_t val) { eeprom_update_dword(EECONFIG_RGBLIGHT, val); } void eeconfig_update_rgblight_default(void) { - dprintf("eeconfig_update_rgblight_default\n"); - rgblight_config.enable = 1; - rgblight_config.mode = 1; - rgblight_config.hue = 200; - rgblight_config.sat = 204; - rgblight_config.val = 204; - eeconfig_update_rgblight(rgblight_config.raw); + dprintf("eeconfig_update_rgblight_default\n"); + rgblight_config.enable = 1; + rgblight_config.mode = 1; + rgblight_config.hue = 200; + rgblight_config.sat = 204; + rgblight_config.val = 204; + eeconfig_update_rgblight(rgblight_config.raw); } void eeconfig_debug_rgblight(void) { - dprintf("rgblight_config eprom\n"); - dprintf("rgblight_config.enable = %d\n", rgblight_config.enable); - dprintf("rghlight_config.mode = %d\n", rgblight_config.mode); - dprintf("rgblight_config.hue = %d\n", rgblight_config.hue); - dprintf("rgblight_config.sat = %d\n", rgblight_config.sat); - dprintf("rgblight_config.val = %d\n", rgblight_config.val); + dprintf("rgblight_config eprom\n"); + dprintf("rgblight_config.enable = %d\n", rgblight_config.enable); + dprintf("rghlight_config.mode = %d\n", rgblight_config.mode); + dprintf("rgblight_config.hue = %d\n", rgblight_config.hue); + dprintf("rgblight_config.sat = %d\n", rgblight_config.sat); + dprintf("rgblight_config.val = %d\n", rgblight_config.val); } void rgblight_init(void) { debug_enable = 1; // Debug ON! - dprintf("rgblight_init called.\n"); + dprintf("rgblight_init called.\n"); rgblight_inited = 1; - dprintf("rgblight_init start!\n"); + dprintf("rgblight_init start!\n"); if (!eeconfig_is_enabled()) { - dprintf("rgblight_init eeconfig is not enabled.\n"); + dprintf("rgblight_init eeconfig is not enabled.\n"); eeconfig_init(); - eeconfig_update_rgblight_default(); + eeconfig_update_rgblight_default(); } rgblight_config.raw = eeconfig_read_rgblight(); - if (!rgblight_config.mode) { - dprintf("rgblight_init rgblight_config.mode = 0. Write default values to EEPROM.\n"); - eeconfig_update_rgblight_default(); - rgblight_config.raw = eeconfig_read_rgblight(); - } - eeconfig_debug_rgblight(); // display current eeprom values + if (!rgblight_config.mode) { + dprintf("rgblight_init rgblight_config.mode = 0. Write default values to EEPROM.\n"); + eeconfig_update_rgblight_default(); + rgblight_config.raw = eeconfig_read_rgblight(); + } + eeconfig_debug_rgblight(); // display current eeprom values - #if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER) - rgblight_timer_init(); // setup the timer - #endif + #if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER) + rgblight_timer_init(); // setup the timer + #endif if (rgblight_config.enable) { rgblight_mode(rgblight_config.mode); @@ -156,58 +167,57 @@ void rgblight_init(void) { } void rgblight_increase(void) { - uint8_t mode = 0; + uint8_t mode = 0; if (rgblight_config.mode < RGBLIGHT_MODES) { mode = rgblight_config.mode + 1; } - rgblight_mode(mode); + rgblight_mode(mode); } - void rgblight_decrease(void) { - uint8_t mode = 0; - if (rgblight_config.mode > 1) { //mode will never < 1, if mode is less than 1, eeprom need to be initialized. - mode = rgblight_config.mode-1; + uint8_t mode = 0; + // Mode will never be < 1. If it ever is, eeprom needs to be initialized. + if (rgblight_config.mode > 1) { + mode = rgblight_config.mode - 1; } - rgblight_mode(mode); + rgblight_mode(mode); } - void rgblight_step(void) { - uint8_t mode = 0; + uint8_t mode = 0; mode = rgblight_config.mode + 1; if (mode > RGBLIGHT_MODES) { mode = 1; } - rgblight_mode(mode); + rgblight_mode(mode); } void rgblight_mode(uint8_t mode) { - if (!rgblight_config.enable) { - return; - } - if (mode<1) { - rgblight_config.mode = 1; - } else if (mode > RGBLIGHT_MODES) { - rgblight_config.mode = RGBLIGHT_MODES; - } else { - rgblight_config.mode = mode; - } + if (!rgblight_config.enable) { + return; + } + if (mode < 1) { + rgblight_config.mode = 1; + } else if (mode > RGBLIGHT_MODES) { + rgblight_config.mode = RGBLIGHT_MODES; + } else { + rgblight_config.mode = mode; + } eeconfig_update_rgblight(rgblight_config.raw); xprintf("rgblight mode: %u\n", rgblight_config.mode); - if (rgblight_config.mode == 1) { - #if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER) - rgblight_timer_disable(); - #endif - } else if (rgblight_config.mode >=2 && rgblight_config.mode <=23) { - // MODE 2-5, breathing - // MODE 6-8, rainbow mood - // MODE 9-14, rainbow swirl - // MODE 15-20, snake - // MODE 21-23, knight - - #if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER) - rgblight_timer_enable(); - #endif - } + if (rgblight_config.mode == 1) { + #if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER) + rgblight_timer_disable(); + #endif + } else if (rgblight_config.mode >= 2 && rgblight_config.mode <= 23) { + // MODE 2-5, breathing + // MODE 6-8, rainbow mood + // MODE 9-14, rainbow swirl + // MODE 15-20, snake + // MODE 21-23, knight + + #if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER) + rgblight_timer_enable(); + #endif + } rgblight_sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val); } @@ -215,127 +225,125 @@ void rgblight_toggle(void) { rgblight_config.enable ^= 1; eeconfig_update_rgblight(rgblight_config.raw); xprintf("rgblight toggle: rgblight_config.enable = %u\n", rgblight_config.enable); - if (rgblight_config.enable) { - rgblight_mode(rgblight_config.mode); - } else { - - #if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER) - rgblight_timer_disable(); - #endif - _delay_ms(50); - rgblight_set(); - } + if (rgblight_config.enable) { + rgblight_mode(rgblight_config.mode); + } else { + #if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER) + rgblight_timer_disable(); + #endif + _delay_ms(50); + rgblight_set(); + } } -void rgblight_increase_hue(void){ - uint16_t hue; +void rgblight_increase_hue(void) { + uint16_t hue; hue = (rgblight_config.hue+RGBLIGHT_HUE_STEP) % 360; rgblight_sethsv(hue, rgblight_config.sat, rgblight_config.val); } -void rgblight_decrease_hue(void){ - uint16_t hue; - if (rgblight_config.hue-RGBLIGHT_HUE_STEP <0 ) { - hue = (rgblight_config.hue+360-RGBLIGHT_HUE_STEP) % 360; - } else { - hue = (rgblight_config.hue-RGBLIGHT_HUE_STEP) % 360; - } +void rgblight_decrease_hue(void) { + uint16_t hue; + if (rgblight_config.hue-RGBLIGHT_HUE_STEP < 0) { + hue = (rgblight_config.hue + 360 - RGBLIGHT_HUE_STEP) % 360; + } else { + hue = (rgblight_config.hue - RGBLIGHT_HUE_STEP) % 360; + } rgblight_sethsv(hue, rgblight_config.sat, rgblight_config.val); } void rgblight_increase_sat(void) { - uint8_t sat; + uint8_t sat; if (rgblight_config.sat + RGBLIGHT_SAT_STEP > 255) { sat = 255; } else { - sat = rgblight_config.sat+RGBLIGHT_SAT_STEP; + sat = rgblight_config.sat + RGBLIGHT_SAT_STEP; } rgblight_sethsv(rgblight_config.hue, sat, rgblight_config.val); } -void rgblight_decrease_sat(void){ - uint8_t sat; +void rgblight_decrease_sat(void) { + uint8_t sat; if (rgblight_config.sat - RGBLIGHT_SAT_STEP < 0) { sat = 0; } else { - sat = rgblight_config.sat-RGBLIGHT_SAT_STEP; + sat = rgblight_config.sat - RGBLIGHT_SAT_STEP; } rgblight_sethsv(rgblight_config.hue, sat, rgblight_config.val); } -void rgblight_increase_val(void){ - uint8_t val; +void rgblight_increase_val(void) { + uint8_t val; if (rgblight_config.val + RGBLIGHT_VAL_STEP > 255) { val = 255; } else { - val = rgblight_config.val+RGBLIGHT_VAL_STEP; + val = rgblight_config.val + RGBLIGHT_VAL_STEP; } rgblight_sethsv(rgblight_config.hue, rgblight_config.sat, val); } void rgblight_decrease_val(void) { - uint8_t val; + uint8_t val; if (rgblight_config.val - RGBLIGHT_VAL_STEP < 0) { val = 0; } else { - val = rgblight_config.val-RGBLIGHT_VAL_STEP; + val = rgblight_config.val - RGBLIGHT_VAL_STEP; } rgblight_sethsv(rgblight_config.hue, rgblight_config.sat, val); } -void rgblight_sethsv_noeeprom(uint16_t hue, uint8_t sat, uint8_t val){ - inmem_config.raw = rgblight_config.raw; +void rgblight_sethsv_noeeprom(uint16_t hue, uint8_t sat, uint8_t val) { + inmem_config.raw = rgblight_config.raw; if (rgblight_config.enable) { struct cRGB tmp_led; sethsv(hue, sat, val, &tmp_led); - inmem_config.hue = hue; - inmem_config.sat = sat; - inmem_config.val = val; + inmem_config.hue = hue; + inmem_config.sat = sat; + inmem_config.val = val; // dprintf("rgblight set hue [MEMORY]: %u,%u,%u\n", inmem_config.hue, inmem_config.sat, inmem_config.val); rgblight_setrgb(tmp_led.r, tmp_led.g, tmp_led.b); } } -void rgblight_sethsv(uint16_t hue, uint8_t sat, uint8_t val){ +void rgblight_sethsv(uint16_t hue, uint8_t sat, uint8_t val) { if (rgblight_config.enable) { - if (rgblight_config.mode == 1) { - // same static color - rgblight_sethsv_noeeprom(hue, sat, val); - } else { - // all LEDs in same color - if (rgblight_config.mode >= 2 && rgblight_config.mode <= 5) { - // breathing mode, ignore the change of val, use in memory value instead - val = rgblight_config.val; - } else if (rgblight_config.mode >= 6 && rgblight_config.mode <= 14) { - // rainbow mood and rainbow swirl, ignore the change of hue - hue = rgblight_config.hue; - } - } - rgblight_config.hue = hue; - rgblight_config.sat = sat; - rgblight_config.val = val; - eeconfig_update_rgblight(rgblight_config.raw); - xprintf("rgblight set hsv [EEPROM]: %u,%u,%u\n", rgblight_config.hue, rgblight_config.sat, rgblight_config.val); - } -} - -void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b){ + if (rgblight_config.mode == 1) { + // same static color + rgblight_sethsv_noeeprom(hue, sat, val); + } else { + // all LEDs in same color + if (rgblight_config.mode >= 2 && rgblight_config.mode <= 5) { + // breathing mode, ignore the change of val, use in memory value instead + val = rgblight_config.val; + } else if (rgblight_config.mode >= 6 && rgblight_config.mode <= 14) { + // rainbow mood and rainbow swirl, ignore the change of hue + hue = rgblight_config.hue; + } + } + rgblight_config.hue = hue; + rgblight_config.sat = sat; + rgblight_config.val = val; + eeconfig_update_rgblight(rgblight_config.raw); + xprintf("rgblight set hsv [EEPROM]: %u,%u,%u\n", rgblight_config.hue, rgblight_config.sat, rgblight_config.val); + } +} + +void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b) { // dprintf("rgblight set rgb: %u,%u,%u\n", r,g,b); - for (uint8_t i=0;i>8)&0xff; - OCR3AL = RGBLED_TIMER_TOP&0xff; - SREG = sreg; + static uint8_t rgblight_timer_is_init = 0; + if (rgblight_timer_is_init) { + return; + } + rgblight_timer_is_init = 1; + /* Timer 3 setup */ + TCCR3B = _BV(WGM32) //CTC mode OCR3A as TOP + | _BV(CS30); //Clock selelct: clk/1 + /* Set TOP value */ + uint8_t sreg = SREG; + cli(); + OCR3AH = (RGBLED_TIMER_TOP >> 8) & 0xff; + OCR3AL = RGBLED_TIMER_TOP & 0xff; + SREG = sreg; } void rgblight_timer_enable(void) { - TIMSK3 |= _BV(OCIE3A); - dprintf("TIMER3 enabled.\n"); + TIMSK3 |= _BV(OCIE3A); + dprintf("TIMER3 enabled.\n"); } void rgblight_timer_disable(void) { - TIMSK3 &= ~_BV(OCIE3A); - dprintf("TIMER3 disabled.\n"); + TIMSK3 &= ~_BV(OCIE3A); + dprintf("TIMER3 disabled.\n"); } void rgblight_timer_toggle(void) { - TIMSK3 ^= _BV(OCIE3A); - dprintf("TIMER3 toggled.\n"); + TIMSK3 ^= _BV(OCIE3A); + dprintf("TIMER3 toggled.\n"); } ISR(TIMER3_COMPA_vect) { - // Mode = 1, static light, do nothing here - if (rgblight_config.mode>=2 && rgblight_config.mode<=5) { - // mode = 2 to 5, breathing mode - rgblight_effect_breathing(rgblight_config.mode-2); - - } else if (rgblight_config.mode>=6 && rgblight_config.mode<=8) { - rgblight_effect_rainbow_mood(rgblight_config.mode-6); - } else if (rgblight_config.mode>=9 && rgblight_config.mode<=14) { - rgblight_effect_rainbow_swirl(rgblight_config.mode-9); - } else if (rgblight_config.mode>=15 && rgblight_config.mode<=20) { - rgblight_effect_snake(rgblight_config.mode-15); - } else if (rgblight_config.mode>=21 && rgblight_config.mode<=23) { - rgblight_effect_knight(rgblight_config.mode-21); - } -} - -// effects + // mode = 1, static light, do nothing here + if (rgblight_config.mode >= 2 && rgblight_config.mode <= 5) { + // mode = 2 to 5, breathing mode + rgblight_effect_breathing(rgblight_config.mode - 2); + } else if (rgblight_config.mode >= 6 && rgblight_config.mode <= 8) { + // mode = 6 to 8, rainbow mood mod + rgblight_effect_rainbow_mood(rgblight_config.mode - 6); + } else if (rgblight_config.mode >= 9 && rgblight_config.mode <= 14) { + // mode = 9 to 14, rainbow swirl mode + rgblight_effect_rainbow_swirl(rgblight_config.mode - 9); + } else if (rgblight_config.mode >= 15 && rgblight_config.mode <= 20) { + // mode = 15 to 20, snake mode + rgblight_effect_snake(rgblight_config.mode - 15); + } else if (rgblight_config.mode >= 21 && rgblight_config.mode <= 23) { + // mode = 21 to 23, knight mode + rgblight_effect_knight(rgblight_config.mode - 21); + } +} + +// Effects void rgblight_effect_breathing(uint8_t interval) { - static uint8_t pos = 0; - static uint16_t last_timer = 0; + static uint8_t pos = 0; + static uint16_t last_timer = 0; - if (timer_elapsed(last_timer)=RGBLED_NUM) k=RGBLED_NUM-1; - if (i==k) { - sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, &preled[i]); - } - } - } - if (RGBLIGHT_EFFECT_KNIGHT_OFFSET) { - for (i=0;iRGBLED_NUM+RGBLIGHT_EFFECT_KNIGHT_LENGTH) { - pos = RGBLED_NUM+RGBLIGHT_EFFECT_KNIGHT_LENGTH-1; - increament = 1; - } else { - pos += 1; - } - } - -} - -#endif \ No newline at end of file + static int8_t pos = 0; + static uint16_t last_timer = 0; + uint8_t i, j, cur; + int8_t k; + struct cRGB preled[RGBLED_NUM]; + static int8_t increament = -1; + if (timer_elapsed(last_timer) < pgm_read_byte(&RGBLED_KNIGHT_INTERVALS[interval])) { + return; + } + last_timer = timer_read(); + for (i = 0; i < RGBLED_NUM; i++) { + preled[i].r = 0; + preled[i].g = 0; + preled[i].b = 0; + for (j = 0; j < RGBLIGHT_EFFECT_KNIGHT_LENGTH; j++) { + k = pos + j * increament; + if (k < 0) { + k = 0; + } + if (k >= RGBLED_NUM) { + k = RGBLED_NUM - 1; + } + if (i == k) { + sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, &preled[i]); + } + } + } + if (RGBLIGHT_EFFECT_KNIGHT_OFFSET) { + for (i = 0; i < RGBLED_NUM; i++) { + cur = (i + RGBLIGHT_EFFECT_KNIGHT_OFFSET) % RGBLED_NUM; + led[i].r = preled[cur].r; + led[i].g = preled[cur].g; + led[i].b = preled[cur].b; + } + } + rgblight_set(); + if (increament == 1) { + if (pos - 1 < 0 - RGBLIGHT_EFFECT_KNIGHT_LENGTH) { + pos = 0 - RGBLIGHT_EFFECT_KNIGHT_LENGTH; + increament = -1; + } else { + pos -= 1; + } + } else { + if (pos + 1 > RGBLED_NUM + RGBLIGHT_EFFECT_KNIGHT_LENGTH) { + pos = RGBLED_NUM + RGBLIGHT_EFFECT_KNIGHT_LENGTH - 1; + increament = 1; + } else { + pos += 1; + } + } +} + +#endif -- cgit v1.2.3-24-g4f1b From 899c88cd8bf024792760fcf3ee8be6fed13fb315 Mon Sep 17 00:00:00 2001 From: Jordi Orlando <0xdec@users.noreply.github.com> Date: Tue, 26 Jul 2016 14:46:30 -0500 Subject: Increament -> increment --- quantum/rgblight.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'quantum') diff --git a/quantum/rgblight.c b/quantum/rgblight.c index 1b3c576d1..c2841b851 100644 --- a/quantum/rgblight.c +++ b/quantum/rgblight.c @@ -453,9 +453,9 @@ void rgblight_effect_snake(uint8_t interval) { static uint16_t last_timer = 0; uint8_t i, j; int8_t k; - int8_t increament = 1; + int8_t increment = 1; if (interval % 2) { - increament = -1; + increment = -1; } if (timer_elapsed(last_timer) < pgm_read_byte(&RGBLED_SNAKE_INTERVALS[interval / 2])) { return; @@ -466,7 +466,7 @@ void rgblight_effect_snake(uint8_t interval) { led[i].g = 0; led[i].b = 0; for (j = 0; j < RGBLIGHT_EFFECT_SNAKE_LENGTH; j++) { - k = pos + j * increament; + k = pos + j * increment; if (k < 0) { k = k + RGBLED_NUM; } @@ -476,7 +476,7 @@ void rgblight_effect_snake(uint8_t interval) { } } rgblight_set(); - if (increament == 1) { + if (increment == 1) { if (pos - 1 < 0) { pos = RGBLED_NUM - 1; } else { @@ -492,7 +492,7 @@ void rgblight_effect_knight(uint8_t interval) { uint8_t i, j, cur; int8_t k; struct cRGB preled[RGBLED_NUM]; - static int8_t increament = -1; + static int8_t increment = -1; if (timer_elapsed(last_timer) < pgm_read_byte(&RGBLED_KNIGHT_INTERVALS[interval])) { return; } @@ -502,7 +502,7 @@ void rgblight_effect_knight(uint8_t interval) { preled[i].g = 0; preled[i].b = 0; for (j = 0; j < RGBLIGHT_EFFECT_KNIGHT_LENGTH; j++) { - k = pos + j * increament; + k = pos + j * increment; if (k < 0) { k = 0; } @@ -523,17 +523,17 @@ void rgblight_effect_knight(uint8_t interval) { } } rgblight_set(); - if (increament == 1) { + if (increment == 1) { if (pos - 1 < 0 - RGBLIGHT_EFFECT_KNIGHT_LENGTH) { pos = 0 - RGBLIGHT_EFFECT_KNIGHT_LENGTH; - increament = -1; + increment = -1; } else { pos -= 1; } } else { if (pos + 1 > RGBLED_NUM + RGBLIGHT_EFFECT_KNIGHT_LENGTH) { pos = RGBLED_NUM + RGBLIGHT_EFFECT_KNIGHT_LENGTH - 1; - increament = 1; + increment = 1; } else { pos += 1; } -- cgit v1.2.3-24-g4f1b From ea2d2f5d5841791745c93ef27cd1528a7fd69c97 Mon Sep 17 00:00:00 2001 From: Jordi Orlando <0xdec@users.noreply.github.com> Date: Tue, 26 Jul 2016 15:31:22 -0500 Subject: Simplify HSV->RGB calculation De-dupe repeated code --- quantum/rgblight.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) (limited to 'quantum') diff --git a/quantum/rgblight.c b/quantum/rgblight.c index c2841b851..f82e3ec55 100644 --- a/quantum/rgblight.c +++ b/quantum/rgblight.c @@ -55,57 +55,56 @@ uint8_t rgblight_inited = 0; void sethsv(uint16_t hue, uint8_t sat, uint8_t val, struct cRGB *led1) { - /* Convert hue, saturation and brightness ( HSB/HSV ) to RGB. The DIM_CURVE is - used only on brightness/value and on saturation (inverted). This looks the - most natural. */ - uint8_t r = 0, g = 0, b = 0; + // Convert hue, saturation, and value (HSV/HSB) to RGB. DIM_CURVE is used only + // on value and saturation (inverted). This looks the most natural. + uint8_t r = 0, g = 0, b = 0, base, color; val = pgm_read_byte(&DIM_CURVE[val]); sat = 255 - pgm_read_byte(&DIM_CURVE[255 - sat]); - uint8_t base; - if (sat == 0) { // Acromatic color (gray). Hue doesn't mind. r = val; g = val; b = val; } else { base = ((255 - sat) * val) >> 8; + color = (val - base) * (hue % 60) / 60; switch (hue / 60) { case 0: r = val; - g = (((val - base) * hue) / 60) + base; + g = base + color; b = base; break; case 1: - r = (((val - base) * (60 - (hue % 60))) / 60) + base; + r = val - color; g = val; b = base; break; case 2: r = base; g = val; - b = (((val - base) * (hue % 60)) / 60) + base; + b = base + color; break; case 3: r = base; - g = (((val - base) * (60 - (hue % 60))) / 60) + base; + g = val - color; b = val; break; case 4: - r = (((val - base) * (hue % 60)) / 60) + base; + r = base + color; g = base; b = val; break; case 5: r = val; g = base; - b = (((val - base) * (60 - (hue % 60))) / 60) + base; + b = val - color; break; } } - setrgb(r,g,b, led1); + + setrgb(r, g, b, led1); } void setrgb(uint8_t r, uint8_t g, uint8_t b, struct cRGB *led1) { @@ -346,7 +345,6 @@ void rgblight_set(void) { } } - #if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER) // Animation timer -- AVR Timer3 -- cgit v1.2.3-24-g4f1b From b21e8b97acb722bfa7b85831cfd010716ed77962 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 27 Jul 2016 08:42:09 +0200 Subject: tap-dance: Add some debugging support Signed-off-by: Gergely Nagy --- quantum/process_keycode/process_tap_dance.c | 15 +++++++++++++++ quantum/process_keycode/process_tap_dance.h | 1 + 2 files changed, 16 insertions(+) (limited to 'quantum') diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c index d240dc2e6..5429e3438 100644 --- a/quantum/process_keycode/process_tap_dance.c +++ b/quantum/process_keycode/process_tap_dance.c @@ -1,6 +1,18 @@ #include "quantum.h" static qk_tap_dance_state_t qk_tap_dance_state; +bool td_debug_enable = false; + +#if CONSOLE_ENABLE +#define td_debug(s) if (td_debug_enable) \ + { \ + xprintf ("D:tap_dance:%s:%s = { keycode = %d, count = %d, active = %d, pressed = %d }\n", __FUNCTION__, s, \ + qk_tap_dance_state.keycode, qk_tap_dance_state.count, \ + qk_tap_dance_state.active, qk_tap_dance_state.pressed); \ + } +#else +#define td_debug(s) +#endif void qk_tap_dance_pair_finished (qk_tap_dance_state_t *state, void *user_data) { qk_tap_dance_pair_t *pair = (qk_tap_dance_pair_t *)user_data; @@ -33,16 +45,19 @@ static inline void _process_tap_dance_action_fn (qk_tap_dance_state_t *state, static inline void process_tap_dance_action_on_each_tap (qk_tap_dance_action_t action) { + td_debug("trigger"); _process_tap_dance_action_fn (&qk_tap_dance_state, action.user_data, action.fn.on_each_tap); } static inline void process_tap_dance_action_on_dance_finished (qk_tap_dance_action_t action) { + td_debug("trigger"); _process_tap_dance_action_fn (&qk_tap_dance_state, action.user_data, action.fn.on_dance_finished); } static inline void process_tap_dance_action_on_reset (qk_tap_dance_action_t action) { + td_debug("trigger") _process_tap_dance_action_fn (&qk_tap_dance_state, action.user_data, action.fn.on_reset); } diff --git a/quantum/process_keycode/process_tap_dance.h b/quantum/process_keycode/process_tap_dance.h index e2c74efe9..6a1258067 100644 --- a/quantum/process_keycode/process_tap_dance.h +++ b/quantum/process_keycode/process_tap_dance.h @@ -49,6 +49,7 @@ typedef struct } extern const qk_tap_dance_action_t tap_dance_actions[]; +extern bool td_debug_enable; /* To be used internally */ -- cgit v1.2.3-24-g4f1b From e01b4c3fd9a7b66276ffd22dcac25d569d7bb7ff Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Sat, 9 Jul 2016 00:41:15 +0300 Subject: Most ergodox keymaps compiles on Infinity There are linker errors due to missing led funcitonality though --- quantum/quantum.h | 1 + 1 file changed, 1 insertion(+) (limited to 'quantum') diff --git a/quantum/quantum.h b/quantum/quantum.h index 7ebfb24e3..6e3fbcc79 100644 --- a/quantum/quantum.h +++ b/quantum/quantum.h @@ -25,6 +25,7 @@ #include "led.h" #include "action_util.h" #include +#include "print.h" extern uint32_t default_layer_state; -- cgit v1.2.3-24-g4f1b From 7d0345ef25b5e1924f1e98c76d78607778e0b17d Mon Sep 17 00:00:00 2001 From: JeeBak Kim Date: Sat, 30 Jul 2016 01:52:33 -0700 Subject: Add IN_LIKE_FLINT song --- quantum/audio/song_list.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'quantum') diff --git a/quantum/audio/song_list.h b/quantum/audio/song_list.h index fc6fcdeef..8022ca672 100644 --- a/quantum/audio/song_list.h +++ b/quantum/audio/song_list.h @@ -28,6 +28,14 @@ Q__NOTE(_E4), Q__NOTE(_C4), \ Q__NOTE(_E4), +/* Requires: PLAY_NOTE_ARRAY(..., ..., STACCATO); */ +#define IN_LIKE_FLINT \ + E__NOTE(_AS4), E__NOTE(_AS4), QD_NOTE(_B4), \ + E__NOTE(_AS4), E__NOTE(_B4), QD_NOTE(_CS4), \ + E__NOTE(_B4), E__NOTE(_CS4), QD_NOTE(_DS4), \ + E__NOTE(_CS4), E__NOTE(_B4), QD_NOTE(_AS4), \ + E__NOTE(_AS4), E__NOTE(_AS4), QD_NOTE(_B4), + #define GOODBYE_SOUND \ E__NOTE(_E7), \ E__NOTE(_A6), \ -- cgit v1.2.3-24-g4f1b From c70b276b1b29e31945a5a03f560961d8a008176d Mon Sep 17 00:00:00 2001 From: kuel Date: Tue, 2 Aug 2016 14:09:01 -0500 Subject: Add keymap_cyrillic.h, lots of cyrillic characters --- quantum/keymap_extras/keymap_cyrillic.h | 161 ++++++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 quantum/keymap_extras/keymap_cyrillic.h (limited to 'quantum') diff --git a/quantum/keymap_extras/keymap_cyrillic.h b/quantum/keymap_extras/keymap_cyrillic.h new file mode 100644 index 000000000..d5390afff --- /dev/null +++ b/quantum/keymap_extras/keymap_cyrillic.h @@ -0,0 +1,161 @@ +#ifndef KEYMAP_CYRILLIC_H +#define KEYMAP_CYRILLIC_H + +#include "keymap.h" + +/* + * This is based off of + * https://en.wikipedia.org/wiki/Cyrillic_script + */ + +// Capital Char russian/ukrainian/bulgarian +#define CY_A UC(0x0410) // А rus ukr bul +#define CY_BE UC(0x0411) // Б rus ukr bul +#define CY_VE UC(0x0412) // В rus ukr bul +#define CY_GHE UC(0x0413) // Г rus ukr bul +#define CY_GHEUP UC(0x0490) // Ґ ukr +#define CY_DE UC(0x0414) // Д rus ukr bul +#define CY_DJE UC(0x0402) // Ђ +#define CY_GJE UC(0x0403) // Ѓ +#define CY_IE UC(0x0415) // Е rus ukr bul +#define CY_IO UC(0x0401) // Ё rus +#define CY_UIE UC(0x0404) // Є ukr +#define CY_ZHE UC(0x0416) // Ж rus ukr bul +#define CY_ZE UC(0x0417) // З rus ukr bul +#define CY_DZE UC(0x0405) // Ѕ +#define CY_I UC(0x0418) // И rus ukr bul +#define CY_B_U_I UC(0x0406) // І ukr +#define CY_YI UC(0x0407) // Ї ukr +#define CY_SRT_I UC(0x0419) // Й rus ukr bul +#define CY_JE UC(0x0408) // Ј +#define CY_KA UC(0x041a) // К rus ukr bul +#define CY_EL UC(0x041b) // Л rus ukr bul +#define CY_LJE UC(0x0409) // Љ +#define CY_EM UC(0x041c) // М rus ukr bul +#define CY_EN UC(0x041d) // Н rus ukr bul +#define CY_NJE UC(0x040a) // Њ +#define CY_O UC(0x041e) // О rus ukr bul +#define CY_PE UC(0x041f) // П rus ukr bul +#define CY_ER UC(0x0420) // Р rus ukr bul +#define CY_ES UC(0x0421) // С rus ukr bul +#define CY_TE UC(0x0422) // Т rus ukr bul +#define CY_TSHE UC(0x040b) // Ћ +#define CY_KJE UC(0x040c) // Ќ +#define CY_U UC(0x0423) // У rus ukr bul +#define CY_SRT_U UC(0x040e) // Ў +#define CY_EF UC(0x0424) // Ф rus ukr bul +#define CY_HA UC(0x0425) // Х rus bul +#define CY_TSE UC(0x0426) // Ц rus ukr bul +#define CY_CHE UC(0x0427) // Ч rus ukr bul +#define CY_DZHE UC(0x040f) // Џ +#define CY_SHA UC(0x0428) // Ш rus ukr bul +#define CY_SHCHA UC(0x0429) // Щ rus ukr bul +#define CY_HSIGN UC(0x042a) // Ъ rus bul +#define CY_YERU UC(0x042b) // Ы rus +#define CY_SSIGN UC(0x042c) // Ь rus ukr bul +#define CY_E UC(0x042d) // Э rus +#define CY_YU UC(0x042e) // Ю rus ukr bul +#define CY_YA UC(0x042f) // Я rus ukr bul +// Important Cyrillic non-Slavic letters +#define CY_PALOCHKA UC(0x04c0) // Ӏ +#define CY_SCHWA UC(0x04d8) // Ә +#define CY_GHE_S UC(0x0492) // Ғ +#define CY_ZE_D UC(0x0498) // Ҙ +#define CY_ES_D UC(0x04aa) // Ҫ +#define CY_BR_KA UC(0x04a0) // Ҡ +#define CY_ZHE_D UC(0x0496) // Җ +#define CY_KA_D UC(0x049a) // Қ +#define CY_EN_D UC(0x04a2) // Ң +#define CY_ENGHE UC(0x04a4) // Ҥ +#define CY_BRD_O UC(0x04e8) // Ө +#define CY_STR_U UC(0x04ae) // Ү +#define CY_S_U_S UC(0x04b0) // Ұ +#define CY_SHHA UC(0x04ba) // Һ +#define CY_HA_D UC(0x04b2) // Ҳ + + +// Small +#define CY_a UC(0x0430) // a rus ukr bul +#define CY_be UC(0x0431) // б rus ukr bul +#define CY_ve UC(0x0432) // в rus ukr bul +#define CY_ghe UC(0x0433) // г rus ukr bul +#define CY_gheup UC(0x0491) // ґ ukr +#define CY_de UC(0x0434) // д rus ukr bul +#define CY_dje UC(0x0452) // ђ +#define CY_gje UC(0x0453) // ѓ +#define CY_ie UC(0x0435) // е rus ukr bul +#define CY_io UC(0x0451) // ё rus +#define CY_uie UC(0x0454) // є ukr +#define CY_zhe UC(0x0436) // ж rus ukr bul +#define CY_ze UC(0x0437) // з rus ukr bul +#define CY_dze UC(0x0455) // ѕ +#define CY_i UC(0x0438) // и rus ukr bul +#define CY_b_u_i UC(0x0456) // і ukr +#define CY_yi UC(0x0457) // ї ukr +#define CY_srt_i UC(0x0439) // й rus ukr bul +#define CY_je UC(0x0458) // ј +#define CY_ka UC(0x043a) // к rus ukr bul +#define CY_el UC(0x043b) // л rus ukr bul +#define CY_lje UC(0x0459) // љ +#define CY_em UC(0x043c) // м rus ukr bul +#define CY_en UC(0x043d) // н rus ukr bul +#define CY_nje UC(0x045a) // њ +#define CY_o UC(0x043e) // о rus ukr bul +#define CY_pe UC(0x043f) // п rus ukr bul +#define CY_er UC(0x0440) // р rus ukr bul +#define CY_es UC(0x0441) // с rus ukr bul +#define CY_te UC(0x0442) // т rus ukr bul +#define CY_tshe UC(0x045b) // ћ +#define CY_kje UC(0x045c) // ќ +#define CY_u UC(0x0443) // у rus ukr bul +#define CY_srt_u UC(0x045e) // ў +#define CY_ef UC(0x0444) // ф rus ukr bul +#define CY_ha UC(0x0445) // х rus ukr bul +#define CY_tse UC(0x0446) // ц rus ukr bul +#define CY_che UC(0x0447) // ч rus ukr bul +#define CY_dzhe UC(0x045f) // џ +#define CY_sha UC(0x0448) // ш rus ukr bul +#define CY_shcha UC(0x0449) // щ rus ukr bul +#define CY_hsign UC(0x044a) // ъ rus bul +#define CY_yeru UC(0x044b) // ы rus +#define CY_ssign UC(0x044c) // ь rus ukr bul +#define CY_e UC(0x044d) // э rus +#define CY_yu UC(0x044e) // ю rus ukr bul +#define CY_ya UC(0x044f) // я rus ukr bul +// Important Cyrillic non-Slavic letters +#define CY_palochka UC(0x04cf) // ӏ +#define CY_schwa UC(0x04d9) // ә +#define CY_ghe_s UC(0x0493) // ғ +#define CY_ze_d UC(0x0499) // ҙ +#define CY_es_d UC(0x04ab) // ҫ +#define CY_br_ka UC(0x04a1) // ҡ +#define CY_zhe_d UC(0x0497) // җ +#define CY_ka_d UC(0x049b) // қ +#define CY_en_d UC(0x04a3) // ң +#define CY_enghe UC(0x04a5) // ҥ +#define CY_brd_o UC(0x04e9) // ө +#define CY_str_u UC(0x04af) // ү +#define CY_s_u_s UC(0x04b1) // ұ +#define CY_shha UC(0x04bb) // һ +#define CY_ha_d UC(0x04b3) // ҳ + + +// Extra +#define CY_slr_ve UC(0x1c80) // ᲀ CYRILLIC SMALL LETTER ROUNDED VE +#define CY_ll_de UC(0x1c81) // ᲁ CYRILLIC SMALL LETTER LONG-LEGGED DE +#define CY_ZEMLYA UC(0xa640) // Ꙁ CYRILLIC CAPITAL LETTER ZEMLYA +#define CY_zemlya UC(0xa641) // ꙁ CYRILLIC SMALL LETTER ZEMLYA +#define CY_RV_DZE UC(0xa644) // Ꙅ CYRILLIC CAPITAL LETTER REVERSED DZE +#define CY_rv_DZE UC(0xa645) // ꙅ CYRILLIC SMALL LETTER REVERSED DZE +#define CY_slw_es UC(0x1c83) // ᲃ CYRILLIC SMALL LETTER WIDE ES +#define CY_st_te UC(0x1c84) // ᲄ CYRILLIC SMALL LETTER TALL TE +#define CY_3l_te UC(0x1c85) // ᲅ CYRILLIC SMALL LETTER THREE-LEGGED TE +#define CY_thsign UC(0x1c86) // ᲆ CYRILLIC SMALL LETTER TALL HARD SIGN +#define CY_YERUBY UC(0xa650) // Ꙑ CYRILLIC CAPITAL LETTER YERU WITH BACK YER +#define CY_yeruby UC(0xa651) // ꙑ CYRILLIC SMALL LETTER YERU WITH BACK YER +#define CY_RUBLE UC(0x20bd) // ₽ +#define CY_NUMERO UC(0x2116) // № + +// The letters Zje and Sje are made for other letters and accent marks + +#endif -- cgit v1.2.3-24-g4f1b From c5ee24a6c3ea39e9725dfc276c92d5bce726ca78 Mon Sep 17 00:00:00 2001 From: kuel Date: Sun, 7 Aug 2016 11:01:12 -0500 Subject: Add keymap_russian.h, a software implementation of Russian rename keymap_cyrillic.h to keymap_unicode_cyrillic.h changed CY_RUBLE and CY_NUMERO to CY_RUBL and CY_NMRO in keymap_unicode_cyrillic.h --- quantum/keymap_extras/keymap_cyrillic.h | 161 ----------------------- quantum/keymap_extras/keymap_russian.h | 79 ++++++++++++ quantum/keymap_extras/keymap_unicode_cyrillic.h | 163 ++++++++++++++++++++++++ 3 files changed, 242 insertions(+), 161 deletions(-) delete mode 100644 quantum/keymap_extras/keymap_cyrillic.h create mode 100644 quantum/keymap_extras/keymap_russian.h create mode 100644 quantum/keymap_extras/keymap_unicode_cyrillic.h (limited to 'quantum') diff --git a/quantum/keymap_extras/keymap_cyrillic.h b/quantum/keymap_extras/keymap_cyrillic.h deleted file mode 100644 index d5390afff..000000000 --- a/quantum/keymap_extras/keymap_cyrillic.h +++ /dev/null @@ -1,161 +0,0 @@ -#ifndef KEYMAP_CYRILLIC_H -#define KEYMAP_CYRILLIC_H - -#include "keymap.h" - -/* - * This is based off of - * https://en.wikipedia.org/wiki/Cyrillic_script - */ - -// Capital Char russian/ukrainian/bulgarian -#define CY_A UC(0x0410) // А rus ukr bul -#define CY_BE UC(0x0411) // Б rus ukr bul -#define CY_VE UC(0x0412) // В rus ukr bul -#define CY_GHE UC(0x0413) // Г rus ukr bul -#define CY_GHEUP UC(0x0490) // Ґ ukr -#define CY_DE UC(0x0414) // Д rus ukr bul -#define CY_DJE UC(0x0402) // Ђ -#define CY_GJE UC(0x0403) // Ѓ -#define CY_IE UC(0x0415) // Е rus ukr bul -#define CY_IO UC(0x0401) // Ё rus -#define CY_UIE UC(0x0404) // Є ukr -#define CY_ZHE UC(0x0416) // Ж rus ukr bul -#define CY_ZE UC(0x0417) // З rus ukr bul -#define CY_DZE UC(0x0405) // Ѕ -#define CY_I UC(0x0418) // И rus ukr bul -#define CY_B_U_I UC(0x0406) // І ukr -#define CY_YI UC(0x0407) // Ї ukr -#define CY_SRT_I UC(0x0419) // Й rus ukr bul -#define CY_JE UC(0x0408) // Ј -#define CY_KA UC(0x041a) // К rus ukr bul -#define CY_EL UC(0x041b) // Л rus ukr bul -#define CY_LJE UC(0x0409) // Љ -#define CY_EM UC(0x041c) // М rus ukr bul -#define CY_EN UC(0x041d) // Н rus ukr bul -#define CY_NJE UC(0x040a) // Њ -#define CY_O UC(0x041e) // О rus ukr bul -#define CY_PE UC(0x041f) // П rus ukr bul -#define CY_ER UC(0x0420) // Р rus ukr bul -#define CY_ES UC(0x0421) // С rus ukr bul -#define CY_TE UC(0x0422) // Т rus ukr bul -#define CY_TSHE UC(0x040b) // Ћ -#define CY_KJE UC(0x040c) // Ќ -#define CY_U UC(0x0423) // У rus ukr bul -#define CY_SRT_U UC(0x040e) // Ў -#define CY_EF UC(0x0424) // Ф rus ukr bul -#define CY_HA UC(0x0425) // Х rus bul -#define CY_TSE UC(0x0426) // Ц rus ukr bul -#define CY_CHE UC(0x0427) // Ч rus ukr bul -#define CY_DZHE UC(0x040f) // Џ -#define CY_SHA UC(0x0428) // Ш rus ukr bul -#define CY_SHCHA UC(0x0429) // Щ rus ukr bul -#define CY_HSIGN UC(0x042a) // Ъ rus bul -#define CY_YERU UC(0x042b) // Ы rus -#define CY_SSIGN UC(0x042c) // Ь rus ukr bul -#define CY_E UC(0x042d) // Э rus -#define CY_YU UC(0x042e) // Ю rus ukr bul -#define CY_YA UC(0x042f) // Я rus ukr bul -// Important Cyrillic non-Slavic letters -#define CY_PALOCHKA UC(0x04c0) // Ӏ -#define CY_SCHWA UC(0x04d8) // Ә -#define CY_GHE_S UC(0x0492) // Ғ -#define CY_ZE_D UC(0x0498) // Ҙ -#define CY_ES_D UC(0x04aa) // Ҫ -#define CY_BR_KA UC(0x04a0) // Ҡ -#define CY_ZHE_D UC(0x0496) // Җ -#define CY_KA_D UC(0x049a) // Қ -#define CY_EN_D UC(0x04a2) // Ң -#define CY_ENGHE UC(0x04a4) // Ҥ -#define CY_BRD_O UC(0x04e8) // Ө -#define CY_STR_U UC(0x04ae) // Ү -#define CY_S_U_S UC(0x04b0) // Ұ -#define CY_SHHA UC(0x04ba) // Һ -#define CY_HA_D UC(0x04b2) // Ҳ - - -// Small -#define CY_a UC(0x0430) // a rus ukr bul -#define CY_be UC(0x0431) // б rus ukr bul -#define CY_ve UC(0x0432) // в rus ukr bul -#define CY_ghe UC(0x0433) // г rus ukr bul -#define CY_gheup UC(0x0491) // ґ ukr -#define CY_de UC(0x0434) // д rus ukr bul -#define CY_dje UC(0x0452) // ђ -#define CY_gje UC(0x0453) // ѓ -#define CY_ie UC(0x0435) // е rus ukr bul -#define CY_io UC(0x0451) // ё rus -#define CY_uie UC(0x0454) // є ukr -#define CY_zhe UC(0x0436) // ж rus ukr bul -#define CY_ze UC(0x0437) // з rus ukr bul -#define CY_dze UC(0x0455) // ѕ -#define CY_i UC(0x0438) // и rus ukr bul -#define CY_b_u_i UC(0x0456) // і ukr -#define CY_yi UC(0x0457) // ї ukr -#define CY_srt_i UC(0x0439) // й rus ukr bul -#define CY_je UC(0x0458) // ј -#define CY_ka UC(0x043a) // к rus ukr bul -#define CY_el UC(0x043b) // л rus ukr bul -#define CY_lje UC(0x0459) // љ -#define CY_em UC(0x043c) // м rus ukr bul -#define CY_en UC(0x043d) // н rus ukr bul -#define CY_nje UC(0x045a) // њ -#define CY_o UC(0x043e) // о rus ukr bul -#define CY_pe UC(0x043f) // п rus ukr bul -#define CY_er UC(0x0440) // р rus ukr bul -#define CY_es UC(0x0441) // с rus ukr bul -#define CY_te UC(0x0442) // т rus ukr bul -#define CY_tshe UC(0x045b) // ћ -#define CY_kje UC(0x045c) // ќ -#define CY_u UC(0x0443) // у rus ukr bul -#define CY_srt_u UC(0x045e) // ў -#define CY_ef UC(0x0444) // ф rus ukr bul -#define CY_ha UC(0x0445) // х rus ukr bul -#define CY_tse UC(0x0446) // ц rus ukr bul -#define CY_che UC(0x0447) // ч rus ukr bul -#define CY_dzhe UC(0x045f) // џ -#define CY_sha UC(0x0448) // ш rus ukr bul -#define CY_shcha UC(0x0449) // щ rus ukr bul -#define CY_hsign UC(0x044a) // ъ rus bul -#define CY_yeru UC(0x044b) // ы rus -#define CY_ssign UC(0x044c) // ь rus ukr bul -#define CY_e UC(0x044d) // э rus -#define CY_yu UC(0x044e) // ю rus ukr bul -#define CY_ya UC(0x044f) // я rus ukr bul -// Important Cyrillic non-Slavic letters -#define CY_palochka UC(0x04cf) // ӏ -#define CY_schwa UC(0x04d9) // ә -#define CY_ghe_s UC(0x0493) // ғ -#define CY_ze_d UC(0x0499) // ҙ -#define CY_es_d UC(0x04ab) // ҫ -#define CY_br_ka UC(0x04a1) // ҡ -#define CY_zhe_d UC(0x0497) // җ -#define CY_ka_d UC(0x049b) // қ -#define CY_en_d UC(0x04a3) // ң -#define CY_enghe UC(0x04a5) // ҥ -#define CY_brd_o UC(0x04e9) // ө -#define CY_str_u UC(0x04af) // ү -#define CY_s_u_s UC(0x04b1) // ұ -#define CY_shha UC(0x04bb) // һ -#define CY_ha_d UC(0x04b3) // ҳ - - -// Extra -#define CY_slr_ve UC(0x1c80) // ᲀ CYRILLIC SMALL LETTER ROUNDED VE -#define CY_ll_de UC(0x1c81) // ᲁ CYRILLIC SMALL LETTER LONG-LEGGED DE -#define CY_ZEMLYA UC(0xa640) // Ꙁ CYRILLIC CAPITAL LETTER ZEMLYA -#define CY_zemlya UC(0xa641) // ꙁ CYRILLIC SMALL LETTER ZEMLYA -#define CY_RV_DZE UC(0xa644) // Ꙅ CYRILLIC CAPITAL LETTER REVERSED DZE -#define CY_rv_DZE UC(0xa645) // ꙅ CYRILLIC SMALL LETTER REVERSED DZE -#define CY_slw_es UC(0x1c83) // ᲃ CYRILLIC SMALL LETTER WIDE ES -#define CY_st_te UC(0x1c84) // ᲄ CYRILLIC SMALL LETTER TALL TE -#define CY_3l_te UC(0x1c85) // ᲅ CYRILLIC SMALL LETTER THREE-LEGGED TE -#define CY_thsign UC(0x1c86) // ᲆ CYRILLIC SMALL LETTER TALL HARD SIGN -#define CY_YERUBY UC(0xa650) // Ꙑ CYRILLIC CAPITAL LETTER YERU WITH BACK YER -#define CY_yeruby UC(0xa651) // ꙑ CYRILLIC SMALL LETTER YERU WITH BACK YER -#define CY_RUBLE UC(0x20bd) // ₽ -#define CY_NUMERO UC(0x2116) // № - -// The letters Zje and Sje are made for other letters and accent marks - -#endif diff --git a/quantum/keymap_extras/keymap_russian.h b/quantum/keymap_extras/keymap_russian.h new file mode 100644 index 000000000..efb63a5cc --- /dev/null +++ b/quantum/keymap_extras/keymap_russian.h @@ -0,0 +1,79 @@ +#ifndef KEYMAP_RUSSIAN_H +#define KEYMAP_RUSSIAN_H + +#include "keymap.h" + +// rename ruble and numero in keymap_cyrillic.c + +// Normal Chracters // reg SHIFT +#define RU_A KC_F // а and А +#define RU_BE KC_COMM // б and Б +#define RU_VE KC_D // в and В +#define RU_GHE KC_U // г and Г +#define RU_DE KC_L // д and Д +#define RU_IE KC_T // е and Е +#define RU_IO KC_GRV // ё and Ё +#define RU_ZHE KC_SCLN // ж and Ж +#define RU_ZE KC_P // з and З +#define RU_I KC_B // и and И +#define RU_SRT_I KC_Q // й and Й +#define RU_KA KC_R // к and К +#define RU_EL KC_K // л and Л +#define RU_EM KC_V // м and М +#define RU_EN KC_Y // н and Н +#define RU_O KC_J // о and О +#define RU_PE KC_G // п and П +#define RU_ER KC_H // р and Р +#define RU_ES KC_C // с and С +#define RU_TE KC_N // т and Т +#define RU_U KC_E // у and У +#define RU_EF KC_A // ф and Ф +#define RU_HA KC_LBRC // х and Х +#define RU_TSE KC_W // ц and Ц +#define RU_CHE KC_X // ч and Ч +#define RU_SHA KC_I // ш and Ш +#define RU_SHCHA KC_O // щ and Щ +#define RU_HSIGN KC_RBRC // ъ and Ъ +#define RU_YERU KC_S // ы and Ы +#define RU_SSIGN KC_M // ь and Ь +#define RU_E KC_QUOT // э and Э +#define RU_YU KC_DOT // ю and Ю +#define RU_YA KC_Z // я and Я + +#define RU_1 KC_1 // 1 and ! +#define RU_2 KC_2 // 2 and " +#define RU_3 KC_3 // 3 and № +#define RU_4 KC_4 // 4 and ; +#define RU_5 KC_5 // 5 and % +#define RU_6 KC_6 // 6 and : +#define RU_7 KC_7 // 7 and ? +#define RU_8 KC_8 // 8 and * +#define RU_9 KC_9 // 9 and ( +#define RU_0 KC_0 // 0 and ) + +#define RU_MINS KC_MINS // - and _ +#define RU_EQL KC_EQL // = and + +#define RU_BSLS KC_BSLS // \ and / +#define RU_DOT KC_SLSH // . and , + +// Shifted Chracters +#define RU_EXLM LSFT(RU_1) // ! +#define RU_DQUT LSFT(RU_2) // " +#define RU_NMRO LSFT(RU_3) // № +#define RU_SCLN LSFT(RU_4) // ; +#define RU_PERC LSFT(RU_5) // % +#define RU_COLN LSFT(RU_6) // : +#define RU_QUES LSFT(RU_7) // ? +#define RU_ASTR LSFT(RU_8) // * +#define RU_LPRN LSFT(RU_9) // ( +#define RU_RPRN LSFT(RU_0) // ) + +#define RU_UNDR LSFT(RU_MINS) // _ +#define RU_PLUS LSFT(RU_EQL) // + +#define RU_SLSH LSFT(RU_BSLS) // / +#define RU_COMM LSFT(RU_DOT) // , + +// Alt Gr-ed characters +#define RU_RUBL RALT(RU_8) // ₽ + +#endif diff --git a/quantum/keymap_extras/keymap_unicode_cyrillic.h b/quantum/keymap_extras/keymap_unicode_cyrillic.h new file mode 100644 index 000000000..a40626d91 --- /dev/null +++ b/quantum/keymap_extras/keymap_unicode_cyrillic.h @@ -0,0 +1,163 @@ +#ifndef KEYMAP_CYRILLIC_H +#define KEYMAP_CYRILLIC_H + +#include "keymap.h" + +/* + * This is based off of + * https://en.wikipedia.org/wiki/Cyrillic_script + * + * Unicode is iffy, a software implementation is preferred + */ + +// Capital Char russian/ukrainian/bulgarian +#define CY_A UC(0x0410) // А rus ukr bul +#define CY_BE UC(0x0411) // Б rus ukr bul +#define CY_VE UC(0x0412) // В rus ukr bul +#define CY_GHE UC(0x0413) // Г rus ukr bul +#define CY_GHEUP UC(0x0490) // Ґ ukr +#define CY_DE UC(0x0414) // Д rus ukr bul +#define CY_DJE UC(0x0402) // Ђ +#define CY_GJE UC(0x0403) // Ѓ +#define CY_IE UC(0x0415) // Е rus ukr bul +#define CY_IO UC(0x0401) // Ё rus +#define CY_UIE UC(0x0404) // Є ukr +#define CY_ZHE UC(0x0416) // Ж rus ukr bul +#define CY_ZE UC(0x0417) // З rus ukr bul +#define CY_DZE UC(0x0405) // Ѕ +#define CY_I UC(0x0418) // И rus ukr bul +#define CY_B_U_I UC(0x0406) // І ukr +#define CY_YI UC(0x0407) // Ї ukr +#define CY_SRT_I UC(0x0419) // Й rus ukr bul +#define CY_JE UC(0x0408) // Ј +#define CY_KA UC(0x041a) // К rus ukr bul +#define CY_EL UC(0x041b) // Л rus ukr bul +#define CY_LJE UC(0x0409) // Љ +#define CY_EM UC(0x041c) // М rus ukr bul +#define CY_EN UC(0x041d) // Н rus ukr bul +#define CY_NJE UC(0x040a) // Њ +#define CY_O UC(0x041e) // О rus ukr bul +#define CY_PE UC(0x041f) // П rus ukr bul +#define CY_ER UC(0x0420) // Р rus ukr bul +#define CY_ES UC(0x0421) // С rus ukr bul +#define CY_TE UC(0x0422) // Т rus ukr bul +#define CY_TSHE UC(0x040b) // Ћ +#define CY_KJE UC(0x040c) // Ќ +#define CY_U UC(0x0423) // У rus ukr bul +#define CY_SRT_U UC(0x040e) // Ў +#define CY_EF UC(0x0424) // Ф rus ukr bul +#define CY_HA UC(0x0425) // Х rus bul +#define CY_TSE UC(0x0426) // Ц rus ukr bul +#define CY_CHE UC(0x0427) // Ч rus ukr bul +#define CY_DZHE UC(0x040f) // Џ +#define CY_SHA UC(0x0428) // Ш rus ukr bul +#define CY_SHCHA UC(0x0429) // Щ rus ukr bul +#define CY_HSIGN UC(0x042a) // Ъ rus bul +#define CY_YERU UC(0x042b) // Ы rus +#define CY_SSIGN UC(0x042c) // Ь rus ukr bul +#define CY_E UC(0x042d) // Э rus +#define CY_YU UC(0x042e) // Ю rus ukr bul +#define CY_YA UC(0x042f) // Я rus ukr bul +// Important Cyrillic non-Slavic letters +#define CY_PALOCHKA UC(0x04c0) // Ӏ +#define CY_SCHWA UC(0x04d8) // Ә +#define CY_GHE_S UC(0x0492) // Ғ +#define CY_ZE_D UC(0x0498) // Ҙ +#define CY_ES_D UC(0x04aa) // Ҫ +#define CY_BR_KA UC(0x04a0) // Ҡ +#define CY_ZHE_D UC(0x0496) // Җ +#define CY_KA_D UC(0x049a) // Қ +#define CY_EN_D UC(0x04a2) // Ң +#define CY_ENGHE UC(0x04a4) // Ҥ +#define CY_BRD_O UC(0x04e8) // Ө +#define CY_STR_U UC(0x04ae) // Ү +#define CY_S_U_S UC(0x04b0) // Ұ +#define CY_SHHA UC(0x04ba) // Һ +#define CY_HA_D UC(0x04b2) // Ҳ + + +// Small +#define CY_a UC(0x0430) // a rus ukr bul +#define CY_be UC(0x0431) // б rus ukr bul +#define CY_ve UC(0x0432) // в rus ukr bul +#define CY_ghe UC(0x0433) // г rus ukr bul +#define CY_gheup UC(0x0491) // ґ ukr +#define CY_de UC(0x0434) // д rus ukr bul +#define CY_dje UC(0x0452) // ђ +#define CY_gje UC(0x0453) // ѓ +#define CY_ie UC(0x0435) // е rus ukr bul +#define CY_io UC(0x0451) // ё rus +#define CY_uie UC(0x0454) // є ukr +#define CY_zhe UC(0x0436) // ж rus ukr bul +#define CY_ze UC(0x0437) // з rus ukr bul +#define CY_dze UC(0x0455) // ѕ +#define CY_i UC(0x0438) // и rus ukr bul +#define CY_b_u_i UC(0x0456) // і ukr +#define CY_yi UC(0x0457) // ї ukr +#define CY_srt_i UC(0x0439) // й rus ukr bul +#define CY_je UC(0x0458) // ј +#define CY_ka UC(0x043a) // к rus ukr bul +#define CY_el UC(0x043b) // л rus ukr bul +#define CY_lje UC(0x0459) // љ +#define CY_em UC(0x043c) // м rus ukr bul +#define CY_en UC(0x043d) // н rus ukr bul +#define CY_nje UC(0x045a) // њ +#define CY_o UC(0x043e) // о rus ukr bul +#define CY_pe UC(0x043f) // п rus ukr bul +#define CY_er UC(0x0440) // р rus ukr bul +#define CY_es UC(0x0441) // с rus ukr bul +#define CY_te UC(0x0442) // т rus ukr bul +#define CY_tshe UC(0x045b) // ћ +#define CY_kje UC(0x045c) // ќ +#define CY_u UC(0x0443) // у rus ukr bul +#define CY_srt_u UC(0x045e) // ў +#define CY_ef UC(0x0444) // ф rus ukr bul +#define CY_ha UC(0x0445) // х rus ukr bul +#define CY_tse UC(0x0446) // ц rus ukr bul +#define CY_che UC(0x0447) // ч rus ukr bul +#define CY_dzhe UC(0x045f) // џ +#define CY_sha UC(0x0448) // ш rus ukr bul +#define CY_shcha UC(0x0449) // щ rus ukr bul +#define CY_hsign UC(0x044a) // ъ rus bul +#define CY_yeru UC(0x044b) // ы rus +#define CY_ssign UC(0x044c) // ь rus ukr bul +#define CY_e UC(0x044d) // э rus +#define CY_yu UC(0x044e) // ю rus ukr bul +#define CY_ya UC(0x044f) // я rus ukr bul +// Important Cyrillic non-Slavic letters +#define CY_palochka UC(0x04cf) // ӏ +#define CY_schwa UC(0x04d9) // ә +#define CY_ghe_s UC(0x0493) // ғ +#define CY_ze_d UC(0x0499) // ҙ +#define CY_es_d UC(0x04ab) // ҫ +#define CY_br_ka UC(0x04a1) // ҡ +#define CY_zhe_d UC(0x0497) // җ +#define CY_ka_d UC(0x049b) // қ +#define CY_en_d UC(0x04a3) // ң +#define CY_enghe UC(0x04a5) // ҥ +#define CY_brd_o UC(0x04e9) // ө +#define CY_str_u UC(0x04af) // ү +#define CY_s_u_s UC(0x04b1) // ұ +#define CY_shha UC(0x04bb) // һ +#define CY_ha_d UC(0x04b3) // ҳ + + +// Extra +#define CY_slr_ve UC(0x1c80) // ᲀ CYRILLIC SMALL LETTER ROUNDED VE +#define CY_ll_de UC(0x1c81) // ᲁ CYRILLIC SMALL LETTER LONG-LEGGED DE +#define CY_ZEMLYA UC(0xa640) // Ꙁ CYRILLIC CAPITAL LETTER ZEMLYA +#define CY_zemlya UC(0xa641) // ꙁ CYRILLIC SMALL LETTER ZEMLYA +#define CY_RV_DZE UC(0xa644) // Ꙅ CYRILLIC CAPITAL LETTER REVERSED DZE +#define CY_rv_DZE UC(0xa645) // ꙅ CYRILLIC SMALL LETTER REVERSED DZE +#define CY_slw_es UC(0x1c83) // ᲃ CYRILLIC SMALL LETTER WIDE ES +#define CY_st_te UC(0x1c84) // ᲄ CYRILLIC SMALL LETTER TALL TE +#define CY_3l_te UC(0x1c85) // ᲅ CYRILLIC SMALL LETTER THREE-LEGGED TE +#define CY_thsign UC(0x1c86) // ᲆ CYRILLIC SMALL LETTER TALL HARD SIGN +#define CY_YERUBY UC(0xa650) // Ꙑ CYRILLIC CAPITAL LETTER YERU WITH BACK YER +#define CY_yeruby UC(0xa651) // ꙑ CYRILLIC SMALL LETTER YERU WITH BACK YER +#define CY_RUBL UC(0x20bd) // ₽ +#define CY_NMRO UC(0x2116) // № + +// The letters Zje and Sje are made for other letters and accent marks + +#endif -- cgit v1.2.3-24-g4f1b From 2a0121a78643b1dc774d82352f8c9e246010803e Mon Sep 17 00:00:00 2001 From: kuel Date: Sun, 7 Aug 2016 11:07:38 -0500 Subject: Removed unnecessary comment --- quantum/keymap_extras/keymap_russian.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'quantum') diff --git a/quantum/keymap_extras/keymap_russian.h b/quantum/keymap_extras/keymap_russian.h index efb63a5cc..237e9abde 100644 --- a/quantum/keymap_extras/keymap_russian.h +++ b/quantum/keymap_extras/keymap_russian.h @@ -3,8 +3,6 @@ #include "keymap.h" -// rename ruble and numero in keymap_cyrillic.c - // Normal Chracters // reg SHIFT #define RU_A KC_F // а and А #define RU_BE KC_COMM // б and Б -- cgit v1.2.3-24-g4f1b From e692ebf86a962e90c51302e7b17a953ea2858f79 Mon Sep 17 00:00:00 2001 From: shela Date: Fri, 12 Aug 2016 20:38:26 +0900 Subject: fix typo --- quantum/keymap.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'quantum') diff --git a/quantum/keymap.h b/quantum/keymap.h index a15865183..f2d94d75c 100644 --- a/quantum/keymap.h +++ b/quantum/keymap.h @@ -156,16 +156,16 @@ enum quantum_keycodes { BL_INC, BL_TOGG, BL_STEP, - - // RGB functionality - RGB_TOG, - RGB_MOD, - RGB_HUI, - RGB_HUD, - RGB_SAI, - RGB_SAD, - RGB_VAI, - RGB_VAD, + + // RGB functionality + RGB_TOG, + RGB_MOD, + RGB_HUI, + RGB_HUD, + RGB_SAI, + RGB_SAD, + RGB_VAI, + RGB_VAD, // Left shift, open paren KC_LSPO, @@ -309,7 +309,7 @@ enum quantum_keycodes { #define OSL(layer) (layer | QK_ONE_SHOT_LAYER) // One-shot mod -#define OSM(layer) (layer | QK_ONE_SHOT_MOD) +#define OSM(mod) (mod | QK_ONE_SHOT_MOD) // M-od, T-ap - 256 keycode max #define MT(mod, kc) (kc | QK_MOD_TAP | ((mod & 0xF) << 8)) -- cgit v1.2.3-24-g4f1b From 8bdf745909bc2581491acce11225f56a85bc8f24 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 13 Aug 2016 10:33:47 +0200 Subject: process_unicode: Fix set_unicode_input_mode() In the header, this was defined as `set_unicode_input_mode`, but the implementation had `set_unicode_mode` for a name. Changed the implementation to match the header. Signed-off-by: Gergely Nagy --- quantum/process_keycode/process_unicode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'quantum') diff --git a/quantum/process_keycode/process_unicode.c b/quantum/process_keycode/process_unicode.c index ad5d7f86b..3fcac15ce 100644 --- a/quantum/process_keycode/process_unicode.c +++ b/quantum/process_keycode/process_unicode.c @@ -13,7 +13,7 @@ uint16_t hex_to_keycode(uint8_t hex) } } -void set_unicode_mode(uint8_t os_target) +void set_unicode_input_mode(uint8_t os_target) { input_mode = os_target; } -- cgit v1.2.3-24-g4f1b From 63e5782d2cdf0ee282ad434c773463d9da9db6b3 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 13 Aug 2016 10:43:22 +0200 Subject: process_unicode: Small refactor & linux fix This moves the unicode input start / end sequences into their own functions, so keymaps and other functionality can build on it too. At the same time, it changes how the Linux variant works, to match reality: CTRL+SHIFT must be unregistered too, and we close the thing with a Space instead. Signed-off-by: Gergely Nagy --- quantum/process_keycode/process_unicode.c | 76 ++++++++++++++++++------------- quantum/process_keycode/process_unicode.h | 3 ++ 2 files changed, 48 insertions(+), 31 deletions(-) (limited to 'quantum') diff --git a/quantum/process_keycode/process_unicode.c b/quantum/process_keycode/process_unicode.c index 3fcac15ce..55e47f179 100644 --- a/quantum/process_keycode/process_unicode.c +++ b/quantum/process_keycode/process_unicode.c @@ -18,40 +18,54 @@ void set_unicode_input_mode(uint8_t os_target) input_mode = os_target; } +void unicode_input_start (void) { + switch(input_mode) { + case UC_OSX: + register_code(KC_LALT); + break; + case UC_LNX: + register_code(KC_LCTL); + register_code(KC_LSFT); + register_code(KC_U); + unregister_code(KC_U); + unregister_code(KC_LSFT); + unregister_code(KC_LCTL); + break; + case UC_WIN: + register_code(KC_LALT); + register_code(KC_PPLS); + unregister_code(KC_PPLS); + break; + } +} + +void unicode_input_finish (void) { + switch(input_mode) { + case UC_OSX: + case UC_WIN: + unregister_code(KC_LALT); + break; + case UC_LNX: + register_code(KC_SPC); + unregister_code(KC_SPC); + break; + } +} + +void register_hex(uint16_t hex) { + for(int i = 3; i >= 0; i--) { + uint8_t digit = ((hex >> (i*4)) & 0xF); + register_code(hex_to_keycode(digit)); + unregister_code(hex_to_keycode(digit)); + } +} + bool process_unicode(uint16_t keycode, keyrecord_t *record) { if (keycode > QK_UNICODE && record->event.pressed) { uint16_t unicode = keycode & 0x7FFF; - switch(input_mode) { - case UC_OSX: - register_code(KC_LALT); - break; - case UC_LNX: - register_code(KC_LCTL); - register_code(KC_LSFT); - register_code(KC_U); - unregister_code(KC_U); - break; - case UC_WIN: - register_code(KC_LALT); - register_code(KC_PPLS); - unregister_code(KC_PPLS); - break; - } - for(int i = 3; i >= 0; i--) { - uint8_t digit = ((unicode >> (i*4)) & 0xF); - register_code(hex_to_keycode(digit)); - unregister_code(hex_to_keycode(digit)); - } - switch(input_mode) { - case UC_OSX: - case UC_WIN: - unregister_code(KC_LALT); - break; - case UC_LNX: - unregister_code(KC_LCTL); - unregister_code(KC_LSFT); - break; - } + unicode_input_start(); + register_hex(unicode); + unicode_input_finish(); } return true; } \ No newline at end of file diff --git a/quantum/process_keycode/process_unicode.h b/quantum/process_keycode/process_unicode.h index ca17f8f66..f719a1226 100644 --- a/quantum/process_keycode/process_unicode.h +++ b/quantum/process_keycode/process_unicode.h @@ -9,6 +9,9 @@ #define UC_BSD 3 void set_unicode_input_mode(uint8_t os_target); +void unicode_input_start(void); +void unicode_input_finish(void); +void register_hex(uint16_t hex); bool process_unicode(uint16_t keycode, keyrecord_t *record); -- cgit v1.2.3-24-g4f1b From fa06a163607e8c6c4bd0968c2de96a9a298b777c Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 13 Aug 2016 10:46:38 +0200 Subject: process_unicode: Add a way to enter unicode symbols by name The purpose of this change is to allow keymaps to specify a dictionary of unicode symbol name to code mappings, and let the person at the keyboard enter unicode symbols by name. This is done by having a way to trigger unicode symbol input mode, when all keys are cached until Esc, Enter or Space are pressed. Once that happens, we try to look up the symbol from our lookup table. If found, we erase back, and type the unicode magic in to get that symbol. If not found, we still erase back, start unicode input mode, and replay what the user typed in. Signed-off-by: Gergely Nagy --- quantum/process_keycode/process_unicode.c | 93 ++++++++++++++++++++++++++++++- quantum/process_keycode/process_unicode.h | 29 +++++++++- 2 files changed, 120 insertions(+), 2 deletions(-) (limited to 'quantum') diff --git a/quantum/process_keycode/process_unicode.c b/quantum/process_keycode/process_unicode.c index 55e47f179..8a6509300 100644 --- a/quantum/process_keycode/process_unicode.c +++ b/quantum/process_keycode/process_unicode.c @@ -68,4 +68,95 @@ bool process_unicode(uint16_t keycode, keyrecord_t *record) { unicode_input_finish(); } return true; -} \ No newline at end of file +} + +#ifdef UCIS_ENABLE +void qk_ucis_start(void) { + qk_ucis_state.count = 0; + qk_ucis_state.in_progress = true; + + unicode_input_start(); + register_hex(0x2328); + unicode_input_finish(); +} + +static bool is_uni_seq(char *seq) { + uint8_t i; + + for (i = 0; seq[i]; i++) { + uint16_t code; + if (('1' <= seq[i]) && (seq[i] <= '0')) + code = seq[i] - '1' + KC_1; + else + code = seq[i] - 'a' + KC_A; + + if (i > qk_ucis_state.count || qk_ucis_state.codes[i] != code) + return false; + } + + return (qk_ucis_state.codes[i] == KC_ENT || + qk_ucis_state.codes[i] == KC_SPC); +} + +__attribute__((weak)) +void qk_ucis_symbol_fallback (void) { + for (uint8_t i = 0; i < qk_ucis_state.count - 1; i++) { + uint8_t code = qk_ucis_state.codes[i]; + register_code(code); + unregister_code(code); + } +} + +bool process_record_ucis (uint16_t keycode, keyrecord_t *record) { + uint8_t i; + + if (!qk_ucis_state.in_progress || !record->event.pressed) + return true; + + qk_ucis_state.codes[qk_ucis_state.count] = keycode; + qk_ucis_state.count++; + + if (keycode == KC_BSPC) { + if (qk_ucis_state.count >= 2) { + qk_ucis_state.count -= 2; + return true; + } else { + qk_ucis_state.count--; + return false; + } + } + + if (keycode == KC_ENT || keycode == KC_SPC || keycode == KC_ESC) { + bool symbol_found = false; + + for (i = qk_ucis_state.count; i > 0; i--) { + register_code (KC_BSPC); + unregister_code (KC_BSPC); + } + + if (keycode == KC_ESC) { + qk_ucis_state.in_progress = false; + return false; + } + + unicode_input_start(); + for (i = 0; ucis_symbol_table[i].symbol; i++) { + if (is_uni_seq (ucis_symbol_table[i].symbol)) { + symbol_found = true; + for (uint8_t j = 0; ucis_symbol_table[i].codes[j]; j++) { + register_hex(ucis_symbol_table[i].codes[j]); + } + break; + } + } + if (!symbol_found) { + qk_ucis_symbol_fallback(); + } + unicode_input_finish(); + + qk_ucis_state.in_progress = false; + return false; + } + return true; +} +#endif diff --git a/quantum/process_keycode/process_unicode.h b/quantum/process_keycode/process_unicode.h index f719a1226..372ea2f0d 100644 --- a/quantum/process_keycode/process_unicode.h +++ b/quantum/process_keycode/process_unicode.h @@ -15,6 +15,33 @@ void register_hex(uint16_t hex); bool process_unicode(uint16_t keycode, keyrecord_t *record); +#ifdef UCIS_ENABLE +#ifndef UCIS_MAX_SYMBOL_LENGTH +#define UCIS_MAX_SYMBOL_LENGTH 32 +#endif + +typedef struct { + char *symbol; + uint16_t codes[4]; +} qk_ucis_symbol_t; + +struct { + uint8_t count; + uint16_t codes[UCIS_MAX_SYMBOL_LENGTH]; + bool in_progress:1; +} qk_ucis_state; + +#define UCIS_TABLE(...) {__VA_ARGS__, {NULL, {}}} +#define UCIS_SYM(name, ...) {name, {__VA_ARGS__, 0}} + +extern const qk_ucis_symbol_t ucis_symbol_table[]; + +void qk_ucis_start(void); +void qk_ucis_symbol_fallback (void); +bool process_record_ucis (uint16_t keycode, keyrecord_t *record); + +#endif + #define UC_BSPC UC(0x0008) #define UC_SPC UC(0x0020) @@ -122,4 +149,4 @@ bool process_unicode(uint16_t keycode, keyrecord_t *record); #define UC_TILD UC(0x007E) #define UC_DEL UC(0x007F) -#endif \ No newline at end of file +#endif -- cgit v1.2.3-24-g4f1b From 0b6861827faea747345ea38202d64c8004ab128c Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 13 Aug 2016 11:11:22 +0200 Subject: process_unicode: Handle too long UCIS symbol names If the symbol name being entered is longer than the max, stop recording it, and stop processing keycodes apart from the ones that can delete, finish or cancel the sequence. Signed-off-by: Gergely Nagy --- quantum/process_keycode/process_unicode.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'quantum') diff --git a/quantum/process_keycode/process_unicode.c b/quantum/process_keycode/process_unicode.c index 8a6509300..851a96eaa 100644 --- a/quantum/process_keycode/process_unicode.c +++ b/quantum/process_keycode/process_unicode.c @@ -110,7 +110,15 @@ void qk_ucis_symbol_fallback (void) { bool process_record_ucis (uint16_t keycode, keyrecord_t *record) { uint8_t i; - if (!qk_ucis_state.in_progress || !record->event.pressed) + if (!qk_ucis_state.in_progress) + return true; + + if (qk_ucis_state.count >= UCIS_MAX_SYMBOL_LENGTH && + !(keycode == KC_BSPC || keycode == KC_ESC || keycode == KC_SPC || keycode == KC_ENT)) { + return false; + } + + if (!record->event.pressed) return true; qk_ucis_state.codes[qk_ucis_state.count] = keycode; -- cgit v1.2.3-24-g4f1b From 857aa5bef6a74f8785a7039feea5286c07bf7067 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 13 Aug 2016 11:14:42 +0200 Subject: process_unicode: Call process_ucis() automatically If UCIS is enabled, call process_ucis() automatically from process_record_quantum(). Signed-off-by: Gergely Nagy --- quantum/process_keycode/process_unicode.c | 2 +- quantum/process_keycode/process_unicode.h | 2 +- quantum/quantum.c | 3 +++ 3 files changed, 5 insertions(+), 2 deletions(-) (limited to 'quantum') diff --git a/quantum/process_keycode/process_unicode.c b/quantum/process_keycode/process_unicode.c index 851a96eaa..d71434411 100644 --- a/quantum/process_keycode/process_unicode.c +++ b/quantum/process_keycode/process_unicode.c @@ -107,7 +107,7 @@ void qk_ucis_symbol_fallback (void) { } } -bool process_record_ucis (uint16_t keycode, keyrecord_t *record) { +bool process_ucis (uint16_t keycode, keyrecord_t *record) { uint8_t i; if (!qk_ucis_state.in_progress) diff --git a/quantum/process_keycode/process_unicode.h b/quantum/process_keycode/process_unicode.h index 372ea2f0d..c5005897e 100644 --- a/quantum/process_keycode/process_unicode.h +++ b/quantum/process_keycode/process_unicode.h @@ -38,7 +38,7 @@ extern const qk_ucis_symbol_t ucis_symbol_table[]; void qk_ucis_start(void); void qk_ucis_symbol_fallback (void); -bool process_record_ucis (uint16_t keycode, keyrecord_t *record); +bool process_ucis (uint16_t keycode, keyrecord_t *record); #endif diff --git a/quantum/quantum.c b/quantum/quantum.c index bc2da510f..a4c5c2ddb 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -86,6 +86,9 @@ bool process_record_quantum(keyrecord_t *record) { #endif #ifdef UNICODE_ENABLE process_unicode(keycode, record) && + #endif + #ifdef UCIS_ENABLE + process_ucis(keycode, record) && #endif true)) { return false; -- cgit v1.2.3-24-g4f1b From 234dd276cf03be6fd6961473e9d9c8f35deec682 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 14 Aug 2016 10:37:51 +0200 Subject: process_unicode: Make the startup overridable Extract out the part of `qk_ucis_start` that inputs the placeholder symbol, and make it weak, so it can be overridden. Signed-off-by: Gergely Nagy --- quantum/process_keycode/process_unicode.c | 5 +++++ quantum/process_keycode/process_unicode.h | 1 + 2 files changed, 6 insertions(+) (limited to 'quantum') diff --git a/quantum/process_keycode/process_unicode.c b/quantum/process_keycode/process_unicode.c index d71434411..c474483e7 100644 --- a/quantum/process_keycode/process_unicode.c +++ b/quantum/process_keycode/process_unicode.c @@ -75,6 +75,11 @@ void qk_ucis_start(void) { qk_ucis_state.count = 0; qk_ucis_state.in_progress = true; + qk_ucis_start_user(); +} + +__attribute__((weak)) +void qk_ucis_start_user(void) { unicode_input_start(); register_hex(0x2328); unicode_input_finish(); diff --git a/quantum/process_keycode/process_unicode.h b/quantum/process_keycode/process_unicode.h index c5005897e..75607e40e 100644 --- a/quantum/process_keycode/process_unicode.h +++ b/quantum/process_keycode/process_unicode.h @@ -37,6 +37,7 @@ struct { extern const qk_ucis_symbol_t ucis_symbol_table[]; void qk_ucis_start(void); +void qk_ucis_start_user(void); void qk_ucis_symbol_fallback (void); bool process_ucis (uint16_t keycode, keyrecord_t *record); -- cgit v1.2.3-24-g4f1b From a312cbf712764277e0dbbbb99410c2f6fc6c7484 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 14 Aug 2016 14:34:52 +0200 Subject: process_unicode: Use uint32_t for UCIS purposes Use a single uint32_t to store the unicode of a symbol, instead of an array of uint16_ts. Signed-off-by: Gergely Nagy --- quantum/process_keycode/process_unicode.c | 12 +++++++++--- quantum/process_keycode/process_unicode.h | 7 ++++--- 2 files changed, 13 insertions(+), 6 deletions(-) (limited to 'quantum') diff --git a/quantum/process_keycode/process_unicode.c b/quantum/process_keycode/process_unicode.c index c474483e7..698cc3c02 100644 --- a/quantum/process_keycode/process_unicode.c +++ b/quantum/process_keycode/process_unicode.c @@ -60,6 +60,14 @@ void register_hex(uint16_t hex) { } } +void register_hex32(uint32_t hex) { + for(int i = 7; i >= 0; i--) { + uint8_t digit = ((hex >> (i*8)) & 0xF); + register_code(hex_to_keycode(digit)); + unregister_code(hex_to_keycode(digit)); + } +} + bool process_unicode(uint16_t keycode, keyrecord_t *record) { if (keycode > QK_UNICODE && record->event.pressed) { uint16_t unicode = keycode & 0x7FFF; @@ -156,9 +164,7 @@ bool process_ucis (uint16_t keycode, keyrecord_t *record) { for (i = 0; ucis_symbol_table[i].symbol; i++) { if (is_uni_seq (ucis_symbol_table[i].symbol)) { symbol_found = true; - for (uint8_t j = 0; ucis_symbol_table[i].codes[j]; j++) { - register_hex(ucis_symbol_table[i].codes[j]); - } + register_hex32(ucis_symbol_table[i].code); break; } } diff --git a/quantum/process_keycode/process_unicode.h b/quantum/process_keycode/process_unicode.h index 75607e40e..dd6dd7138 100644 --- a/quantum/process_keycode/process_unicode.h +++ b/quantum/process_keycode/process_unicode.h @@ -12,6 +12,7 @@ void set_unicode_input_mode(uint8_t os_target); void unicode_input_start(void); void unicode_input_finish(void); void register_hex(uint16_t hex); +void register_hex32(uint32_t hex); bool process_unicode(uint16_t keycode, keyrecord_t *record); @@ -22,7 +23,7 @@ bool process_unicode(uint16_t keycode, keyrecord_t *record); typedef struct { char *symbol; - uint16_t codes[4]; + uint32_t code; } qk_ucis_symbol_t; struct { @@ -31,8 +32,8 @@ struct { bool in_progress:1; } qk_ucis_state; -#define UCIS_TABLE(...) {__VA_ARGS__, {NULL, {}}} -#define UCIS_SYM(name, ...) {name, {__VA_ARGS__, 0}} +#define UCIS_TABLE(...) {__VA_ARGS__, {NULL, 0}} +#define UCIS_SYM(name, code) {name, code} extern const qk_ucis_symbol_t ucis_symbol_table[]; -- cgit v1.2.3-24-g4f1b From 43d08629cf275d0b32281ffe8785258fff226b49 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 15 Aug 2016 10:02:05 +0200 Subject: process_unicode: Replace register_hex32 It turns out that register_hex32 did not work reliably, and some systems only allow 7 chars after the unicode magic sequence, while others allow 8. To remedy the situation, store the codes as strings, and type those in instead of doing bit shifting magic. Signed-off-by: Gergely Nagy --- quantum/process_keycode/process_unicode.c | 37 +++++++++++++++++++++++-------- quantum/process_keycode/process_unicode.h | 8 +++---- 2 files changed, 32 insertions(+), 13 deletions(-) (limited to 'quantum') diff --git a/quantum/process_keycode/process_unicode.c b/quantum/process_keycode/process_unicode.c index 698cc3c02..d8a0f667c 100644 --- a/quantum/process_keycode/process_unicode.c +++ b/quantum/process_keycode/process_unicode.c @@ -60,14 +60,6 @@ void register_hex(uint16_t hex) { } } -void register_hex32(uint32_t hex) { - for(int i = 7; i >= 0; i--) { - uint8_t digit = ((hex >> (i*8)) & 0xF); - register_code(hex_to_keycode(digit)); - unregister_code(hex_to_keycode(digit)); - } -} - bool process_unicode(uint16_t keycode, keyrecord_t *record) { if (keycode > QK_UNICODE && record->event.pressed) { uint16_t unicode = keycode & 0x7FFF; @@ -120,6 +112,33 @@ void qk_ucis_symbol_fallback (void) { } } +void register_ucis(const char *hex) { + for(int i = 0; hex[i]; i++) { + uint8_t kc = 0; + char c = hex[i]; + + switch (c) { + case '0': + kc = KC_0; + break; + case '1' ... '9': + kc = c - '1' + KC_1; + break; + case 'a' ... 'f': + kc = c - 'a' + KC_A; + break; + case 'A' ... 'F': + kc = c - 'A' + KC_A; + break; + } + + if (kc) { + register_code (kc); + unregister_code (kc); + } + } +} + bool process_ucis (uint16_t keycode, keyrecord_t *record) { uint8_t i; @@ -164,7 +183,7 @@ bool process_ucis (uint16_t keycode, keyrecord_t *record) { for (i = 0; ucis_symbol_table[i].symbol; i++) { if (is_uni_seq (ucis_symbol_table[i].symbol)) { symbol_found = true; - register_hex32(ucis_symbol_table[i].code); + register_ucis(ucis_symbol_table[i].code + 2); break; } } diff --git a/quantum/process_keycode/process_unicode.h b/quantum/process_keycode/process_unicode.h index dd6dd7138..be24ddc2b 100644 --- a/quantum/process_keycode/process_unicode.h +++ b/quantum/process_keycode/process_unicode.h @@ -12,7 +12,6 @@ void set_unicode_input_mode(uint8_t os_target); void unicode_input_start(void); void unicode_input_finish(void); void register_hex(uint16_t hex); -void register_hex32(uint32_t hex); bool process_unicode(uint16_t keycode, keyrecord_t *record); @@ -23,7 +22,7 @@ bool process_unicode(uint16_t keycode, keyrecord_t *record); typedef struct { char *symbol; - uint32_t code; + char *code; } qk_ucis_symbol_t; struct { @@ -32,14 +31,15 @@ struct { bool in_progress:1; } qk_ucis_state; -#define UCIS_TABLE(...) {__VA_ARGS__, {NULL, 0}} -#define UCIS_SYM(name, code) {name, code} +#define UCIS_TABLE(...) {__VA_ARGS__, {NULL, NULL}} +#define UCIS_SYM(name, code) {name, #code} extern const qk_ucis_symbol_t ucis_symbol_table[]; void qk_ucis_start(void); void qk_ucis_start_user(void); void qk_ucis_symbol_fallback (void); +void register_ucis(const char *hex); bool process_ucis (uint16_t keycode, keyrecord_t *record); #endif -- cgit v1.2.3-24-g4f1b From e8845f0daf8dc7a7674dc5420cc5a684bbbea09b Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 15 Aug 2016 10:07:13 +0200 Subject: process_unicode: Introduce a slight delay When entering unicode codes, use some delay, so the OS has time to process the information. This is not needed on all systems, but some seem to require it. Signed-off-by: Gergely Nagy --- quantum/process_keycode/process_unicode.c | 4 ++++ quantum/process_keycode/process_unicode.h | 4 ++++ 2 files changed, 8 insertions(+) (limited to 'quantum') diff --git a/quantum/process_keycode/process_unicode.c b/quantum/process_keycode/process_unicode.c index d8a0f667c..72c809c30 100644 --- a/quantum/process_keycode/process_unicode.c +++ b/quantum/process_keycode/process_unicode.c @@ -37,6 +37,7 @@ void unicode_input_start (void) { unregister_code(KC_PPLS); break; } + wait_ms(UNICODE_TYPE_DELAY); } void unicode_input_finish (void) { @@ -109,6 +110,7 @@ void qk_ucis_symbol_fallback (void) { uint8_t code = qk_ucis_state.codes[i]; register_code(code); unregister_code(code); + wait_ms(UNICODE_TYPE_DELAY); } } @@ -135,6 +137,7 @@ void register_ucis(const char *hex) { if (kc) { register_code (kc); unregister_code (kc); + wait_ms (UNICODE_TYPE_DELAY); } } } @@ -172,6 +175,7 @@ bool process_ucis (uint16_t keycode, keyrecord_t *record) { for (i = qk_ucis_state.count; i > 0; i--) { register_code (KC_BSPC); unregister_code (KC_BSPC); + wait_ms(UNICODE_TYPE_DELAY); } if (keycode == KC_ESC) { diff --git a/quantum/process_keycode/process_unicode.h b/quantum/process_keycode/process_unicode.h index be24ddc2b..85364e8eb 100644 --- a/quantum/process_keycode/process_unicode.h +++ b/quantum/process_keycode/process_unicode.h @@ -8,6 +8,10 @@ #define UC_WIN 2 #define UC_BSD 3 +#ifndef UNICODE_TYPE_DELAY +#define UNICODE_TYPE_DELAY 10 +#endif + void set_unicode_input_mode(uint8_t os_target); void unicode_input_start(void); void unicode_input_finish(void); -- cgit v1.2.3-24-g4f1b From d78058cc75a9b05a6885991506d5f807ebb2a9f9 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 17 Aug 2016 10:28:08 +0200 Subject: tap-dance: Include action_tapping.h for TAPPING_TERM Include `action_tapping.h`, so the keymap does not have to define a `TAPPING_TERM` for us, and we can use the default. Signed-off-by: Gergely Nagy --- quantum/process_keycode/process_tap_dance.c | 1 + 1 file changed, 1 insertion(+) (limited to 'quantum') diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c index 5429e3438..bab5c4dbd 100644 --- a/quantum/process_keycode/process_tap_dance.c +++ b/quantum/process_keycode/process_tap_dance.c @@ -1,4 +1,5 @@ #include "quantum.h" +#include "action_tapping.h" static qk_tap_dance_state_t qk_tap_dance_state; bool td_debug_enable = false; -- cgit v1.2.3-24-g4f1b From 29f64d7a93d941167c6c6e95f893ab84586b2205 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 17 Aug 2016 13:04:50 +0200 Subject: tap-dance: Major rework, to make it more reliable This reworks how the tap-dance feature works: instead of one global state, we have a state for each tap-dance key, so we can cancel them when another tap-dance key is in flight. This fixes #527. Since we have a state for each key, we can avoid situation where a keyup would mess with our global state. This fixes #563. And while here, we also make sure to fire events only once, and this fixes #574. There is one breaking change, though: tap-dance debugging support was removed, because dumping the whole state would increase the firmware size too much. Any keymap that made use of this, will have to be updated (but there's no such keymap in the repo). Also, there's a nice trick used in this rework: we need to iterate through tap_dance_actions in a few places, to check for timeouts, and so on. For this, we'd need to know the size of the array. We can't discover that at compile-time, because tap-dance gets compiled separately. We'd like to avoid having to terminate the list with a sentinel value, because that would require updates to all keymaps that use the feature. So, we keep track of the highest tap-dance code seen so far, and iterate until that index. Signed-off-by: Gergely Nagy --- quantum/process_keycode/process_tap_dance.c | 121 ++++++++++++++-------------- quantum/process_keycode/process_tap_dance.h | 9 ++- 2 files changed, 66 insertions(+), 64 deletions(-) (limited to 'quantum') diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c index bab5c4dbd..e152f2350 100644 --- a/quantum/process_keycode/process_tap_dance.c +++ b/quantum/process_keycode/process_tap_dance.c @@ -1,19 +1,8 @@ #include "quantum.h" #include "action_tapping.h" -static qk_tap_dance_state_t qk_tap_dance_state; -bool td_debug_enable = false; - -#if CONSOLE_ENABLE -#define td_debug(s) if (td_debug_enable) \ - { \ - xprintf ("D:tap_dance:%s:%s = { keycode = %d, count = %d, active = %d, pressed = %d }\n", __FUNCTION__, s, \ - qk_tap_dance_state.keycode, qk_tap_dance_state.count, \ - qk_tap_dance_state.active, qk_tap_dance_state.pressed); \ - } -#else -#define td_debug(s) -#endif +static uint16_t last_td; +static int8_t highest_td = -1; void qk_tap_dance_pair_finished (qk_tap_dance_state_t *state, void *user_data) { qk_tap_dance_pair_t *pair = (qk_tap_dance_pair_t *)user_data; @@ -36,98 +25,110 @@ void qk_tap_dance_pair_reset (qk_tap_dance_state_t *state, void *user_data) { } static inline void _process_tap_dance_action_fn (qk_tap_dance_state_t *state, - void *user_data, - qk_tap_dance_user_fn_t fn) + void *user_data, + qk_tap_dance_user_fn_t fn) { if (fn) { fn(state, user_data); } } -static inline void process_tap_dance_action_on_each_tap (qk_tap_dance_action_t action) +static inline void process_tap_dance_action_on_each_tap (qk_tap_dance_action_t *action) { - td_debug("trigger"); - _process_tap_dance_action_fn (&qk_tap_dance_state, action.user_data, action.fn.on_each_tap); + _process_tap_dance_action_fn (&action->state, action->user_data, action->fn.on_each_tap); } -static inline void process_tap_dance_action_on_dance_finished (qk_tap_dance_action_t action) +static inline void process_tap_dance_action_on_dance_finished (qk_tap_dance_action_t *action) { - td_debug("trigger"); - _process_tap_dance_action_fn (&qk_tap_dance_state, action.user_data, action.fn.on_dance_finished); + if (action->state.finished) + return; + action->state.finished = true; + _process_tap_dance_action_fn (&action->state, action->user_data, action->fn.on_dance_finished); } -static inline void process_tap_dance_action_on_reset (qk_tap_dance_action_t action) +static inline void process_tap_dance_action_on_reset (qk_tap_dance_action_t *action) { - td_debug("trigger") - _process_tap_dance_action_fn (&qk_tap_dance_state, action.user_data, action.fn.on_reset); + _process_tap_dance_action_fn (&action->state, action->user_data, action->fn.on_reset); } bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { - bool r = true; uint16_t idx = keycode - QK_TAP_DANCE; - qk_tap_dance_action_t action; + qk_tap_dance_action_t *action; + + if (last_td && last_td != keycode) { + (&tap_dance_actions[last_td - QK_TAP_DANCE])->state.interrupted = true; + } switch(keycode) { case QK_TAP_DANCE ... QK_TAP_DANCE_MAX: - action = tap_dance_actions[idx]; - - process_tap_dance_action_on_each_tap (action); - if (qk_tap_dance_state.keycode && qk_tap_dance_state.keycode != keycode) { - process_tap_dance_action_on_dance_finished (action); - } else if (qk_tap_dance_state.active && qk_tap_dance_state.pressed) { - reset_tap_dance (&qk_tap_dance_state); - } else { - r = false; - } + if ((int16_t)idx > highest_td) + highest_td = idx; + action = &tap_dance_actions[idx]; - qk_tap_dance_state.active = true; - qk_tap_dance_state.pressed = record->event.pressed; + action->state.keycode = keycode; + action->state.pressed = record->event.pressed; if (record->event.pressed) { - qk_tap_dance_state.keycode = keycode; - qk_tap_dance_state.timer = timer_read (); - qk_tap_dance_state.count++; + action->state.count++; + action->state.timer = timer_read(); + + if (last_td && last_td != keycode) { + qk_tap_dance_action_t *paction = &tap_dance_actions[last_td - QK_TAP_DANCE]; + paction->state.interrupted = true; + process_tap_dance_action_on_dance_finished (paction); + reset_tap_dance (&paction->state); + } } + last_td = keycode; + break; default: - if (qk_tap_dance_state.keycode) { - // if we are here, the tap dance was interrupted by a different key - idx = qk_tap_dance_state.keycode - QK_TAP_DANCE; - action = tap_dance_actions[idx]; + if (!record->event.pressed) + return true; + + if (highest_td == -1) + return true; - process_tap_dance_action_on_each_tap (action); + for (int i = 0; i <= highest_td; i++) { + action = &tap_dance_actions[i]; + if (action->state.count == 0) + continue; + action->state.interrupted = true; process_tap_dance_action_on_dance_finished (action); - reset_tap_dance (&qk_tap_dance_state); - qk_tap_dance_state.active = false; + reset_tap_dance (&action->state); } break; } - return r; + return true; } void matrix_scan_tap_dance () { - if (qk_tap_dance_state.active && timer_elapsed (qk_tap_dance_state.timer) > TAPPING_TERM) { - // if we are here, the tap dance was timed out - uint16_t idx = qk_tap_dance_state.keycode - QK_TAP_DANCE; - qk_tap_dance_action_t action = tap_dance_actions[idx]; + if (highest_td == -1) + return; + + for (int i = 0; i <= highest_td; i++) { + qk_tap_dance_action_t *action = &tap_dance_actions[i]; - process_tap_dance_action_on_dance_finished (action); - reset_tap_dance (&qk_tap_dance_state); + if (action->state.count && timer_elapsed (action->state.timer) > TAPPING_TERM) { + process_tap_dance_action_on_dance_finished (action); + reset_tap_dance (&action->state); + } } } void reset_tap_dance (qk_tap_dance_state_t *state) { - uint16_t idx = state->keycode - QK_TAP_DANCE; - qk_tap_dance_action_t action; + qk_tap_dance_action_t *action; if (state->pressed) return; - action = tap_dance_actions[idx]; + action = &tap_dance_actions[state->keycode - QK_TAP_DANCE]; + process_tap_dance_action_on_reset (action); - state->keycode = 0; state->count = 0; - state->active = false; + state->interrupted = false; + state->finished = false; + last_td = 0; } diff --git a/quantum/process_keycode/process_tap_dance.h b/quantum/process_keycode/process_tap_dance.h index 6a1258067..d7b857bdc 100644 --- a/quantum/process_keycode/process_tap_dance.h +++ b/quantum/process_keycode/process_tap_dance.h @@ -11,8 +11,9 @@ typedef struct uint8_t count; uint16_t keycode; uint16_t timer; - bool active:1; - bool pressed:1; + bool interrupted; + bool pressed; + bool finished; } qk_tap_dance_state_t; #define TD(n) (QK_TAP_DANCE + n) @@ -26,6 +27,7 @@ typedef struct qk_tap_dance_user_fn_t on_dance_finished; qk_tap_dance_user_fn_t on_reset; } fn; + qk_tap_dance_state_t state; void *user_data; } qk_tap_dance_action_t; @@ -48,8 +50,7 @@ typedef struct .fn = { user_fn_on_each_tap, user_fn_on_dance_finished, user_fn_on_reset } \ } -extern const qk_tap_dance_action_t tap_dance_actions[]; -extern bool td_debug_enable; +extern qk_tap_dance_action_t tap_dance_actions[]; /* To be used internally */ -- cgit v1.2.3-24-g4f1b From 644c8c79271db8cf1bd934b9a80a0215585e46e7 Mon Sep 17 00:00:00 2001 From: Wojciech Siewierski Date: Thu, 18 Aug 2016 01:34:05 +0200 Subject: Fix the process_record_nocache function This function relies on checking the disable_action_cache static variable before accessing the layer cache. --- quantum/quantum.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'quantum') diff --git a/quantum/quantum.c b/quantum/quantum.c index a4c5c2ddb..cb1ba04ff 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -46,18 +46,20 @@ bool process_record_quantum(keyrecord_t *record) { uint16_t keycode; #if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS) - uint8_t layer; + /* TODO: Use store_or_get_action() or a similar function. */ + if (!disable_action_cache) { + uint8_t layer; - if (record->event.pressed) { - layer = layer_switch_get_layer(key); - update_source_layers_cache(key, layer); - } else { - layer = read_source_layers_cache(key); - } - keycode = keymap_key_to_keycode(layer, key); - #else - keycode = keymap_key_to_keycode(layer_switch_get_layer(key), key); + if (record->event.pressed) { + layer = layer_switch_get_layer(key); + update_source_layers_cache(key, layer); + } else { + layer = read_source_layers_cache(key); + } + keycode = keymap_key_to_keycode(layer, key); + } else #endif + keycode = keymap_key_to_keycode(layer_switch_get_layer(key), key); // This is how you use actions here // if (keycode == KC_LEAD) { -- cgit v1.2.3-24-g4f1b From 39e8e61258b51a2c33a94dd877e983f0b1dae0c1 Mon Sep 17 00:00:00 2001 From: Wojciech Siewierski Date: Thu, 18 Aug 2016 01:37:13 +0200 Subject: Implement the dynamic macros that are recorded in runtime --- quantum/dynamic_macro.h | 226 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 226 insertions(+) create mode 100644 quantum/dynamic_macro.h (limited to 'quantum') diff --git a/quantum/dynamic_macro.h b/quantum/dynamic_macro.h new file mode 100644 index 000000000..a3ad61bc7 --- /dev/null +++ b/quantum/dynamic_macro.h @@ -0,0 +1,226 @@ +/* Author: Wojciech Siewierski < wojciech dot siewierski at onet dot pl > */ +#ifndef DYNAMIC_MACROS_H +#define DYNAMIC_MACROS_H + +#include "action_layer.h" + +#ifndef DYNAMIC_MACRO_SIZE +/* May be overridden with a custom value. Be aware that the effective + * macro length is half of this value: each keypress is recorded twice + * because of the down-event and up-event. This is not a bug, it's the + * intended behavior. */ +#define DYNAMIC_MACRO_SIZE 256 +#endif + +/* DYNAMIC_MACRO_RANGE must be set as the last element of user's + * "planck_keycodes" enum prior to including this header. This allows + * us to 'extend' it. + */ +enum dynamic_macro_keycodes { + DYN_REC_START1 = DYNAMIC_MACRO_RANGE, + DYN_REC_START2, + DYN_MACRO_PLAY1, + DYN_MACRO_PLAY2, +}; + +/* Blink the LEDs to notify the user about some event. */ +void dynamic_macro_led_blink(void) +{ + backlight_toggle(); + _delay_ms(100); + backlight_toggle(); +} + +/** + * Start recording of the dynamic macro. + * + * @param[out] macro_pointer The new macro buffer iterator. + * @param[in] macro_buffer The macro buffer used to initialize macro_pointer. + */ +void dynamic_macro_record_start( + keyrecord_t **macro_pointer, keyrecord_t *macro_buffer) +{ + dynamic_macro_led_blink(); + + clear_keyboard(); + layer_clear(); + *macro_pointer = macro_buffer; +} + +/** + * Play the dynamic macro. + * + * @param macro_buffer[in] The beginning of the macro buffer being played. + * @param macro_end[in] The element after the last macro buffer element. + * @param direction[in] Either +1 or -1, which way to iterate the buffer. + */ +void dynamic_macro_play( + keyrecord_t *macro_buffer, keyrecord_t *macro_end, int8_t direction) +{ + uint32_t saved_layer_state = layer_state; + + clear_keyboard(); + layer_clear(); + + while (macro_buffer != macro_end) { + process_record(macro_buffer); + macro_buffer += direction; + } + + clear_keyboard(); + + layer_state = saved_layer_state; +} + +/** + * Record a single key in a dynamic macro. + * + * @param macro_pointer[in,out] The current buffer position. + * @param macro_end2[in] The end of the other macro which shouldn't be overwritten. + * @param direction[in] Either +1 or -1, which way to iterate the buffer. + * @param record[in] The current keypress. + */ +void dynamic_macro_record_key( + keyrecord_t **macro_pointer, + keyrecord_t *macro_end2, + int8_t direction, + keyrecord_t *record) +{ + if (*macro_pointer + direction != macro_end2) { + **macro_pointer = *record; + *macro_pointer += direction; + } else { + /* Notify about the end of buffer. The blinks are paired + * because they should happen on both down and up events. */ + backlight_toggle(); + } +} + +/** + * End recording of the dynamic macro. Essentially just update the + * pointer to the end of the macro. + */ +void dynamic_macro_record_end(keyrecord_t *macro_pointer, keyrecord_t **macro_end) +{ + dynamic_macro_led_blink(); + + *macro_end = macro_pointer; +} + +/* Handle the key events related to the dynamic macros. Should be + * called from process_record_user() like this: + * + * bool process_record_user(uint16_t keycode, keyrecord_t *record) { + * if (!process_record_dynamic_macro(keycode, record)) { + * return false; + * } + * <...THE REST OF THE FUNCTION...> + * } + */ +bool process_record_dynamic_macro(uint16_t keycode, keyrecord_t *record) +{ + /* Both macros use the same buffer but read/write on different + * ends of it. + * + * Macro1 is written left-to-right starting from the beginning of + * the buffer. + * + * Macro2 is written right-to-left starting from the end of the + * buffer. + * + * ¯o_buffer macro_end + * v v + * +------------------------------------------------------------+ + * |>>>>>> MACRO1 >>>>>>| |<<<<<<<<<<<<< MACRO2 <<<<<<<<<<<<<| + * +------------------------------------------------------------+ + * ^ ^ + * r_macro_end r_macro_buffer + * + * During the recording when one macro encounters the end of the + * other macro, the recording is stopped. Apart from this, there + * are no arbitrary limits for the macros' length in relation to + * each other: for example one can either have two medium sized + * macros or one long macro and one short macro. Or even one empty + * and one using the whole buffer. + */ + static keyrecord_t macro_buffer[DYNAMIC_MACRO_SIZE]; + + /* Pointer to the first buffer element after the first macro. + * Initially points to the very beginning of the buffer since the + * macro is empty. */ + static keyrecord_t *macro_end = macro_buffer; + + /* The other end of the macro buffer. Serves as the beginning of + * the second macro. */ + static keyrecord_t *const r_macro_buffer = macro_buffer + DYNAMIC_MACRO_SIZE - 1; + + /* Like macro_end but for the second macro. */ + static keyrecord_t *r_macro_end = r_macro_buffer; + + /* A persistent pointer to the current macro position (iterator) + * used during the recording. */ + static keyrecord_t *macro_pointer = NULL; + + /* 0 - no macro is being recorded right now + * 1,2 - either macro 1 or 2 is being recorded */ + static uint8_t macro_id = 0; + + if (macro_id == 0) { + /* No macro recording in progress. */ + if (!record->event.pressed) { + switch (keycode) { + case DYN_REC_START1: + dynamic_macro_record_start(¯o_pointer, macro_buffer); + macro_id = 1; + return false; + case DYN_REC_START2: + dynamic_macro_record_start(¯o_pointer, r_macro_buffer); + macro_id = 2; + return false; + case DYN_MACRO_PLAY1: + dynamic_macro_play(macro_buffer, macro_end, +1); + return false; + case DYN_MACRO_PLAY2: + dynamic_macro_play(r_macro_buffer, r_macro_end, -1); + return false; + } + } + } else { + /* A macro is being recorded right now. */ + switch (keycode) { + case MO(_DYN): + /* Use the layer key used to access the macro recording as + * a stop button. */ + if (record->event.pressed) { /* Ignore the initial release + * just after the recoding + * starts. */ + switch (macro_id) { + case 1: + dynamic_macro_record_end(macro_pointer, ¯o_end); + break; + case 2: + dynamic_macro_record_end(macro_pointer, &r_macro_end); + break; + } + macro_id = 0; + } + return false; + default: + /* Store the key in the macro buffer and process it normally. */ + switch (macro_id) { + case 1: + dynamic_macro_record_key(¯o_pointer, r_macro_end, +1, record); + break; + case 2: + dynamic_macro_record_key(¯o_pointer, macro_end, -1, record); + break; + } + return true; + break; + } + } + + return true; +} + +#endif -- cgit v1.2.3-24-g4f1b From 0d28787c5cf2173d12f57b397515f91cffaa820a Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 18 Aug 2016 11:29:53 +0200 Subject: Add a register/unregister_code16 pair of functions These functions register not only the 8bit keycode, but the modifiers too. It doesn't handle the full range of the upper 8bits, just the mods, but that's a good start. Changed the tap-dance pair functions to use these, so one can do: `ACTION_TAP_DANCE_DOUBLE (KC_COLN, KC_SCLN)` ...and that will do the right thing. Signed-off-by: Gergely Nagy --- quantum/process_keycode/process_tap_dance.c | 8 +++---- quantum/quantum.c | 37 +++++++++++++++++++++++++++++ quantum/quantum.h | 3 +++ 3 files changed, 44 insertions(+), 4 deletions(-) (limited to 'quantum') diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c index e152f2350..07de3ecb8 100644 --- a/quantum/process_keycode/process_tap_dance.c +++ b/quantum/process_keycode/process_tap_dance.c @@ -8,9 +8,9 @@ void qk_tap_dance_pair_finished (qk_tap_dance_state_t *state, void *user_data) { qk_tap_dance_pair_t *pair = (qk_tap_dance_pair_t *)user_data; if (state->count == 1) { - register_code (pair->kc1); + register_code16 (pair->kc1); } else if (state->count == 2) { - register_code (pair->kc2); + register_code16 (pair->kc2); } } @@ -18,9 +18,9 @@ void qk_tap_dance_pair_reset (qk_tap_dance_state_t *state, void *user_data) { qk_tap_dance_pair_t *pair = (qk_tap_dance_pair_t *)user_data; if (state->count == 1) { - unregister_code (pair->kc1); + unregister_code16 (pair->kc1); } else if (state->count == 2) { - unregister_code (pair->kc2); + unregister_code16 (pair->kc2); } } diff --git a/quantum/quantum.c b/quantum/quantum.c index cb1ba04ff..e3a20f43e 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -1,5 +1,42 @@ #include "quantum.h" +static void do_code16 (uint16_t code, void (*f) (uint8_t)) { + switch (code) { + case QK_MODS ... QK_MODS_MAX: + break; + default: + return; + } + + if (code & QK_LCTL) + f(KC_LCTL); + if (code & QK_LSFT) + f(KC_LSFT); + if (code & QK_LALT) + f(KC_LALT); + if (code & QK_LGUI) + f(KC_LGUI); + + if (code & QK_RCTL) + f(KC_RCTL); + if (code & QK_RSFT) + f(KC_RSFT); + if (code & QK_RALT) + f(KC_RALT); + if (code & QK_RGUI) + f(KC_RGUI); +} + +void register_code16 (uint16_t code) { + do_code16 (code, register_code); + register_code (code); +} + +void unregister_code16 (uint16_t code) { + unregister_code (code); + do_code16 (code, unregister_code); +} + __attribute__ ((weak)) bool process_action_kb(keyrecord_t *record) { return true; diff --git a/quantum/quantum.h b/quantum/quantum.h index 6e3fbcc79..0c6046649 100644 --- a/quantum/quantum.h +++ b/quantum/quantum.h @@ -83,6 +83,9 @@ void reset_keyboard(void); void startup_user(void); void shutdown_user(void); +void register_code16 (uint16_t code); +void unregister_code16 (uint16_t code); + #ifdef BACKLIGHT_ENABLE void backlight_init_ports(void); -- cgit v1.2.3-24-g4f1b From ab4d7adbb96fa034fd20364247d615f527661594 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Fri, 19 Aug 2016 09:06:28 +0300 Subject: Fix the template for the Makefile/rules.mk split --- quantum/template/Makefile | 76 ++--------------------------------------------- quantum/template/rules.mk | 67 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 74 deletions(-) create mode 100644 quantum/template/rules.mk (limited to 'quantum') diff --git a/quantum/template/Makefile b/quantum/template/Makefile index 3f6d133c9..4e2a6f00f 100644 --- a/quantum/template/Makefile +++ b/quantum/template/Makefile @@ -1,75 +1,3 @@ - - -# MCU name -#MCU = at90usb1287 -MCU = atmega32u4 - -# Processor frequency. -# This will define a symbol, F_CPU, in all source code files equal to the -# processor frequency in Hz. You can then use this symbol in your source code to -# calculate timings. Do NOT tack on a 'UL' at the end, this will be done -# automatically to create a 32-bit value in your source code. -# -# This will be an integer division of F_USB below, as it is sourced by -# F_USB after it has run through any CPU prescalers. Note that this value -# does not *change* the processor frequency - it should merely be updated to -# reflect the processor speed set externally so that the code can use accurate -# software delays. -F_CPU = 16000000 - - -# -# LUFA specific -# -# Target architecture (see library "Board Types" documentation). -ARCH = AVR8 - -# Input clock frequency. -# This will define a symbol, F_USB, in all source code files equal to the -# input clock frequency (before any prescaling is performed) in Hz. This value may -# differ from F_CPU if prescaling is used on the latter, and is required as the -# raw input clock is fed directly to the PLL sections of the AVR for high speed -# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL' -# at the end, this will be done automatically to create a 32-bit value in your -# source code. -# -# If no clock division is performed on the input clock inside the AVR (via the -# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU. -F_USB = $(F_CPU) - -# Interrupt driven control endpoint task(+60) -OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT - - -# Boot Section Size in *bytes* -# Teensy halfKay 512 -# Teensy++ halfKay 1024 -# Atmel DFU loader 4096 -# LUFA bootloader 4096 -# USBaspLoader 2048 -OPT_DEFS += -DBOOTLOADER_SIZE=512 - - -# Build Options -# change yes to no to disable -# -BOOTMAGIC_ENABLE ?= no # Virtual DIP switch configuration(+1000) -MOUSEKEY_ENABLE ?= yes # Mouse keys(+4700) -EXTRAKEY_ENABLE ?= yes # Audio control and System control(+450) -CONSOLE_ENABLE ?= yes # Console for debug(+400) -COMMAND_ENABLE ?= yes # Commands for debug and configuration -# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE -SLEEP_LED_ENABLE ?= no # Breathing sleep LED during USB suspend -# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work -NKRO_ENABLE ?= no # USB Nkey Rollover -BACKLIGHT_ENABLE ?= no # Enable keyboard backlight functionality on B7 by default -MIDI_ENABLE ?= no # MIDI controls -UNICODE_ENABLE ?= no # Unicode -BLUETOOTH_ENABLE ?= no # Enable Bluetooth with the Adafruit EZ-Key HID -AUDIO_ENABLE ?= no # Audio output on port C6 - -ifndef QUANTUM_DIR +ifndef MAKEFILE_INCLUDED include ../../Makefile -endif - - +endif \ No newline at end of file diff --git a/quantum/template/rules.mk b/quantum/template/rules.mk new file mode 100644 index 000000000..55898147d --- /dev/null +++ b/quantum/template/rules.mk @@ -0,0 +1,67 @@ +# MCU name +#MCU = at90usb1287 +MCU = atmega32u4 + +# Processor frequency. +# This will define a symbol, F_CPU, in all source code files equal to the +# processor frequency in Hz. You can then use this symbol in your source code to +# calculate timings. Do NOT tack on a 'UL' at the end, this will be done +# automatically to create a 32-bit value in your source code. +# +# This will be an integer division of F_USB below, as it is sourced by +# F_USB after it has run through any CPU prescalers. Note that this value +# does not *change* the processor frequency - it should merely be updated to +# reflect the processor speed set externally so that the code can use accurate +# software delays. +F_CPU = 16000000 + + +# +# LUFA specific +# +# Target architecture (see library "Board Types" documentation). +ARCH = AVR8 + +# Input clock frequency. +# This will define a symbol, F_USB, in all source code files equal to the +# input clock frequency (before any prescaling is performed) in Hz. This value may +# differ from F_CPU if prescaling is used on the latter, and is required as the +# raw input clock is fed directly to the PLL sections of the AVR for high speed +# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL' +# at the end, this will be done automatically to create a 32-bit value in your +# source code. +# +# If no clock division is performed on the input clock inside the AVR (via the +# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU. +F_USB = $(F_CPU) + +# Interrupt driven control endpoint task(+60) +OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT + + +# Boot Section Size in *bytes* +# Teensy halfKay 512 +# Teensy++ halfKay 1024 +# Atmel DFU loader 4096 +# LUFA bootloader 4096 +# USBaspLoader 2048 +OPT_DEFS += -DBOOTLOADER_SIZE=512 + + +# Build Options +# change yes to no to disable +# +BOOTMAGIC_ENABLE ?= no # Virtual DIP switch configuration(+1000) +MOUSEKEY_ENABLE ?= yes # Mouse keys(+4700) +EXTRAKEY_ENABLE ?= yes # Audio control and System control(+450) +CONSOLE_ENABLE ?= yes # Console for debug(+400) +COMMAND_ENABLE ?= yes # Commands for debug and configuration +# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE +SLEEP_LED_ENABLE ?= no # Breathing sleep LED during USB suspend +# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work +NKRO_ENABLE ?= no # USB Nkey Rollover +BACKLIGHT_ENABLE ?= no # Enable keyboard backlight functionality on B7 by default +MIDI_ENABLE ?= no # MIDI controls +UNICODE_ENABLE ?= no # Unicode +BLUETOOTH_ENABLE ?= no # Enable Bluetooth with the Adafruit EZ-Key HID +AUDIO_ENABLE ?= no # Audio output on port C6 -- cgit v1.2.3-24-g4f1b From dffdeb50b79d3c623e2ed9fd1c1d82d6d0ae7bf0 Mon Sep 17 00:00:00 2001 From: coderkun Date: Sun, 21 Aug 2016 20:25:19 +0200 Subject: Add method to set Unicode input key for ISO 14755 https://github.com/jackhumbert/qmk_firmware/issues/672 --- quantum/process_keycode/process_unicode.c | 10 ++++++++-- quantum/process_keycode/process_unicode.h | 5 +++++ 2 files changed, 13 insertions(+), 2 deletions(-) (limited to 'quantum') diff --git a/quantum/process_keycode/process_unicode.c b/quantum/process_keycode/process_unicode.c index 72c809c30..422217b6d 100644 --- a/quantum/process_keycode/process_unicode.c +++ b/quantum/process_keycode/process_unicode.c @@ -1,6 +1,7 @@ #include "process_unicode.h" static uint8_t input_mode; +static uint16_t linux_key = UNICODE_LNX_KEY; uint16_t hex_to_keycode(uint8_t hex) { @@ -18,6 +19,11 @@ void set_unicode_input_mode(uint8_t os_target) input_mode = os_target; } +void set_unicode_input_key_lnx(uint16_t key) +{ + linux_key = key; +} + void unicode_input_start (void) { switch(input_mode) { case UC_OSX: @@ -26,8 +32,8 @@ void unicode_input_start (void) { case UC_LNX: register_code(KC_LCTL); register_code(KC_LSFT); - register_code(KC_U); - unregister_code(KC_U); + register_code(linux_key); + unregister_code(linux_key); unregister_code(KC_LSFT); unregister_code(KC_LCTL); break; diff --git a/quantum/process_keycode/process_unicode.h b/quantum/process_keycode/process_unicode.h index 85364e8eb..60a116ab7 100644 --- a/quantum/process_keycode/process_unicode.h +++ b/quantum/process_keycode/process_unicode.h @@ -8,11 +8,16 @@ #define UC_WIN 2 #define UC_BSD 3 +#ifndef UNICODE_LNX_KEY +#define UNICODE_LNX_KEY KC_A +#endif + #ifndef UNICODE_TYPE_DELAY #define UNICODE_TYPE_DELAY 10 #endif void set_unicode_input_mode(uint8_t os_target); +void set_unicode_input_key_lnx(uint16_t linux_key); void unicode_input_start(void); void unicode_input_finish(void); void register_hex(uint16_t hex); -- cgit v1.2.3-24-g4f1b From 81594c7883deefedbcd317c72c1b1f1d32e65cd7 Mon Sep 17 00:00:00 2001 From: coderkun Date: Sun, 21 Aug 2016 21:02:18 +0200 Subject: Drop method to set Unicode input key and declare start and finish methods as “weak” instead MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- quantum/process_keycode/process_unicode.c | 12 ++++-------- quantum/process_keycode/process_unicode.h | 5 ----- 2 files changed, 4 insertions(+), 13 deletions(-) (limited to 'quantum') diff --git a/quantum/process_keycode/process_unicode.c b/quantum/process_keycode/process_unicode.c index 422217b6d..a1be8d2fc 100644 --- a/quantum/process_keycode/process_unicode.c +++ b/quantum/process_keycode/process_unicode.c @@ -1,7 +1,6 @@ #include "process_unicode.h" static uint8_t input_mode; -static uint16_t linux_key = UNICODE_LNX_KEY; uint16_t hex_to_keycode(uint8_t hex) { @@ -19,11 +18,7 @@ void set_unicode_input_mode(uint8_t os_target) input_mode = os_target; } -void set_unicode_input_key_lnx(uint16_t key) -{ - linux_key = key; -} - +__attribute__((weak)) void unicode_input_start (void) { switch(input_mode) { case UC_OSX: @@ -32,8 +27,8 @@ void unicode_input_start (void) { case UC_LNX: register_code(KC_LCTL); register_code(KC_LSFT); - register_code(linux_key); - unregister_code(linux_key); + register_code(KC_U); + unregister_code(KC_U); unregister_code(KC_LSFT); unregister_code(KC_LCTL); break; @@ -46,6 +41,7 @@ void unicode_input_start (void) { wait_ms(UNICODE_TYPE_DELAY); } +__attribute__((weak)) void unicode_input_finish (void) { switch(input_mode) { case UC_OSX: diff --git a/quantum/process_keycode/process_unicode.h b/quantum/process_keycode/process_unicode.h index 60a116ab7..85364e8eb 100644 --- a/quantum/process_keycode/process_unicode.h +++ b/quantum/process_keycode/process_unicode.h @@ -8,16 +8,11 @@ #define UC_WIN 2 #define UC_BSD 3 -#ifndef UNICODE_LNX_KEY -#define UNICODE_LNX_KEY KC_A -#endif - #ifndef UNICODE_TYPE_DELAY #define UNICODE_TYPE_DELAY 10 #endif void set_unicode_input_mode(uint8_t os_target); -void set_unicode_input_key_lnx(uint16_t linux_key); void unicode_input_start(void); void unicode_input_finish(void); void register_hex(uint16_t hex); -- cgit v1.2.3-24-g4f1b From 705c775a4a433249081321cea0c2def2627817dc Mon Sep 17 00:00:00 2001 From: IBNobody Date: Sun, 21 Aug 2016 22:05:55 -0500 Subject: Nightly Only major change to qmk was the addition of A0-A7 pins for the AT90USB --- quantum/config_common.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'quantum') diff --git a/quantum/config_common.h b/quantum/config_common.h index 09a4fe701..7ef4b23d4 100644 --- a/quantum/config_common.h +++ b/quantum/config_common.h @@ -45,6 +45,15 @@ #define F5 0xF5 #define F6 0xF6 #define F7 0xF7 +#define A0 0xA0 +#define A1 0xA1 +#define A2 0xA2 +#define A3 0xA3 +#define A4 0xA4 +#define A5 0xA5 +#define A6 0xA6 +#define A7 0xA7 + /* USART configuration */ #ifdef BLUETOOTH_ENABLE -- cgit v1.2.3-24-g4f1b From a058ae40e268b34ba5db45f5fd5d557d50fa5437 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 24 Aug 2016 15:39:23 +0200 Subject: quantum: Move qk_ucis_state to process_unicode.c In order to not declare the same variable in multiple objects (which happens when building UCIS-enabled keymap for both the ErgoDox EZ and the ErgoDox Infinity), move the declaration to the .c file, and keep only an extern reference in the header. Many thanks to @fredizzimo for spotting the error in Travis, and suggesting the fix. Signed-off-by: Gergely Nagy --- quantum/process_keycode/process_unicode.c | 2 ++ quantum/process_keycode/process_unicode.h | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'quantum') diff --git a/quantum/process_keycode/process_unicode.c b/quantum/process_keycode/process_unicode.c index a1be8d2fc..06c1694f2 100644 --- a/quantum/process_keycode/process_unicode.c +++ b/quantum/process_keycode/process_unicode.c @@ -74,6 +74,8 @@ bool process_unicode(uint16_t keycode, keyrecord_t *record) { } #ifdef UCIS_ENABLE +qk_ucis_state_t qk_ucis_state; + void qk_ucis_start(void) { qk_ucis_state.count = 0; qk_ucis_state.in_progress = true; diff --git a/quantum/process_keycode/process_unicode.h b/quantum/process_keycode/process_unicode.h index 85364e8eb..02ce3dd7e 100644 --- a/quantum/process_keycode/process_unicode.h +++ b/quantum/process_keycode/process_unicode.h @@ -29,11 +29,13 @@ typedef struct { char *code; } qk_ucis_symbol_t; -struct { +typedef struct { uint8_t count; uint16_t codes[UCIS_MAX_SYMBOL_LENGTH]; bool in_progress:1; -} qk_ucis_state; +} qk_ucis_state_t; + +extern qk_ucis_state_t qk_ucis_state; #define UCIS_TABLE(...) {__VA_ARGS__, {NULL, NULL}} #define UCIS_SYM(name, code) {name, #code} -- cgit v1.2.3-24-g4f1b From 936a26d04ffa12801031c058f27e221174e3fabd Mon Sep 17 00:00:00 2001 From: IBNobody Date: Thu, 25 Aug 2016 00:15:41 -0500 Subject: Added pin support for A0-A7 Vision Division - It works! --- quantum/config_common.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'quantum') diff --git a/quantum/config_common.h b/quantum/config_common.h index 7ef4b23d4..8ed5f4a10 100644 --- a/quantum/config_common.h +++ b/quantum/config_common.h @@ -45,14 +45,14 @@ #define F5 0xF5 #define F6 0xF6 #define F7 0xF7 -#define A0 0xA0 -#define A1 0xA1 -#define A2 0xA2 -#define A3 0xA3 -#define A4 0xA4 -#define A5 0xA5 -#define A6 0xA6 -#define A7 0xA7 +#define A0 0x00 +#define A1 0x01 +#define A2 0x02 +#define A3 0x03 +#define A4 0x04 +#define A5 0x05 +#define A6 0x06 +#define A7 0x07 /* USART configuration */ -- cgit v1.2.3-24-g4f1b From 6d7cd639a5e4503f00162c7cfa4bc7302b82c71c Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Sun, 21 Aug 2016 16:29:54 +0300 Subject: Basic framework for parsing test targets --- quantum/serial_link/tests/testlist.mk | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 quantum/serial_link/tests/testlist.mk (limited to 'quantum') diff --git a/quantum/serial_link/tests/testlist.mk b/quantum/serial_link/tests/testlist.mk new file mode 100644 index 000000000..4a734b1e1 --- /dev/null +++ b/quantum/serial_link/tests/testlist.mk @@ -0,0 +1,6 @@ +TEST_LIST +=\ + serial_link_byte_stuffer\ + serial_link_frame_router\ + serial_link_frame_validator\ + serial_link_transport\ + serial_link_triple_buffered_object \ No newline at end of file -- cgit v1.2.3-24-g4f1b From 0a11460175d6a838c71343c19eb4ce4699936247 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Wed, 24 Aug 2016 22:23:17 +0300 Subject: Build actual tests, convert byte_stuffer_tests --- quantum/serial_link/protocol/byte_stuffer.c | 3 - quantum/serial_link/protocol/byte_stuffer.h | 3 + quantum/serial_link/tests/byte_stuffer_tests.c | 506 ----------------------- quantum/serial_link/tests/byte_stuffer_tests.cpp | 483 ++++++++++++++++++++++ quantum/serial_link/tests/rules.mk | 3 + 5 files changed, 489 insertions(+), 509 deletions(-) delete mode 100644 quantum/serial_link/tests/byte_stuffer_tests.c create mode 100644 quantum/serial_link/tests/byte_stuffer_tests.cpp create mode 100644 quantum/serial_link/tests/rules.mk (limited to 'quantum') diff --git a/quantum/serial_link/protocol/byte_stuffer.c b/quantum/serial_link/protocol/byte_stuffer.c index fb4c45a8d..2c87d64c2 100644 --- a/quantum/serial_link/protocol/byte_stuffer.c +++ b/quantum/serial_link/protocol/byte_stuffer.c @@ -31,9 +31,6 @@ SOFTWARE. // https://en.wikipedia.org/wiki/Consistent_Overhead_Byte_Stuffing // http://www.stuartcheshire.org/papers/COBSforToN.pdf -#define MAX_FRAME_SIZE 1024 -#define NUM_LINKS 2 - typedef struct byte_stuffer_state { uint16_t next_zero; uint16_t data_pos; diff --git a/quantum/serial_link/protocol/byte_stuffer.h b/quantum/serial_link/protocol/byte_stuffer.h index 2cc88beb4..97e896856 100644 --- a/quantum/serial_link/protocol/byte_stuffer.h +++ b/quantum/serial_link/protocol/byte_stuffer.h @@ -27,6 +27,9 @@ SOFTWARE. #include +#define MAX_FRAME_SIZE 1024 +#define NUM_LINKS 2 + void init_byte_stuffer(void); void byte_stuffer_recv_byte(uint8_t link, uint8_t data); void byte_stuffer_send_frame(uint8_t link, uint8_t* data, uint16_t size); diff --git a/quantum/serial_link/tests/byte_stuffer_tests.c b/quantum/serial_link/tests/byte_stuffer_tests.c deleted file mode 100644 index 64b170e8c..000000000 --- a/quantum/serial_link/tests/byte_stuffer_tests.c +++ /dev/null @@ -1,506 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include -#include -#include "serial_link/protocol/byte_stuffer.h" -#include "serial_link/protocol/byte_stuffer.c" -#include "serial_link/protocol/frame_validator.h" -#include "serial_link/protocol/physical.h" - -static uint8_t sent_data[MAX_FRAME_SIZE*2]; -static uint16_t sent_data_size; - -Describe(ByteStuffer); -BeforeEach(ByteStuffer) { - init_byte_stuffer(); - sent_data_size = 0; -} -AfterEach(ByteStuffer) {} - -void validator_recv_frame(uint8_t link, uint8_t* data, uint16_t size) { - mock(data, size); -} - -void send_data(uint8_t link, const uint8_t* data, uint16_t size) { - memcpy(sent_data + sent_data_size, data, size); - sent_data_size += size; -} - -Ensure(ByteStuffer, receives_no_frame_for_a_single_zero_byte) { - never_expect(validator_recv_frame); - byte_stuffer_recv_byte(0, 0); -} - -Ensure(ByteStuffer, receives_no_frame_for_a_single_FF_byte) { - never_expect(validator_recv_frame); - byte_stuffer_recv_byte(0, 0xFF); -} - -Ensure(ByteStuffer, receives_no_frame_for_a_single_random_byte) { - never_expect(validator_recv_frame); - byte_stuffer_recv_byte(0, 0x4A); -} - -Ensure(ByteStuffer, receives_no_frame_for_a_zero_length_frame) { - never_expect(validator_recv_frame); - byte_stuffer_recv_byte(0, 1); - byte_stuffer_recv_byte(0, 0); -} - -Ensure(ByteStuffer, receives_single_byte_valid_frame) { - uint8_t expected[] = {0x37}; - expect(validator_recv_frame, - when(size, is_equal_to(1)), - when(data, is_equal_to_contents_of(expected, 1)) - ); - byte_stuffer_recv_byte(0, 2); - byte_stuffer_recv_byte(0, 0x37); - byte_stuffer_recv_byte(0, 0); -} - -Ensure(ByteStuffer, receives_three_bytes_valid_frame) { - uint8_t expected[] = {0x37, 0x99, 0xFF}; - expect(validator_recv_frame, - when(size, is_equal_to(3)), - when(data, is_equal_to_contents_of(expected, 3)) - ); - byte_stuffer_recv_byte(0, 4); - byte_stuffer_recv_byte(0, 0x37); - byte_stuffer_recv_byte(0, 0x99); - byte_stuffer_recv_byte(0, 0xFF); - byte_stuffer_recv_byte(0, 0); -} - -Ensure(ByteStuffer, receives_single_zero_valid_frame) { - uint8_t expected[] = {0}; - expect(validator_recv_frame, - when(size, is_equal_to(1)), - when(data, is_equal_to_contents_of(expected, 1)) - ); - byte_stuffer_recv_byte(0, 1); - byte_stuffer_recv_byte(0, 1); - byte_stuffer_recv_byte(0, 0); -} - -Ensure(ByteStuffer, receives_valid_frame_with_zeroes) { - uint8_t expected[] = {5, 0, 3, 0}; - expect(validator_recv_frame, - when(size, is_equal_to(4)), - when(data, is_equal_to_contents_of(expected, 4)) - ); - byte_stuffer_recv_byte(0, 2); - byte_stuffer_recv_byte(0, 5); - byte_stuffer_recv_byte(0, 2); - byte_stuffer_recv_byte(0, 3); - byte_stuffer_recv_byte(0, 1); - byte_stuffer_recv_byte(0, 0); -} - -Ensure(ByteStuffer, receives_two_valid_frames) { - uint8_t expected1[] = {5, 0}; - uint8_t expected2[] = {3}; - expect(validator_recv_frame, - when(size, is_equal_to(2)), - when(data, is_equal_to_contents_of(expected1, 2)) - ); - expect(validator_recv_frame, - when(size, is_equal_to(1)), - when(data, is_equal_to_contents_of(expected2, 1)) - ); - byte_stuffer_recv_byte(1, 2); - byte_stuffer_recv_byte(1, 5); - byte_stuffer_recv_byte(1, 1); - byte_stuffer_recv_byte(1, 0); - byte_stuffer_recv_byte(1, 2); - byte_stuffer_recv_byte(1, 3); - byte_stuffer_recv_byte(1, 0); -} - -Ensure(ByteStuffer, receives_valid_frame_after_unexpected_zero) { - uint8_t expected[] = {5, 7}; - expect(validator_recv_frame, - when(size, is_equal_to(2)), - when(data, is_equal_to_contents_of(expected, 2)) - ); - byte_stuffer_recv_byte(1, 3); - byte_stuffer_recv_byte(1, 1); - byte_stuffer_recv_byte(1, 0); - byte_stuffer_recv_byte(1, 3); - byte_stuffer_recv_byte(1, 5); - byte_stuffer_recv_byte(1, 7); - byte_stuffer_recv_byte(1, 0); -} - -Ensure(ByteStuffer, receives_valid_frame_after_unexpected_non_zero) { - uint8_t expected[] = {5, 7}; - expect(validator_recv_frame, - when(size, is_equal_to(2)), - when(data, is_equal_to_contents_of(expected, 2)) - ); - byte_stuffer_recv_byte(0, 2); - byte_stuffer_recv_byte(0, 9); - byte_stuffer_recv_byte(0, 4); // This should have been zero - byte_stuffer_recv_byte(0, 0); - byte_stuffer_recv_byte(0, 3); - byte_stuffer_recv_byte(0, 5); - byte_stuffer_recv_byte(0, 7); - byte_stuffer_recv_byte(0, 0); -} - -Ensure(ByteStuffer, receives_a_valid_frame_with_over254_non_zeroes_and_then_end_of_frame) { - uint8_t expected[254]; - int i; - for (i=0;i<254;i++) { - expected[i] = i + 1; - } - expect(validator_recv_frame, - when(size, is_equal_to(254)), - when(data, is_equal_to_contents_of(expected, 254)) - ); - byte_stuffer_recv_byte(0, 0xFF); - for (i=0;i<254;i++) { - byte_stuffer_recv_byte(0, i+1); - } - byte_stuffer_recv_byte(0, 0); -} - -Ensure(ByteStuffer, receives_a_valid_frame_with_over254_non_zeroes_next_byte_is_non_zero) { - uint8_t expected[255]; - int i; - for (i=0;i<254;i++) { - expected[i] = i + 1; - } - expected[254] = 7; - expect(validator_recv_frame, - when(size, is_equal_to(255)), - when(data, is_equal_to_contents_of(expected, 255)) - ); - byte_stuffer_recv_byte(0, 0xFF); - for (i=0;i<254;i++) { - byte_stuffer_recv_byte(0, i+1); - } - byte_stuffer_recv_byte(0, 2); - byte_stuffer_recv_byte(0, 7); - byte_stuffer_recv_byte(0, 0); -} - -Ensure(ByteStuffer, receives_a_valid_frame_with_over254_non_zeroes_next_byte_is_zero) { - uint8_t expected[255]; - int i; - for (i=0;i<254;i++) { - expected[i] = i + 1; - } - expected[254] = 0; - expect(validator_recv_frame, - when(size, is_equal_to(255)), - when(data, is_equal_to_contents_of(expected, 255)) - ); - byte_stuffer_recv_byte(0, 0xFF); - for (i=0;i<254;i++) { - byte_stuffer_recv_byte(0, i+1); - } - byte_stuffer_recv_byte(0, 1); - byte_stuffer_recv_byte(0, 1); - byte_stuffer_recv_byte(0, 0); -} - -Ensure(ByteStuffer, receives_two_long_frames_and_some_more) { - uint8_t expected[515]; - int i; - int j; - for (j=0;j<2;j++) { - for (i=0;i<254;i++) { - expected[i+254*j] = i + 1; - } - } - for (i=0;i<7;i++) { - expected[254*2+i] = i + 1; - } - expect(validator_recv_frame, - when(size, is_equal_to(515)), - when(data, is_equal_to_contents_of(expected, 510)) - ); - byte_stuffer_recv_byte(0, 0xFF); - for (i=0;i<254;i++) { - byte_stuffer_recv_byte(0, i+1); - } - byte_stuffer_recv_byte(0, 0xFF); - for (i=0;i<254;i++) { - byte_stuffer_recv_byte(0, i+1); - } - byte_stuffer_recv_byte(0, 8); - byte_stuffer_recv_byte(0, 1); - byte_stuffer_recv_byte(0, 2); - byte_stuffer_recv_byte(0, 3); - byte_stuffer_recv_byte(0, 4); - byte_stuffer_recv_byte(0, 5); - byte_stuffer_recv_byte(0, 6); - byte_stuffer_recv_byte(0, 7); - byte_stuffer_recv_byte(0, 0); -} - -Ensure(ByteStuffer, receives_an_all_zeros_frame_that_is_maximum_size) { - uint8_t expected[MAX_FRAME_SIZE] = {}; - expect(validator_recv_frame, - when(size, is_equal_to(MAX_FRAME_SIZE)), - when(data, is_equal_to_contents_of(expected, MAX_FRAME_SIZE)) - ); - int i; - byte_stuffer_recv_byte(0, 1); - for(i=0;i +#include +extern "C" { +#include "serial_link/protocol/byte_stuffer.h" +#include "serial_link/protocol/frame_validator.h" +#include "serial_link/protocol/physical.h" +} + +using testing::_; +using testing::ElementsAreArray; +using testing::Args; + +class ByteStuffer : public ::testing::Test{ +public: + ByteStuffer() { + Instance = this; + init_byte_stuffer(); + } + + ~ByteStuffer() { + Instance = nullptr; + } + + MOCK_METHOD3(validator_recv_frame, void (uint8_t link, uint8_t* data, uint16_t size)); + + void send_data(uint8_t link, const uint8_t* data, uint16_t size) { + std::copy(data, data + size, std::back_inserter(sent_data)); + } + std::vector sent_data; + + static ByteStuffer* Instance; +}; + +ByteStuffer* ByteStuffer::Instance = nullptr; + +extern "C" { + void validator_recv_frame(uint8_t link, uint8_t* data, uint16_t size) { + ByteStuffer::Instance->validator_recv_frame(link, data, size); + } + + void send_data(uint8_t link, const uint8_t* data, uint16_t size) { + ByteStuffer::Instance->send_data(link, data, size); + } +} + +TEST_F(ByteStuffer, receives_no_frame_for_a_single_zero_byte) { + EXPECT_CALL(*this, validator_recv_frame(_, _, _)) + .Times(0); + byte_stuffer_recv_byte(0, 0); +} + +TEST_F(ByteStuffer, receives_no_frame_for_a_single_FF_byte) { + EXPECT_CALL(*this, validator_recv_frame(_, _, _)) + .Times(0); + byte_stuffer_recv_byte(0, 0xFF); +} + +TEST_F(ByteStuffer, receives_no_frame_for_a_single_random_byte) { + EXPECT_CALL(*this, validator_recv_frame(_, _, _)) + .Times(0); + byte_stuffer_recv_byte(0, 0x4A); +} + +TEST_F(ByteStuffer, receives_no_frame_for_a_zero_length_frame) { + EXPECT_CALL(*this, validator_recv_frame(_, _, _)) + .Times(0); + byte_stuffer_recv_byte(0, 1); + byte_stuffer_recv_byte(0, 0); +} + +TEST_F(ByteStuffer, receives_single_byte_valid_frame) { + uint8_t expected[] = {0x37}; + EXPECT_CALL(*this, validator_recv_frame(_, _, _)) + .With(Args<1, 2>(ElementsAreArray(expected))); + byte_stuffer_recv_byte(0, 2); + byte_stuffer_recv_byte(0, 0x37); + byte_stuffer_recv_byte(0, 0); +} +TEST_F(ByteStuffer, receives_three_bytes_valid_frame) { + uint8_t expected[] = {0x37, 0x99, 0xFF}; + EXPECT_CALL(*this, validator_recv_frame(_, _, _)) + .With(Args<1, 2>(ElementsAreArray(expected))); + byte_stuffer_recv_byte(0, 4); + byte_stuffer_recv_byte(0, 0x37); + byte_stuffer_recv_byte(0, 0x99); + byte_stuffer_recv_byte(0, 0xFF); + byte_stuffer_recv_byte(0, 0); +} + +TEST_F(ByteStuffer, receives_single_zero_valid_frame) { + uint8_t expected[] = {0}; + EXPECT_CALL(*this, validator_recv_frame(_, _, _)) + .With(Args<1, 2>(ElementsAreArray(expected))); + byte_stuffer_recv_byte(0, 1); + byte_stuffer_recv_byte(0, 1); + byte_stuffer_recv_byte(0, 0); +} + +TEST_F(ByteStuffer, receives_valid_frame_with_zeroes) { + uint8_t expected[] = {5, 0, 3, 0}; + EXPECT_CALL(*this, validator_recv_frame(_, _, _)) + .With(Args<1, 2>(ElementsAreArray(expected))); + byte_stuffer_recv_byte(0, 2); + byte_stuffer_recv_byte(0, 5); + byte_stuffer_recv_byte(0, 2); + byte_stuffer_recv_byte(0, 3); + byte_stuffer_recv_byte(0, 1); + byte_stuffer_recv_byte(0, 0); +} + + +TEST_F(ByteStuffer, receives_two_valid_frames) { + uint8_t expected1[] = {5, 0}; + uint8_t expected2[] = {3}; + EXPECT_CALL(*this, validator_recv_frame(_, _, _)) + .With(Args<1, 2>(ElementsAreArray(expected1))); + EXPECT_CALL(*this, validator_recv_frame(_, _, _)) + .With(Args<1, 2>(ElementsAreArray(expected2))); + byte_stuffer_recv_byte(1, 2); + byte_stuffer_recv_byte(1, 5); + byte_stuffer_recv_byte(1, 1); + byte_stuffer_recv_byte(1, 0); + byte_stuffer_recv_byte(1, 2); + byte_stuffer_recv_byte(1, 3); + byte_stuffer_recv_byte(1, 0); +} + +TEST_F(ByteStuffer, receives_valid_frame_after_unexpected_zero) { + uint8_t expected[] = {5, 7}; + EXPECT_CALL(*this, validator_recv_frame(_, _, _)) + .With(Args<1, 2>(ElementsAreArray(expected))); + byte_stuffer_recv_byte(1, 3); + byte_stuffer_recv_byte(1, 1); + byte_stuffer_recv_byte(1, 0); + byte_stuffer_recv_byte(1, 3); + byte_stuffer_recv_byte(1, 5); + byte_stuffer_recv_byte(1, 7); + byte_stuffer_recv_byte(1, 0); +} + +TEST_F(ByteStuffer, receives_valid_frame_after_unexpected_non_zero) { + uint8_t expected[] = {5, 7}; + EXPECT_CALL(*this, validator_recv_frame(_, _, _)) + .With(Args<1, 2>(ElementsAreArray(expected))); + byte_stuffer_recv_byte(0, 2); + byte_stuffer_recv_byte(0, 9); + byte_stuffer_recv_byte(0, 4); // This should have been zero + byte_stuffer_recv_byte(0, 0); + byte_stuffer_recv_byte(0, 3); + byte_stuffer_recv_byte(0, 5); + byte_stuffer_recv_byte(0, 7); + byte_stuffer_recv_byte(0, 0); +} + +TEST_F(ByteStuffer, receives_a_valid_frame_with_over254_non_zeroes_and_then_end_of_frame) { + uint8_t expected[254]; + int i; + for (i=0;i<254;i++) { + expected[i] = i + 1; + } + EXPECT_CALL(*this, validator_recv_frame(_, _, _)) + .With(Args<1, 2>(ElementsAreArray(expected))); + byte_stuffer_recv_byte(0, 0xFF); + for (i=0;i<254;i++) { + byte_stuffer_recv_byte(0, i+1); + } + byte_stuffer_recv_byte(0, 0); +} + +TEST_F(ByteStuffer, receives_a_valid_frame_with_over254_non_zeroes_next_byte_is_non_zero) { + uint8_t expected[255]; + int i; + for (i=0;i<254;i++) { + expected[i] = i + 1; + } + expected[254] = 7; + EXPECT_CALL(*this, validator_recv_frame(_, _, _)) + .With(Args<1, 2>(ElementsAreArray(expected))); + byte_stuffer_recv_byte(0, 0xFF); + for (i=0;i<254;i++) { + byte_stuffer_recv_byte(0, i+1); + } + byte_stuffer_recv_byte(0, 2); + byte_stuffer_recv_byte(0, 7); + byte_stuffer_recv_byte(0, 0); +} + +TEST_F(ByteStuffer, receives_a_valid_frame_with_over254_non_zeroes_next_byte_is_zero) { + uint8_t expected[255]; + int i; + for (i=0;i<254;i++) { + expected[i] = i + 1; + } + expected[254] = 0; + EXPECT_CALL(*this, validator_recv_frame(_, _, _)) + .With(Args<1, 2>(ElementsAreArray(expected))); + byte_stuffer_recv_byte(0, 0xFF); + for (i=0;i<254;i++) { + byte_stuffer_recv_byte(0, i+1); + } + byte_stuffer_recv_byte(0, 1); + byte_stuffer_recv_byte(0, 1); + byte_stuffer_recv_byte(0, 0); +} + +TEST_F(ByteStuffer, receives_two_long_frames_and_some_more) { + uint8_t expected[515]; + int i; + int j; + for (j=0;j<2;j++) { + for (i=0;i<254;i++) { + expected[i+254*j] = i + 1; + } + } + for (i=0;i<7;i++) { + expected[254*2+i] = i + 1; + } + EXPECT_CALL(*this, validator_recv_frame(_, _, _)) + .With(Args<1, 2>(ElementsAreArray(expected))); + byte_stuffer_recv_byte(0, 0xFF); + for (i=0;i<254;i++) { + byte_stuffer_recv_byte(0, i+1); + } + byte_stuffer_recv_byte(0, 0xFF); + for (i=0;i<254;i++) { + byte_stuffer_recv_byte(0, i+1); + } + byte_stuffer_recv_byte(0, 8); + byte_stuffer_recv_byte(0, 1); + byte_stuffer_recv_byte(0, 2); + byte_stuffer_recv_byte(0, 3); + byte_stuffer_recv_byte(0, 4); + byte_stuffer_recv_byte(0, 5); + byte_stuffer_recv_byte(0, 6); + byte_stuffer_recv_byte(0, 7); + byte_stuffer_recv_byte(0, 0); +} + +TEST_F(ByteStuffer, receives_an_all_zeros_frame_that_is_maximum_size) { + uint8_t expected[MAX_FRAME_SIZE] = {}; + EXPECT_CALL(*this, validator_recv_frame(_, _, _)) + .With(Args<1, 2>(ElementsAreArray(expected))); + int i; + byte_stuffer_recv_byte(0, 1); + for(i=0;i(ElementsAreArray(expected))); + int i; + byte_stuffer_recv_byte(0, 1); + for(i=0;i(ElementsAreArray(original_data))); + int i; + for(auto& d : sent_data) { + byte_stuffer_recv_byte(1, d); + } +} + +TEST_F(ByteStuffer, sends_and_receives_full_roundtrip_small_packet_with_zeros) { + uint8_t original_data[] = { 1, 0, 3, 0, 0, 9}; + byte_stuffer_send_frame(1, original_data, sizeof(original_data)); + EXPECT_CALL(*this, validator_recv_frame(_, _, _)) + .With(Args<1, 2>(ElementsAreArray(original_data))); + int i; + for(auto& d : sent_data) { + byte_stuffer_recv_byte(1, d); + } +} + +TEST_F(ByteStuffer, sends_and_receives_full_roundtrip_254_bytes) { + uint8_t original_data[254]; + int i; + for(i=0;i<254;i++) { + original_data[i] = i + 1; + } + byte_stuffer_send_frame(0, original_data, sizeof(original_data)); + EXPECT_CALL(*this, validator_recv_frame(_, _, _)) + .With(Args<1, 2>(ElementsAreArray(original_data))); + for(auto& d : sent_data) { + byte_stuffer_recv_byte(1, d); + } +} + +TEST_F(ByteStuffer, sends_and_receives_full_roundtrip_256_bytes) { + uint8_t original_data[256]; + int i; + for(i=0;i<254;i++) { + original_data[i] = i + 1; + } + original_data[254] = 22; + original_data[255] = 23; + byte_stuffer_send_frame(0, original_data, sizeof(original_data)); + EXPECT_CALL(*this, validator_recv_frame(_, _, _)) + .With(Args<1, 2>(ElementsAreArray(original_data))); + for(auto& d : sent_data) { + byte_stuffer_recv_byte(1, d); + } +} + +TEST_F(ByteStuffer, sends_and_receives_full_roundtrip_254_bytes_and_then_zero) { + uint8_t original_data[255]; + int i; + for(i=0;i<254;i++) { + original_data[i] = i + 1; + } + original_data[254] = 0; + byte_stuffer_send_frame(0, original_data, sizeof(original_data)); + EXPECT_CALL(*this, validator_recv_frame(_, _, _)) + .With(Args<1, 2>(ElementsAreArray(original_data))); + for(auto& d : sent_data) { + byte_stuffer_recv_byte(1, d); + } +} diff --git a/quantum/serial_link/tests/rules.mk b/quantum/serial_link/tests/rules.mk new file mode 100644 index 000000000..651f56b95 --- /dev/null +++ b/quantum/serial_link/tests/rules.mk @@ -0,0 +1,3 @@ +serial_link_byte_stuffer_SRC :=\ + $(SERIAL_PATH)/tests/byte_stuffer_tests.cpp \ + $(SERIAL_PATH)/protocol/byte_stuffer.c \ No newline at end of file -- cgit v1.2.3-24-g4f1b From cdd0913bcc63334fa20f1a7bd46bdce4d4f2843b Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Sat, 27 Aug 2016 13:43:46 +0300 Subject: Convert frame_router_tests to GTest --- quantum/serial_link/tests/frame_router_tests.c | 231 ----------------------- quantum/serial_link/tests/frame_router_tests.cpp | 229 ++++++++++++++++++++++ quantum/serial_link/tests/rules.mk | 8 +- 3 files changed, 236 insertions(+), 232 deletions(-) delete mode 100644 quantum/serial_link/tests/frame_router_tests.c create mode 100644 quantum/serial_link/tests/frame_router_tests.cpp (limited to 'quantum') diff --git a/quantum/serial_link/tests/frame_router_tests.c b/quantum/serial_link/tests/frame_router_tests.c deleted file mode 100644 index 6c806fa93..000000000 --- a/quantum/serial_link/tests/frame_router_tests.c +++ /dev/null @@ -1,231 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include -#include -#include "serial_link/protocol/byte_stuffer.c" -#include "serial_link/protocol/frame_validator.c" -#include "serial_link/protocol/frame_router.c" -#include "serial_link/protocol/transport.h" - -static uint8_t received_data[256]; -static uint16_t received_data_size; - -typedef struct { - uint8_t sent_data[256]; - uint16_t sent_data_size; -} receive_buffer_t; - -typedef struct { - receive_buffer_t send_buffers[2]; -} router_buffer_t; - -router_buffer_t router_buffers[8]; - -router_buffer_t* current_router_buffer; - - -Describe(FrameRouter); -BeforeEach(FrameRouter) { - init_byte_stuffer(); - memset(router_buffers, 0, sizeof(router_buffers)); - current_router_buffer = 0; -} -AfterEach(FrameRouter) {} - -typedef struct { - uint32_t data; - uint8_t extra[16]; -} frame_buffer_t; - - -void send_data(uint8_t link, const uint8_t* data, uint16_t size) { - receive_buffer_t* buffer = ¤t_router_buffer->send_buffers[link]; - memcpy(buffer->sent_data + buffer->sent_data_size, data, size); - buffer->sent_data_size += size; -} - -static void receive_data(uint8_t link, uint8_t* data, uint16_t size) { - int i; - for(i=0;i to) { - receive_data(DOWN_LINK, - router_buffers[from].send_buffers[UP_LINK].sent_data, - router_buffers[from].send_buffers[UP_LINK].sent_data_size); - } - else if(to > from) { - receive_data(UP_LINK, - router_buffers[from].send_buffers[DOWN_LINK].sent_data, - router_buffers[from].send_buffers[DOWN_LINK].sent_data_size); - } -} - -void transport_recv_frame(uint8_t from, uint8_t* data, uint16_t size) { - mock(from, data, size); -} - - -Ensure(FrameRouter, master_broadcast_is_received_by_everyone) { - frame_buffer_t data; - data.data = 0xAB7055BB; - activate_router(0); - router_send_frame(0xFF, (uint8_t*)&data, 4); - assert_that(router_buffers[0].send_buffers[DOWN_LINK].sent_data_size, is_greater_than(0)); - assert_that(router_buffers[0].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); - - expect(transport_recv_frame, - when(from, is_equal_to(0)), - when(size, is_equal_to(4)), - when(data, is_equal_to_contents_of(&data.data, 4)) - ); - simulate_transport(0, 1); - assert_that(router_buffers[1].send_buffers[DOWN_LINK].sent_data_size, is_greater_than(0)); - assert_that(router_buffers[1].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); - - expect(transport_recv_frame, - when(from, is_equal_to(0)), - when(size, is_equal_to(4)), - when(data, is_equal_to_contents_of(&data.data, 4)) - ); - simulate_transport(1, 2); - assert_that(router_buffers[2].send_buffers[DOWN_LINK].sent_data_size, is_greater_than(0)); - assert_that(router_buffers[2].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); -} - -Ensure(FrameRouter, master_send_is_received_by_targets) { - frame_buffer_t data; - data.data = 0xAB7055BB; - activate_router(0); - router_send_frame((1 << 1) | (1 << 2), (uint8_t*)&data, 4); - assert_that(router_buffers[0].send_buffers[DOWN_LINK].sent_data_size, is_greater_than(0)); - assert_that(router_buffers[0].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); - - simulate_transport(0, 1); - assert_that(router_buffers[1].send_buffers[DOWN_LINK].sent_data_size, is_greater_than(0)); - assert_that(router_buffers[1].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); - - expect(transport_recv_frame, - when(from, is_equal_to(0)), - when(size, is_equal_to(4)), - when(data, is_equal_to_contents_of(&data.data, 4)) - ); - simulate_transport(1, 2); - assert_that(router_buffers[2].send_buffers[DOWN_LINK].sent_data_size, is_greater_than(0)); - assert_that(router_buffers[2].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); - - expect(transport_recv_frame, - when(from, is_equal_to(0)), - when(size, is_equal_to(4)), - when(data, is_equal_to_contents_of(&data.data, 4)) - ); - simulate_transport(2, 3); - assert_that(router_buffers[3].send_buffers[DOWN_LINK].sent_data_size, is_greater_than(0)); - assert_that(router_buffers[3].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); -} - -Ensure(FrameRouter, first_link_sends_to_master) { - frame_buffer_t data; - data.data = 0xAB7055BB; - activate_router(1); - router_send_frame(0, (uint8_t*)&data, 4); - assert_that(router_buffers[1].send_buffers[UP_LINK].sent_data_size, is_greater_than(0)); - assert_that(router_buffers[1].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0)); - - expect(transport_recv_frame, - when(from, is_equal_to(1)), - when(size, is_equal_to(4)), - when(data, is_equal_to_contents_of(&data.data, 4)) - ); - simulate_transport(1, 0); - assert_that(router_buffers[0].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0)); - assert_that(router_buffers[0].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); -} - -Ensure(FrameRouter, second_link_sends_to_master) { - frame_buffer_t data; - data.data = 0xAB7055BB; - activate_router(2); - router_send_frame(0, (uint8_t*)&data, 4); - assert_that(router_buffers[2].send_buffers[UP_LINK].sent_data_size, is_greater_than(0)); - assert_that(router_buffers[2].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0)); - - simulate_transport(2, 1); - assert_that(router_buffers[1].send_buffers[UP_LINK].sent_data_size, is_greater_than(0)); - assert_that(router_buffers[1].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0)); - - expect(transport_recv_frame, - when(from, is_equal_to(2)), - when(size, is_equal_to(4)), - when(data, is_equal_to_contents_of(&data.data, 4)) - ); - simulate_transport(1, 0); - assert_that(router_buffers[0].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0)); - assert_that(router_buffers[0].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); -} - -Ensure(FrameRouter, master_sends_to_master_does_nothing) { - frame_buffer_t data; - data.data = 0xAB7055BB; - activate_router(0); - router_send_frame(0, (uint8_t*)&data, 4); - assert_that(router_buffers[0].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); - assert_that(router_buffers[0].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0)); -} - -Ensure(FrameRouter, link_sends_to_other_link_does_nothing) { - frame_buffer_t data; - data.data = 0xAB7055BB; - activate_router(1); - router_send_frame(2, (uint8_t*)&data, 4); - assert_that(router_buffers[1].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); - assert_that(router_buffers[1].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0)); -} - -Ensure(FrameRouter, master_receives_on_uplink_does_nothing) { - frame_buffer_t data; - data.data = 0xAB7055BB; - activate_router(1); - router_send_frame(0, (uint8_t*)&data, 4); - assert_that(router_buffers[1].send_buffers[UP_LINK].sent_data_size, is_greater_than(0)); - assert_that(router_buffers[1].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0)); - - never_expect(transport_recv_frame); - activate_router(0); - receive_data(UP_LINK, - router_buffers[1].send_buffers[UP_LINK].sent_data, - router_buffers[1].send_buffers[UP_LINK].sent_data_size); - assert_that(router_buffers[0].send_buffers[UP_LINK].sent_data_size, is_equal_to(0)); - assert_that(router_buffers[0].send_buffers[DOWN_LINK].sent_data_size, is_equal_to(0)); -} diff --git a/quantum/serial_link/tests/frame_router_tests.cpp b/quantum/serial_link/tests/frame_router_tests.cpp new file mode 100644 index 000000000..2bd5bf830 --- /dev/null +++ b/quantum/serial_link/tests/frame_router_tests.cpp @@ -0,0 +1,229 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016 Fred Sundvik + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include "gtest/gtest.h" +#include "gmock/gmock.h" +#include +extern "C" { + #include "serial_link/protocol/transport.h" + #include "serial_link/protocol/byte_stuffer.h" + #include "serial_link/protocol/frame_router.h" +} + +using testing::_; +using testing::ElementsAreArray; +using testing::Args; + +class FrameRouter : public testing::Test { +public: + FrameRouter() : + current_router_buffer(nullptr) + { + Instance = this; + init_byte_stuffer(); + } + + ~FrameRouter() { + Instance = nullptr; + } + + void send_data(uint8_t link, const uint8_t* data, uint16_t size) { + auto& buffer = current_router_buffer->send_buffers[link]; + std::copy(data, data + size, std::back_inserter(buffer)); + } + + void receive_data(uint8_t link, uint8_t* data, uint16_t size) { + int i; + for(i=0;i to) { + receive_data(DOWN_LINK, + router_buffers[from].send_buffers[UP_LINK].data(), + router_buffers[from].send_buffers[UP_LINK].size()); + } + else if(to > from) { + receive_data(UP_LINK, + router_buffers[from].send_buffers[DOWN_LINK].data(), + router_buffers[from].send_buffers[DOWN_LINK].size()); + } + } + + MOCK_METHOD3(transport_recv_frame, void (uint8_t from, uint8_t* data, uint16_t size)); + + std::vector received_data; + + struct router_buffer { + std::vector send_buffers[2]; + }; + + router_buffer router_buffers[8]; + router_buffer* current_router_buffer; + + static FrameRouter* Instance; +}; + +FrameRouter* FrameRouter::Instance = nullptr; + + +typedef struct { + std::array data; + uint8_t extra[16]; +} frame_buffer_t; + + +extern "C" { + void send_data(uint8_t link, const uint8_t* data, uint16_t size) { + FrameRouter::Instance->send_data(link, data, size); + } + + + void transport_recv_frame(uint8_t from, uint8_t* data, uint16_t size) { + FrameRouter::Instance->transport_recv_frame(from, data, size); + } +} + +TEST_F(FrameRouter, master_broadcast_is_received_by_everyone) { + frame_buffer_t data; + data.data = {0xAB, 0x70, 0x55, 0xBB}; + activate_router(0); + router_send_frame(0xFF, (uint8_t*)&data, 4); + EXPECT_GT(router_buffers[0].send_buffers[DOWN_LINK].size(), 0); + EXPECT_EQ(router_buffers[0].send_buffers[UP_LINK].size(), 0); + EXPECT_CALL(*this, transport_recv_frame(0, _, _)) + .With(Args<1, 2>(ElementsAreArray(data.data))); + simulate_transport(0, 1); + EXPECT_GT(router_buffers[1].send_buffers[DOWN_LINK].size(), 0); + EXPECT_EQ(router_buffers[1].send_buffers[UP_LINK].size(), 0); + + EXPECT_CALL(*this, transport_recv_frame(0, _, _)) + .With(Args<1, 2>(ElementsAreArray(data.data))); + simulate_transport(1, 2); + EXPECT_GT(router_buffers[2].send_buffers[DOWN_LINK].size(), 0); + EXPECT_EQ(router_buffers[2].send_buffers[UP_LINK].size(), 0); +} + +TEST_F(FrameRouter, master_send_is_received_by_targets) { + frame_buffer_t data; + data.data = {0xAB, 0x70, 0x55, 0xBB}; + activate_router(0); + router_send_frame((1 << 1) | (1 << 2), (uint8_t*)&data, 4); + EXPECT_GT(router_buffers[0].send_buffers[DOWN_LINK].size(), 0); + EXPECT_EQ(router_buffers[0].send_buffers[UP_LINK].size(), 0); + + simulate_transport(0, 1); + EXPECT_GT(router_buffers[1].send_buffers[DOWN_LINK].size(), 0); + EXPECT_EQ(router_buffers[1].send_buffers[UP_LINK].size(), 0); + + EXPECT_CALL(*this, transport_recv_frame(0, _, _)) + .With(Args<1, 2>(ElementsAreArray(data.data))); + simulate_transport(1, 2); + EXPECT_GT(router_buffers[2].send_buffers[DOWN_LINK].size(), 0); + EXPECT_EQ(router_buffers[2].send_buffers[UP_LINK].size(), 0); + + EXPECT_CALL(*this, transport_recv_frame(0, _, _)) + .With(Args<1, 2>(ElementsAreArray(data.data))); + simulate_transport(2, 3); + EXPECT_GT(router_buffers[3].send_buffers[DOWN_LINK].size(), 0); + EXPECT_EQ(router_buffers[3].send_buffers[UP_LINK].size(), 0); +} + +TEST_F(FrameRouter, first_link_sends_to_master) { + frame_buffer_t data; + data.data = {0xAB, 0x70, 0x55, 0xBB}; + activate_router(1); + router_send_frame(0, (uint8_t*)&data, 4); + EXPECT_GT(router_buffers[1].send_buffers[UP_LINK].size(), 0); + EXPECT_EQ(router_buffers[1].send_buffers[DOWN_LINK].size(), 0); + + EXPECT_CALL(*this, transport_recv_frame(1, _, _)) + .With(Args<1, 2>(ElementsAreArray(data.data))); + simulate_transport(1, 0); + EXPECT_EQ(router_buffers[0].send_buffers[DOWN_LINK].size(), 0); + EXPECT_EQ(router_buffers[0].send_buffers[UP_LINK].size(), 0); +} + +TEST_F(FrameRouter, second_link_sends_to_master) { + frame_buffer_t data; + data.data = {0xAB, 0x70, 0x55, 0xBB}; + activate_router(2); + router_send_frame(0, (uint8_t*)&data, 4); + EXPECT_GT(router_buffers[2].send_buffers[UP_LINK].size(), 0); + EXPECT_EQ(router_buffers[2].send_buffers[DOWN_LINK].size(), 0); + + simulate_transport(2, 1); + EXPECT_GT(router_buffers[1].send_buffers[UP_LINK].size(), 0); + EXPECT_EQ(router_buffers[1].send_buffers[DOWN_LINK].size(), 0); + + EXPECT_CALL(*this, transport_recv_frame(2, _, _)) + .With(Args<1, 2>(ElementsAreArray(data.data))); + simulate_transport(1, 0); + EXPECT_EQ(router_buffers[0].send_buffers[DOWN_LINK].size(), 0); + EXPECT_EQ(router_buffers[0].send_buffers[UP_LINK].size(), 0); +} + +TEST_F(FrameRouter, master_sends_to_master_does_nothing) { + frame_buffer_t data; + data.data = {0xAB, 0x70, 0x55, 0xBB}; + activate_router(0); + router_send_frame(0, (uint8_t*)&data, 4); + EXPECT_EQ(router_buffers[0].send_buffers[UP_LINK].size(), 0); + EXPECT_EQ(router_buffers[0].send_buffers[DOWN_LINK].size(), 0); +} + +TEST_F(FrameRouter, link_sends_to_other_link_does_nothing) { + frame_buffer_t data; + data.data = {0xAB, 0x70, 0x55, 0xBB}; + activate_router(1); + router_send_frame(2, (uint8_t*)&data, 4); + EXPECT_EQ(router_buffers[1].send_buffers[UP_LINK].size(), 0); + EXPECT_EQ(router_buffers[1].send_buffers[DOWN_LINK].size(), 0); +} + +TEST_F(FrameRouter, master_receives_on_uplink_does_nothing) { + frame_buffer_t data; + data.data = {0xAB, 0x70, 0x55, 0xBB}; + activate_router(1); + router_send_frame(0, (uint8_t*)&data, 4); + EXPECT_GT(router_buffers[1].send_buffers[UP_LINK].size(), 0); + EXPECT_EQ(router_buffers[1].send_buffers[DOWN_LINK].size(), 0); + + EXPECT_CALL(*this, transport_recv_frame(_, _, _)) + .Times(0); + activate_router(0); + receive_data(UP_LINK, + router_buffers[1].send_buffers[UP_LINK].data(), + router_buffers[1].send_buffers[UP_LINK].size()); + EXPECT_EQ(router_buffers[0].send_buffers[UP_LINK].size(), 0); + EXPECT_EQ(router_buffers[0].send_buffers[DOWN_LINK].size(), 0); +} diff --git a/quantum/serial_link/tests/rules.mk b/quantum/serial_link/tests/rules.mk index 651f56b95..7d0d6c0d0 100644 --- a/quantum/serial_link/tests/rules.mk +++ b/quantum/serial_link/tests/rules.mk @@ -1,3 +1,9 @@ serial_link_byte_stuffer_SRC :=\ $(SERIAL_PATH)/tests/byte_stuffer_tests.cpp \ - $(SERIAL_PATH)/protocol/byte_stuffer.c \ No newline at end of file + $(SERIAL_PATH)/protocol/byte_stuffer.c + +serial_link_frame_router_SRC := \ + $(SERIAL_PATH)/tests/frame_router_tests.cpp \ + $(SERIAL_PATH)/protocol/byte_stuffer.c \ + $(SERIAL_PATH)/protocol/frame_validator.c \ + $(SERIAL_PATH)/protocol/frame_router.c \ No newline at end of file -- cgit v1.2.3-24-g4f1b From b3eba797af74ace19b9f2e762bdd33d9449e3f94 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Sat, 27 Aug 2016 13:54:16 +0300 Subject: Convert frame_validator_tests to GTest --- quantum/serial_link/tests/frame_validator_tests.c | 101 ------------------ .../serial_link/tests/frame_validator_tests.cpp | 115 +++++++++++++++++++++ quantum/serial_link/tests/rules.mk | 8 +- 3 files changed, 121 insertions(+), 103 deletions(-) delete mode 100644 quantum/serial_link/tests/frame_validator_tests.c create mode 100644 quantum/serial_link/tests/frame_validator_tests.cpp (limited to 'quantum') diff --git a/quantum/serial_link/tests/frame_validator_tests.c b/quantum/serial_link/tests/frame_validator_tests.c deleted file mode 100644 index d20947e2c..000000000 --- a/quantum/serial_link/tests/frame_validator_tests.c +++ /dev/null @@ -1,101 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include -#include -#include "serial_link/protocol/frame_validator.c" - -void route_incoming_frame(uint8_t link, uint8_t* data, uint16_t size) { - mock(data, size); -} - -void byte_stuffer_send_frame(uint8_t link, uint8_t* data, uint16_t size) { - mock(data, size); -} - -Describe(FrameValidator); -BeforeEach(FrameValidator) {} -AfterEach(FrameValidator) {} - -Ensure(FrameValidator, doesnt_validate_frames_under_5_bytes) { - never_expect(route_incoming_frame); - uint8_t data[] = {1, 2}; - validator_recv_frame(0, 0, 1); - validator_recv_frame(0, data, 2); - validator_recv_frame(0, data, 3); - validator_recv_frame(0, data, 4); -} - -Ensure(FrameValidator, validates_one_byte_frame_with_correct_crc) { - uint8_t data[] = {0x44, 0x04, 0x6A, 0xB3, 0xA3}; - expect(route_incoming_frame, - when(size, is_equal_to(1)), - when(data, is_equal_to_contents_of(data, 1)) - ); - validator_recv_frame(0, data, 5); -} - -Ensure(FrameValidator, does_not_validate_one_byte_frame_with_incorrect_crc) { - uint8_t data[] = {0x44, 0, 0, 0, 0}; - never_expect(route_incoming_frame); - validator_recv_frame(1, data, 5); -} - -Ensure(FrameValidator, validates_four_byte_frame_with_correct_crc) { - uint8_t data[] = {0x44, 0x10, 0xFF, 0x00, 0x74, 0x4E, 0x30, 0xBA}; - expect(route_incoming_frame, - when(size, is_equal_to(4)), - when(data, is_equal_to_contents_of(data, 4)) - ); - validator_recv_frame(1, data, 8); -} - -Ensure(FrameValidator, validates_five_byte_frame_with_correct_crc) { - uint8_t data[] = {1, 2, 3, 4, 5, 0xF4, 0x99, 0x0B, 0x47}; - expect(route_incoming_frame, - when(size, is_equal_to(5)), - when(data, is_equal_to_contents_of(data, 5)) - ); - validator_recv_frame(0, data, 9); -} - -Ensure(FrameValidator, sends_one_byte_with_correct_crc) { - uint8_t original[] = {0x44, 0, 0, 0, 0}; - uint8_t expected[] = {0x44, 0x04, 0x6A, 0xB3, 0xA3}; - expect(byte_stuffer_send_frame, - when(size, is_equal_to(sizeof(expected))), - when(data, is_equal_to_contents_of(expected, sizeof(expected))) - ); - validator_send_frame(0, original, 1); -} - -Ensure(FrameValidator, sends_five_bytes_with_correct_crc) { - uint8_t original[] = {1, 2, 3, 4, 5, 0, 0, 0, 0}; - uint8_t expected[] = {1, 2, 3, 4, 5, 0xF4, 0x99, 0x0B, 0x47}; - expect(byte_stuffer_send_frame, - when(size, is_equal_to(sizeof(expected))), - when(data, is_equal_to_contents_of(expected, sizeof(expected))) - ); - validator_send_frame(0, original, 5); -} diff --git a/quantum/serial_link/tests/frame_validator_tests.cpp b/quantum/serial_link/tests/frame_validator_tests.cpp new file mode 100644 index 000000000..9223af83b --- /dev/null +++ b/quantum/serial_link/tests/frame_validator_tests.cpp @@ -0,0 +1,115 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016 Fred Sundvik + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include "gtest/gtest.h" +#include "gmock/gmock.h" +extern "C" { +#include "serial_link/protocol/frame_validator.h" +} + +using testing::_; +using testing::ElementsAreArray; +using testing::Args; + +class FrameValidator : public testing::Test { +public: + FrameValidator() { + Instance = this; + } + + ~FrameValidator() { + Instance = nullptr; + } + + MOCK_METHOD3(route_incoming_frame, void (uint8_t link, uint8_t* data, uint16_t size)); + MOCK_METHOD3(byte_stuffer_send_frame, void (uint8_t link, uint8_t* data, uint16_t size)); + + static FrameValidator* Instance; +}; + +FrameValidator* FrameValidator::Instance = nullptr; + +extern "C" { +void route_incoming_frame(uint8_t link, uint8_t* data, uint16_t size) { + FrameValidator::Instance->route_incoming_frame(link, data, size); +} + +void byte_stuffer_send_frame(uint8_t link, uint8_t* data, uint16_t size) { + FrameValidator::Instance->byte_stuffer_send_frame(link, data, size); +} +} + +TEST_F(FrameValidator, doesnt_validate_frames_under_5_bytes) { + EXPECT_CALL(*this, route_incoming_frame(_, _, _)) + .Times(0); + uint8_t data[] = {1, 2}; + validator_recv_frame(0, 0, 1); + validator_recv_frame(0, data, 2); + validator_recv_frame(0, data, 3); + validator_recv_frame(0, data, 4); +} + +TEST_F(FrameValidator, validates_one_byte_frame_with_correct_crc) { + uint8_t data[] = {0x44, 0x04, 0x6A, 0xB3, 0xA3}; + EXPECT_CALL(*this, route_incoming_frame(_, _, _)) + .With(Args<1, 2>(ElementsAreArray(data, 1))); + validator_recv_frame(0, data, 5); +} + +TEST_F(FrameValidator, does_not_validate_one_byte_frame_with_incorrect_crc) { + uint8_t data[] = {0x44, 0, 0, 0, 0}; + EXPECT_CALL(*this, route_incoming_frame(_, _, _)) + .Times(0); + validator_recv_frame(1, data, 5); +} + +TEST_F(FrameValidator, validates_four_byte_frame_with_correct_crc) { + uint8_t data[] = {0x44, 0x10, 0xFF, 0x00, 0x74, 0x4E, 0x30, 0xBA}; + EXPECT_CALL(*this, route_incoming_frame(_, _, _)) + .With(Args<1, 2>(ElementsAreArray(data, 4))); + validator_recv_frame(1, data, 8); +} + +TEST_F(FrameValidator, validates_five_byte_frame_with_correct_crc) { + uint8_t data[] = {1, 2, 3, 4, 5, 0xF4, 0x99, 0x0B, 0x47}; + EXPECT_CALL(*this, route_incoming_frame(_, _, _)) + .With(Args<1, 2>(ElementsAreArray(data, 5))); + validator_recv_frame(0, data, 9); +} + +TEST_F(FrameValidator, sends_one_byte_with_correct_crc) { + uint8_t original[] = {0x44, 0, 0, 0, 0}; + uint8_t expected[] = {0x44, 0x04, 0x6A, 0xB3, 0xA3}; + EXPECT_CALL(*this, byte_stuffer_send_frame(_, _, _)) + .With(Args<1, 2>(ElementsAreArray(expected))); + validator_send_frame(0, original, 1); +} + +TEST_F(FrameValidator, sends_five_bytes_with_correct_crc) { + uint8_t original[] = {1, 2, 3, 4, 5, 0, 0, 0, 0}; + uint8_t expected[] = {1, 2, 3, 4, 5, 0xF4, 0x99, 0x0B, 0x47}; + EXPECT_CALL(*this, byte_stuffer_send_frame(_, _, _)) + .With(Args<1, 2>(ElementsAreArray(expected))); + validator_send_frame(0, original, 5); +} diff --git a/quantum/serial_link/tests/rules.mk b/quantum/serial_link/tests/rules.mk index 7d0d6c0d0..7f2a8f457 100644 --- a/quantum/serial_link/tests/rules.mk +++ b/quantum/serial_link/tests/rules.mk @@ -5,5 +5,9 @@ serial_link_byte_stuffer_SRC :=\ serial_link_frame_router_SRC := \ $(SERIAL_PATH)/tests/frame_router_tests.cpp \ $(SERIAL_PATH)/protocol/byte_stuffer.c \ - $(SERIAL_PATH)/protocol/frame_validator.c \ - $(SERIAL_PATH)/protocol/frame_router.c \ No newline at end of file + $(SERIAL_PATH)/protocol/frame_validator.c \ + $(SERIAL_PATH)/protocol/frame_router.c + +serial_link_frame_validator_SRC := \ + $(SERIAL_PATH)/tests/frame_validator_tests.cpp \ + $(SERIAL_PATH)/protocol/frame_validator.c \ No newline at end of file -- cgit v1.2.3-24-g4f1b From bcdf9ab76bf3723e6015d4255d53e7c1e7259b61 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Sat, 27 Aug 2016 14:18:49 +0300 Subject: Convert transport_tests to GTest --- quantum/serial_link/protocol/transport.c | 4 + quantum/serial_link/protocol/transport.h | 7 +- quantum/serial_link/tests/rules.mk | 7 +- quantum/serial_link/tests/transport_tests.c | 168 ----------------------- quantum/serial_link/tests/transport_tests.cpp | 188 ++++++++++++++++++++++++++ 5 files changed, 202 insertions(+), 172 deletions(-) delete mode 100644 quantum/serial_link/tests/transport_tests.c create mode 100644 quantum/serial_link/tests/transport_tests.cpp (limited to 'quantum') diff --git a/quantum/serial_link/protocol/transport.c b/quantum/serial_link/protocol/transport.c index f418d11ce..ff795fe20 100644 --- a/quantum/serial_link/protocol/transport.c +++ b/quantum/serial_link/protocol/transport.c @@ -31,6 +31,10 @@ SOFTWARE. static remote_object_t* remote_objects[MAX_REMOTE_OBJECTS]; static uint32_t num_remote_objects = 0; +void reinitialize_serial_link_transport(void) { + num_remote_objects = 0; +} + void add_remote_objects(remote_object_t** _remote_objects, uint32_t _num_remote_objects) { unsigned int i; for(i=0;i<_num_remote_objects;i++) { diff --git a/quantum/serial_link/protocol/transport.h b/quantum/serial_link/protocol/transport.h index 9a052d880..2c5d890b2 100644 --- a/quantum/serial_link/protocol/transport.h +++ b/quantum/serial_link/protocol/transport.h @@ -82,7 +82,7 @@ typedef struct { \ remote_object_t* obj = (remote_object_t*)&remote_object_##name; \ uint8_t* start = obj->buffer + LOCAL_OBJECT_SIZE(obj->object_size);\ triple_buffer_object_t* tb = (triple_buffer_object_t*)start; \ - return triple_buffer_read_internal(obj->object_size, tb); \ + return (type*)triple_buffer_read_internal(obj->object_size, tb); \ } #define MASTER_TO_SINGLE_SLAVE_OBJECT(name, type) \ @@ -112,7 +112,7 @@ typedef struct { \ remote_object_t* obj = (remote_object_t*)&remote_object_##name; \ uint8_t* start = obj->buffer + NUM_SLAVES * LOCAL_OBJECT_SIZE(obj->object_size);\ triple_buffer_object_t* tb = (triple_buffer_object_t*)start; \ - return triple_buffer_read_internal(obj->object_size, tb); \ + return (type*)triple_buffer_read_internal(obj->object_size, tb); \ } #define SLAVE_TO_MASTER_OBJECT(name, type) \ @@ -139,12 +139,13 @@ typedef struct { \ uint8_t* start = obj->buffer + LOCAL_OBJECT_SIZE(obj->object_size);\ start+=slave * REMOTE_OBJECT_SIZE(obj->object_size); \ triple_buffer_object_t* tb = (triple_buffer_object_t*)start; \ - return triple_buffer_read_internal(obj->object_size, tb); \ + return (type*)triple_buffer_read_internal(obj->object_size, tb); \ } #define REMOTE_OBJECT(name) (remote_object_t*)&remote_object_##name void add_remote_objects(remote_object_t** remote_objects, uint32_t num_remote_objects); +void reinitialize_serial_link_transport(void); void transport_recv_frame(uint8_t from, uint8_t* data, uint16_t size); void update_transport(void); diff --git a/quantum/serial_link/tests/rules.mk b/quantum/serial_link/tests/rules.mk index 7f2a8f457..bf342c9d2 100644 --- a/quantum/serial_link/tests/rules.mk +++ b/quantum/serial_link/tests/rules.mk @@ -10,4 +10,9 @@ serial_link_frame_router_SRC := \ serial_link_frame_validator_SRC := \ $(SERIAL_PATH)/tests/frame_validator_tests.cpp \ - $(SERIAL_PATH)/protocol/frame_validator.c \ No newline at end of file + $(SERIAL_PATH)/protocol/frame_validator.c + +serial_link_transport_SRC := \ + $(SERIAL_PATH)/tests/transport_tests.cpp \ + $(SERIAL_PATH)/protocol/transport.c \ + $(SERIAL_PATH)/protocol/triple_buffered_object.c \ No newline at end of file diff --git a/quantum/serial_link/tests/transport_tests.c b/quantum/serial_link/tests/transport_tests.c deleted file mode 100644 index 358e1b9fd..000000000 --- a/quantum/serial_link/tests/transport_tests.c +++ /dev/null @@ -1,168 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include -#include -#include "serial_link/protocol/transport.c" -#include "serial_link/protocol/triple_buffered_object.c" - -void signal_data_written(void) { - mock(); -} - -static uint8_t sent_data[2048]; -static uint16_t sent_data_size; - -void router_send_frame(uint8_t destination, uint8_t* data, uint16_t size) { - mock(destination); - memcpy(sent_data + sent_data_size, data, size); - sent_data_size += size; -} - -typedef struct { - uint32_t test; -} test_object1_t; - -typedef struct { - uint32_t test1; - uint32_t test2; -} test_object2_t; - -MASTER_TO_ALL_SLAVES_OBJECT(master_to_slave, test_object1_t); -MASTER_TO_SINGLE_SLAVE_OBJECT(master_to_single_slave, test_object1_t); -SLAVE_TO_MASTER_OBJECT(slave_to_master, test_object1_t); - -static remote_object_t* test_remote_objects[] = { - REMOTE_OBJECT(master_to_slave), - REMOTE_OBJECT(master_to_single_slave), - REMOTE_OBJECT(slave_to_master), -}; - -Describe(Transport); -BeforeEach(Transport) { - add_remote_objects(test_remote_objects, sizeof(test_remote_objects) / sizeof(remote_object_t*)); - sent_data_size = 0; -} -AfterEach(Transport) {} - -Ensure(Transport, write_to_local_signals_an_event) { - begin_write_master_to_slave(); - expect(signal_data_written); - end_write_master_to_slave(); - begin_write_slave_to_master(); - expect(signal_data_written); - end_write_slave_to_master(); - begin_write_master_to_single_slave(1); - expect(signal_data_written); - end_write_master_to_single_slave(1); -} - -Ensure(Transport, writes_from_master_to_all_slaves) { - update_transport(); - test_object1_t* obj = begin_write_master_to_slave(); - obj->test = 5; - expect(signal_data_written); - end_write_master_to_slave(); - expect(router_send_frame, - when(destination, is_equal_to(0xFF))); - update_transport(); - transport_recv_frame(0, sent_data, sent_data_size); - test_object1_t* obj2 = read_master_to_slave(); - assert_that(obj2, is_not_equal_to(NULL)); - assert_that(obj2->test, is_equal_to(5)); -} - -Ensure(Transport, writes_from_slave_to_master) { - update_transport(); - test_object1_t* obj = begin_write_slave_to_master(); - obj->test = 7; - expect(signal_data_written); - end_write_slave_to_master(); - expect(router_send_frame, - when(destination, is_equal_to(0))); - update_transport(); - transport_recv_frame(3, sent_data, sent_data_size); - test_object1_t* obj2 = read_slave_to_master(2); - assert_that(read_slave_to_master(0), is_equal_to(NULL)); - assert_that(obj2, is_not_equal_to(NULL)); - assert_that(obj2->test, is_equal_to(7)); -} - -Ensure(Transport, writes_from_master_to_single_slave) { - update_transport(); - test_object1_t* obj = begin_write_master_to_single_slave(3); - obj->test = 7; - expect(signal_data_written); - end_write_master_to_single_slave(3); - expect(router_send_frame, - when(destination, is_equal_to(4))); - update_transport(); - transport_recv_frame(0, sent_data, sent_data_size); - test_object1_t* obj2 = read_master_to_single_slave(); - assert_that(obj2, is_not_equal_to(NULL)); - assert_that(obj2->test, is_equal_to(7)); -} - -Ensure(Transport, ignores_object_with_invalid_id) { - update_transport(); - test_object1_t* obj = begin_write_master_to_single_slave(3); - obj->test = 7; - expect(signal_data_written); - end_write_master_to_single_slave(3); - expect(router_send_frame, - when(destination, is_equal_to(4))); - update_transport(); - sent_data[sent_data_size - 1] = 44; - transport_recv_frame(0, sent_data, sent_data_size); - test_object1_t* obj2 = read_master_to_single_slave(); - assert_that(obj2, is_equal_to(NULL)); -} - -Ensure(Transport, ignores_object_with_size_too_small) { - update_transport(); - test_object1_t* obj = begin_write_master_to_slave(); - obj->test = 7; - expect(signal_data_written); - end_write_master_to_slave(); - expect(router_send_frame); - update_transport(); - sent_data[sent_data_size - 2] = 0; - transport_recv_frame(0, sent_data, sent_data_size - 1); - test_object1_t* obj2 = read_master_to_slave(); - assert_that(obj2, is_equal_to(NULL)); -} - -Ensure(Transport, ignores_object_with_size_too_big) { - update_transport(); - test_object1_t* obj = begin_write_master_to_slave(); - obj->test = 7; - expect(signal_data_written); - end_write_master_to_slave(); - expect(router_send_frame); - update_transport(); - sent_data[sent_data_size + 21] = 0; - transport_recv_frame(0, sent_data, sent_data_size + 22); - test_object1_t* obj2 = read_master_to_slave(); - assert_that(obj2, is_equal_to(NULL)); -} diff --git a/quantum/serial_link/tests/transport_tests.cpp b/quantum/serial_link/tests/transport_tests.cpp new file mode 100644 index 000000000..21b7b165f --- /dev/null +++ b/quantum/serial_link/tests/transport_tests.cpp @@ -0,0 +1,188 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016 Fred Sundvik + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include "gtest/gtest.h" +#include "gmock/gmock.h" + +using testing::_; +using testing::ElementsAreArray; +using testing::Args; + +extern "C" { +#include "serial_link/protocol/transport.h" +} + +struct test_object1 { + uint32_t test; +}; + +struct test_object2 { + uint32_t test1; + uint32_t test2; +}; + +MASTER_TO_ALL_SLAVES_OBJECT(master_to_slave, test_object1); +MASTER_TO_SINGLE_SLAVE_OBJECT(master_to_single_slave, test_object1); +SLAVE_TO_MASTER_OBJECT(slave_to_master, test_object1); + +static remote_object_t* test_remote_objects[] = { + REMOTE_OBJECT(master_to_slave), + REMOTE_OBJECT(master_to_single_slave), + REMOTE_OBJECT(slave_to_master), +}; + +class Transport : public testing::Test { +public: + Transport() { + Instance = this; + add_remote_objects(test_remote_objects, sizeof(test_remote_objects) / sizeof(remote_object_t*)); + } + + ~Transport() { + Instance = nullptr; + reinitialize_serial_link_transport(); + } + + MOCK_METHOD0(signal_data_written, void ()); + MOCK_METHOD1(router_send_frame, void (uint8_t destination)); + + void router_send_frame(uint8_t destination, uint8_t* data, uint16_t size) { + router_send_frame(destination); + std::copy(data, data + size, std::back_inserter(sent_data)); + } + + static Transport* Instance; + + std::vector sent_data; +}; + +Transport* Transport::Instance = nullptr; + +extern "C" { +void signal_data_written(void) { + Transport::Instance->signal_data_written(); +} + +void router_send_frame(uint8_t destination, uint8_t* data, uint16_t size) { + Transport::Instance->router_send_frame(destination, data, size); +} +} + +TEST_F(Transport, write_to_local_signals_an_event) { + begin_write_master_to_slave(); + EXPECT_CALL(*this, signal_data_written()); + end_write_master_to_slave(); + begin_write_slave_to_master(); + EXPECT_CALL(*this, signal_data_written()); + end_write_slave_to_master(); + begin_write_master_to_single_slave(1); + EXPECT_CALL(*this, signal_data_written()); + end_write_master_to_single_slave(1); +} + +TEST_F(Transport, writes_from_master_to_all_slaves) { + update_transport(); + test_object1* obj = begin_write_master_to_slave(); + obj->test = 5; + EXPECT_CALL(*this, signal_data_written()); + end_write_master_to_slave(); + EXPECT_CALL(*this, router_send_frame(0xFF)); + update_transport(); + transport_recv_frame(0, sent_data.data(), sent_data.size()); + test_object1* obj2 = read_master_to_slave(); + EXPECT_NE(obj2, nullptr); + EXPECT_EQ(obj2->test, 5); +} + +TEST_F(Transport, writes_from_slave_to_master) { + update_transport(); + test_object1* obj = begin_write_slave_to_master(); + obj->test = 7; + EXPECT_CALL(*this, signal_data_written()); + end_write_slave_to_master(); + EXPECT_CALL(*this, router_send_frame(0)); + update_transport(); + transport_recv_frame(3, sent_data.data(), sent_data.size()); + test_object1* obj2 = read_slave_to_master(2); + EXPECT_EQ(read_slave_to_master(0), nullptr); + EXPECT_NE(obj2, nullptr); + EXPECT_EQ(obj2->test, 7); +} + +TEST_F(Transport, writes_from_master_to_single_slave) { + update_transport(); + test_object1* obj = begin_write_master_to_single_slave(3); + obj->test = 7; + EXPECT_CALL(*this, signal_data_written()); + end_write_master_to_single_slave(3); + EXPECT_CALL(*this, router_send_frame(4)); + update_transport(); + transport_recv_frame(0, sent_data.data(), sent_data.size()); + test_object1* obj2 = read_master_to_single_slave(); + EXPECT_NE(obj2, nullptr); + EXPECT_EQ(obj2->test, 7); +} + +TEST_F(Transport, ignores_object_with_invalid_id) { + update_transport(); + test_object1* obj = begin_write_master_to_single_slave(3); + obj->test = 7; + EXPECT_CALL(*this, signal_data_written()); + end_write_master_to_single_slave(3); + EXPECT_CALL(*this, router_send_frame(4)); + update_transport(); + sent_data[sent_data.size() - 1] = 44; + transport_recv_frame(0, sent_data.data(), sent_data.size()); + test_object1* obj2 = read_master_to_single_slave(); + EXPECT_EQ(obj2, nullptr); +} + +TEST_F(Transport, ignores_object_with_size_too_small) { + update_transport(); + test_object1* obj = begin_write_master_to_slave(); + obj->test = 7; + EXPECT_CALL(*this, signal_data_written()); + end_write_master_to_slave(); + EXPECT_CALL(*this, router_send_frame(_)); + update_transport(); + sent_data[sent_data.size() - 2] = 0; + transport_recv_frame(0, sent_data.data(), sent_data.size() - 1); + test_object1* obj2 = read_master_to_slave(); + EXPECT_EQ(obj2, nullptr); +} + +TEST_F(Transport, ignores_object_with_size_too_big) { + update_transport(); + test_object1* obj = begin_write_master_to_slave(); + obj->test = 7; + EXPECT_CALL(*this, signal_data_written()); + end_write_master_to_slave(); + EXPECT_CALL(*this, router_send_frame(_)); + update_transport(); + sent_data.resize(sent_data.size() + 22); + sent_data[sent_data.size() - 1] = 0; + transport_recv_frame(0, sent_data.data(), sent_data.size()); + test_object1* obj2 = read_master_to_slave(); + EXPECT_EQ(obj2, nullptr); +} -- cgit v1.2.3-24-g4f1b From ffb0a126f5b2484eda7f6b1c62ea61924eec6521 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Sat, 27 Aug 2016 14:25:52 +0300 Subject: Convert tirple_buffered_object_tests to GTest --- quantum/serial_link/tests/rules.mk | 12 ++-- quantum/serial_link/tests/testlist.mk | 6 +- .../tests/triple_buffered_object_tests.c | 82 --------------------- .../tests/triple_buffered_object_tests.cpp | 84 ++++++++++++++++++++++ 4 files changed, 95 insertions(+), 89 deletions(-) delete mode 100644 quantum/serial_link/tests/triple_buffered_object_tests.c create mode 100644 quantum/serial_link/tests/triple_buffered_object_tests.cpp (limited to 'quantum') diff --git a/quantum/serial_link/tests/rules.mk b/quantum/serial_link/tests/rules.mk index bf342c9d2..b81515bc5 100644 --- a/quantum/serial_link/tests/rules.mk +++ b/quantum/serial_link/tests/rules.mk @@ -2,17 +2,21 @@ serial_link_byte_stuffer_SRC :=\ $(SERIAL_PATH)/tests/byte_stuffer_tests.cpp \ $(SERIAL_PATH)/protocol/byte_stuffer.c +serial_link_frame_validator_SRC := \ + $(SERIAL_PATH)/tests/frame_validator_tests.cpp \ + $(SERIAL_PATH)/protocol/frame_validator.c + serial_link_frame_router_SRC := \ $(SERIAL_PATH)/tests/frame_router_tests.cpp \ $(SERIAL_PATH)/protocol/byte_stuffer.c \ $(SERIAL_PATH)/protocol/frame_validator.c \ $(SERIAL_PATH)/protocol/frame_router.c -serial_link_frame_validator_SRC := \ - $(SERIAL_PATH)/tests/frame_validator_tests.cpp \ - $(SERIAL_PATH)/protocol/frame_validator.c +serial_link_triple_buffered_object_SRC := \ + $(SERIAL_PATH)/tests/triple_buffered_object_tests.cpp \ + $(SERIAL_PATH)/protocol/triple_buffered_object.c serial_link_transport_SRC := \ $(SERIAL_PATH)/tests/transport_tests.cpp \ $(SERIAL_PATH)/protocol/transport.c \ - $(SERIAL_PATH)/protocol/triple_buffered_object.c \ No newline at end of file + $(SERIAL_PATH)/protocol/triple_buffered_object.c diff --git a/quantum/serial_link/tests/testlist.mk b/quantum/serial_link/tests/testlist.mk index 4a734b1e1..a80e88884 100644 --- a/quantum/serial_link/tests/testlist.mk +++ b/quantum/serial_link/tests/testlist.mk @@ -1,6 +1,6 @@ TEST_LIST +=\ serial_link_byte_stuffer\ - serial_link_frame_router\ serial_link_frame_validator\ - serial_link_transport\ - serial_link_triple_buffered_object \ No newline at end of file + serial_link_frame_router\ + serial_link_triple_buffered_object\ + serial_link_transport \ No newline at end of file diff --git a/quantum/serial_link/tests/triple_buffered_object_tests.c b/quantum/serial_link/tests/triple_buffered_object_tests.c deleted file mode 100644 index 6f7c82b46..000000000 --- a/quantum/serial_link/tests/triple_buffered_object_tests.c +++ /dev/null @@ -1,82 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include -#include "serial_link/protocol/triple_buffered_object.c" - -typedef struct { - uint8_t state; - uint32_t buffer[3]; -}test_object_t; - -test_object_t test_object; - -Describe(TripleBufferedObject); -BeforeEach(TripleBufferedObject) { - triple_buffer_init((triple_buffer_object_t*)&test_object); -} -AfterEach(TripleBufferedObject) {} - - -Ensure(TripleBufferedObject, writes_and_reads_object) { - *triple_buffer_begin_write(&test_object) = 0x3456ABCC; - triple_buffer_end_write(&test_object); - assert_that(*triple_buffer_read(&test_object), is_equal_to(0x3456ABCC)); -} - -Ensure(TripleBufferedObject, does_not_read_empty) { - assert_that(triple_buffer_read(&test_object), is_equal_to(NULL)); -} - -Ensure(TripleBufferedObject, writes_twice_and_reads_object) { - *triple_buffer_begin_write(&test_object) = 0x3456ABCC; - triple_buffer_end_write(&test_object); - *triple_buffer_begin_write(&test_object) = 0x44778899; - triple_buffer_end_write(&test_object); - assert_that(*triple_buffer_read(&test_object), is_equal_to(0x44778899)); -} - -Ensure(TripleBufferedObject, performs_another_write_in_the_middle_of_read) { - *triple_buffer_begin_write(&test_object) = 1; - triple_buffer_end_write(&test_object); - uint32_t* read = triple_buffer_read(&test_object); - *triple_buffer_begin_write(&test_object) = 2; - triple_buffer_end_write(&test_object); - assert_that(*read, is_equal_to(1)); - assert_that(*triple_buffer_read(&test_object), is_equal_to(2)); - assert_that(triple_buffer_read(&test_object), is_equal_to(NULL)); -} - -Ensure(TripleBufferedObject, performs_two_writes_in_the_middle_of_read) { - *triple_buffer_begin_write(&test_object) = 1; - triple_buffer_end_write(&test_object); - uint32_t* read = triple_buffer_read(&test_object); - *triple_buffer_begin_write(&test_object) = 2; - triple_buffer_end_write(&test_object); - *triple_buffer_begin_write(&test_object) = 3; - triple_buffer_end_write(&test_object); - assert_that(*read, is_equal_to(1)); - assert_that(*triple_buffer_read(&test_object), is_equal_to(3)); - assert_that(triple_buffer_read(&test_object), is_equal_to(NULL)); -} diff --git a/quantum/serial_link/tests/triple_buffered_object_tests.cpp b/quantum/serial_link/tests/triple_buffered_object_tests.cpp new file mode 100644 index 000000000..7724bbee9 --- /dev/null +++ b/quantum/serial_link/tests/triple_buffered_object_tests.cpp @@ -0,0 +1,84 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016 Fred Sundvik + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include "gtest/gtest.h" +extern "C" { +#include "serial_link/protocol/triple_buffered_object.h" +} + +struct test_object{ + uint8_t state; + uint32_t buffer[3]; +}; + +test_object test_object; + +class TripleBufferedObject : public testing::Test { +public: + TripleBufferedObject() { + triple_buffer_init((triple_buffer_object_t*)&test_object); + } +}; + +TEST_F(TripleBufferedObject, writes_and_reads_object) { + *triple_buffer_begin_write(&test_object) = 0x3456ABCC; + triple_buffer_end_write(&test_object); + EXPECT_EQ(*triple_buffer_read(&test_object), 0x3456ABCC); +} + +TEST_F(TripleBufferedObject, does_not_read_empty) { + EXPECT_EQ(triple_buffer_read(&test_object), nullptr); +} + +TEST_F(TripleBufferedObject, writes_twice_and_reads_object) { + *triple_buffer_begin_write(&test_object) = 0x3456ABCC; + triple_buffer_end_write(&test_object); + *triple_buffer_begin_write(&test_object) = 0x44778899; + triple_buffer_end_write(&test_object); + EXPECT_EQ(*triple_buffer_read(&test_object), 0x44778899); +} + +TEST_F(TripleBufferedObject, performs_another_write_in_the_middle_of_read) { + *triple_buffer_begin_write(&test_object) = 1; + triple_buffer_end_write(&test_object); + uint32_t* read = triple_buffer_read(&test_object); + *triple_buffer_begin_write(&test_object) = 2; + triple_buffer_end_write(&test_object); + EXPECT_EQ(*read, 1); + EXPECT_EQ(*triple_buffer_read(&test_object), 2); + EXPECT_EQ(triple_buffer_read(&test_object), nullptr); +} + +TEST_F(TripleBufferedObject, performs_two_writes_in_the_middle_of_read) { + *triple_buffer_begin_write(&test_object) = 1; + triple_buffer_end_write(&test_object); + uint32_t* read = triple_buffer_read(&test_object); + *triple_buffer_begin_write(&test_object) = 2; + triple_buffer_end_write(&test_object); + *triple_buffer_begin_write(&test_object) = 3; + triple_buffer_end_write(&test_object); + EXPECT_EQ(*read, 1); + EXPECT_EQ(*triple_buffer_read(&test_object), 3); + EXPECT_EQ(triple_buffer_read(&test_object), nullptr); +} -- cgit v1.2.3-24-g4f1b From 1f5838a28679975f689e35471a35720ed5c7e7c5 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Sat, 27 Aug 2016 23:29:37 +0300 Subject: Fix the keyboard template with new make syntax Also add proper link to the parent --- quantum/template/readme.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'quantum') diff --git a/quantum/template/readme.md b/quantum/template/readme.md index b2fb4dd98..b16f4cd76 100644 --- a/quantum/template/readme.md +++ b/quantum/template/readme.md @@ -3,7 +3,7 @@ ## Quantum MK Firmware -For the full Quantum feature list, see [the parent readme.md](/doc/readme.md). +For the full Quantum feature list, see [the parent readme](/). ## Building @@ -13,16 +13,16 @@ Depending on which keymap you would like to use, you will have to compile slight ### Default -To build with the default keymap, simply run `make`. +To build with the default keymap, simply run `make default`. ### Other Keymaps Several version of keymap are available in advance but you are recommended to define your favorite layout yourself. To define your own keymap create a folder with the name of your keymap in the keymaps folder, and see keymap documentation (you can find in top readme.md) and existant keymap files. -To build the firmware binary hex file with a keymap just do `make` with `keymap` option like: +To build the firmware binary hex file with a keymap just do `make` with a keymap like this: ``` -$ make keymap=[default|jack|] +$ make [default|jack|] ``` -Keymaps follow the format **__keymap.c__** and are stored in folders in the `keymaps` folder, eg `keymaps/my_keymap/` \ No newline at end of file +Keymaps follow the format **__\.c__** and are stored in the `keymaps` folder. -- cgit v1.2.3-24-g4f1b From c9ea236fc35d350c0ff33de0af84d3dee7d0eb95 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 31 Aug 2016 08:21:52 +0200 Subject: process_unicode: Add get_unicode_input_mode() There may be cases where one would like to know the current Unicode input mode, without having to keep track of it themselves. Add a function that does just this. Signed-off-by: Gergely Nagy --- quantum/process_keycode/process_unicode.c | 4 ++++ quantum/process_keycode/process_unicode.h | 1 + 2 files changed, 5 insertions(+) (limited to 'quantum') diff --git a/quantum/process_keycode/process_unicode.c b/quantum/process_keycode/process_unicode.c index 06c1694f2..a5d7dca21 100644 --- a/quantum/process_keycode/process_unicode.c +++ b/quantum/process_keycode/process_unicode.c @@ -18,6 +18,10 @@ void set_unicode_input_mode(uint8_t os_target) input_mode = os_target; } +uint8_t get_unicode_input_mode(void) { + return input_mode; +} + __attribute__((weak)) void unicode_input_start (void) { switch(input_mode) { diff --git a/quantum/process_keycode/process_unicode.h b/quantum/process_keycode/process_unicode.h index 02ce3dd7e..27f8072ee 100644 --- a/quantum/process_keycode/process_unicode.h +++ b/quantum/process_keycode/process_unicode.h @@ -13,6 +13,7 @@ #endif void set_unicode_input_mode(uint8_t os_target); +uint8_t get_unicode_input_mode(void); void unicode_input_start(void); void unicode_input_finish(void); void register_hex(uint16_t hex); -- cgit v1.2.3-24-g4f1b From acda2b793f69c6e0e9b9667e9ebe8a0325eb5ecd Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 1 Sep 2016 08:32:47 +0200 Subject: tap-dance: Do not start a sequence on keyup There was an odd case, which confused the hell out of tap-dance: suppose you had a number of tap-dance keys, on a layer, and as part of the tap-dance, you turned that layer off - or had it on one-shot to begin with. In this case, the keydown event would trigger the tap-dance key, but the keyup would not. This had two funky consequences: - tap-dance did not correctly register that the dance has ended. - pressing any other tap-dance key would interrupt the previous tap-dance, and potentially input unwanted characters. To fix this, we simply do not start a tap-dance sequence on keyup, only when it is pressed. This way the previous sequence has enough time to time-out and finish properly, and we don't get confused. This fixes algernon/ergodox-layout#107. Signed-off-by: Gergely Nagy --- quantum/process_keycode/process_tap_dance.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'quantum') diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c index 07de3ecb8..79ade4d00 100644 --- a/quantum/process_keycode/process_tap_dance.c +++ b/quantum/process_keycode/process_tap_dance.c @@ -65,9 +65,9 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { highest_td = idx; action = &tap_dance_actions[idx]; - action->state.keycode = keycode; action->state.pressed = record->event.pressed; if (record->event.pressed) { + action->state.keycode = keycode; action->state.count++; action->state.timer = timer_read(); @@ -77,8 +77,9 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { process_tap_dance_action_on_dance_finished (paction); reset_tap_dance (&paction->state); } + + last_td = keycode; } - last_td = keycode; break; -- cgit v1.2.3-24-g4f1b From e571d4656cd283ce8d793fe3dd2ac176b84b0bf5 Mon Sep 17 00:00:00 2001 From: IBNobody Date: Tue, 6 Sep 2016 18:02:43 -0500 Subject: Set keyboard_nkro (used by TMK) w/ MAGIC_HOST_NKRO If NKRO is enabled, also set keyboard_nkro with MAGIC_HOST_NKRO and MAGIC_UNHOST_NKRO. --- quantum/quantum.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'quantum') diff --git a/quantum/quantum.c b/quantum/quantum.c index e3a20f43e..fa86b6220 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -27,6 +27,10 @@ static void do_code16 (uint16_t code, void (*f) (uint8_t)) { f(KC_RGUI); } +#ifdef NKRO_ENABLE + extern bool keyboard_nkro; +#endif + void register_code16 (uint16_t code) { do_code16 (code, register_code); register_code (code); @@ -223,6 +227,11 @@ bool process_record_quantum(keyrecord_t *record) { keymap_config.swap_backslash_backspace = 1; } else if (keycode == MAGIC_HOST_NKRO) { keymap_config.nkro = 1; + +#ifdef NKRO_ENABLE + clear_keyboard(); // clear to prevent stuck keys + keyboard_nkro = keymap_config.nkro; +#endif } else if (keycode == MAGIC_SWAP_ALT_GUI) { keymap_config.swap_lalt_lgui = 1; keymap_config.swap_ralt_rgui = 1; @@ -244,6 +253,10 @@ bool process_record_quantum(keyrecord_t *record) { keymap_config.swap_backslash_backspace = 0; } else if (keycode == MAGIC_UNHOST_NKRO) { keymap_config.nkro = 0; +#ifdef NKRO_ENABLE + clear_keyboard(); // clear to prevent stuck keys + keyboard_nkro = keymap_config.nkro; +#endif } else if (keycode == MAGIC_UNSWAP_ALT_GUI) { keymap_config.swap_lalt_lgui = 0; keymap_config.swap_ralt_rgui = 0; -- cgit v1.2.3-24-g4f1b From 558f3ec1eb325caf706efc15e2fab26121aba442 Mon Sep 17 00:00:00 2001 From: IBNobody Date: Tue, 6 Sep 2016 23:19:01 -0500 Subject: Use keyboard config for nkro (#7) * removing nkro references - wip * changed NKRO to be defined by keymap_config --- quantum/keycode_config.h | 5 ++ quantum/keymap.h | 1 + quantum/quantum.c | 124 ++++++++++++++++++++++++++--------------------- 3 files changed, 74 insertions(+), 56 deletions(-) (limited to 'quantum') diff --git a/quantum/keycode_config.h b/quantum/keycode_config.h index 6216eefc9..c15b0d32f 100644 --- a/quantum/keycode_config.h +++ b/quantum/keycode_config.h @@ -1,6 +1,9 @@ #include "eeconfig.h" #include "keycode.h" +#ifndef KEYCODE_CONFIG_H +#define KEYCODE_CONFIG_H + uint16_t keycode_config(uint16_t keycode); /* NOTE: Not portable. Bit field order depends on implementation */ @@ -19,3 +22,5 @@ typedef union { } keymap_config_t; extern keymap_config_t keymap_config; + +#endif /* KEYCODE_CONFIG_H */ diff --git a/quantum/keymap.h b/quantum/keymap.h index f2d94d75c..98ddfd0c5 100644 --- a/quantum/keymap.h +++ b/quantum/keymap.h @@ -111,6 +111,7 @@ enum quantum_keycodes { MAGIC_UNSWAP_BACKSLASH_BACKSPACE, MAGIC_UNHOST_NKRO, MAGIC_UNSWAP_ALT_GUI, + MAGIC_TOGGLE_NKRO, // Leader key #ifndef DISABLE_LEADER diff --git a/quantum/quantum.c b/quantum/quantum.c index fa86b6220..a16bd5443 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -27,10 +27,6 @@ static void do_code16 (uint16_t code, void (*f) (uint8_t)) { f(KC_RGUI); } -#ifdef NKRO_ENABLE - extern bool keyboard_nkro; -#endif - void register_code16 (uint16_t code) { do_code16 (code, register_code); register_code (code); @@ -203,7 +199,7 @@ bool process_record_quantum(keyrecord_t *record) { return false; break; #endif - case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_UNSWAP_ALT_GUI: + case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_TOGGLE_NKRO: if (record->event.pressed) { // MAGIC actions (BOOTMAGIC without the boot) if (!eeconfig_is_enabled()) { @@ -211,57 +207,73 @@ bool process_record_quantum(keyrecord_t *record) { } /* keymap config */ keymap_config.raw = eeconfig_read_keymap(); - if (keycode == MAGIC_SWAP_CONTROL_CAPSLOCK) { - keymap_config.swap_control_capslock = 1; - } else if (keycode == MAGIC_CAPSLOCK_TO_CONTROL) { - keymap_config.capslock_to_control = 1; - } else if (keycode == MAGIC_SWAP_LALT_LGUI) { - keymap_config.swap_lalt_lgui = 1; - } else if (keycode == MAGIC_SWAP_RALT_RGUI) { - keymap_config.swap_ralt_rgui = 1; - } else if (keycode == MAGIC_NO_GUI) { - keymap_config.no_gui = 1; - } else if (keycode == MAGIC_SWAP_GRAVE_ESC) { - keymap_config.swap_grave_esc = 1; - } else if (keycode == MAGIC_SWAP_BACKSLASH_BACKSPACE) { - keymap_config.swap_backslash_backspace = 1; - } else if (keycode == MAGIC_HOST_NKRO) { - keymap_config.nkro = 1; - -#ifdef NKRO_ENABLE - clear_keyboard(); // clear to prevent stuck keys - keyboard_nkro = keymap_config.nkro; -#endif - } else if (keycode == MAGIC_SWAP_ALT_GUI) { - keymap_config.swap_lalt_lgui = 1; - keymap_config.swap_ralt_rgui = 1; - } - /* UNs */ - else if (keycode == MAGIC_UNSWAP_CONTROL_CAPSLOCK) { - keymap_config.swap_control_capslock = 0; - } else if (keycode == MAGIC_UNCAPSLOCK_TO_CONTROL) { - keymap_config.capslock_to_control = 0; - } else if (keycode == MAGIC_UNSWAP_LALT_LGUI) { - keymap_config.swap_lalt_lgui = 0; - } else if (keycode == MAGIC_UNSWAP_RALT_RGUI) { - keymap_config.swap_ralt_rgui = 0; - } else if (keycode == MAGIC_UNNO_GUI) { - keymap_config.no_gui = 0; - } else if (keycode == MAGIC_UNSWAP_GRAVE_ESC) { - keymap_config.swap_grave_esc = 0; - } else if (keycode == MAGIC_UNSWAP_BACKSLASH_BACKSPACE) { - keymap_config.swap_backslash_backspace = 0; - } else if (keycode == MAGIC_UNHOST_NKRO) { - keymap_config.nkro = 0; -#ifdef NKRO_ENABLE - clear_keyboard(); // clear to prevent stuck keys - keyboard_nkro = keymap_config.nkro; -#endif - } else if (keycode == MAGIC_UNSWAP_ALT_GUI) { - keymap_config.swap_lalt_lgui = 0; - keymap_config.swap_ralt_rgui = 0; + switch (keycode) + { + case MAGIC_SWAP_CONTROL_CAPSLOCK: + keymap_config.swap_control_capslock = true; + break; + case MAGIC_CAPSLOCK_TO_CONTROL: + keymap_config.capslock_to_control = true; + break; + case MAGIC_SWAP_LALT_LGUI: + keymap_config.swap_lalt_lgui = true; + break; + case MAGIC_SWAP_RALT_RGUI: + keymap_config.swap_ralt_rgui = true; + break; + case MAGIC_NO_GUI: + keymap_config.no_gui = true; + break; + case MAGIC_SWAP_GRAVE_ESC: + keymap_config.swap_grave_esc = true; + break; + case MAGIC_SWAP_BACKSLASH_BACKSPACE: + keymap_config.swap_backslash_backspace = true; + break; + case MAGIC_HOST_NKRO: + keymap_config.nkro = true; + break; + case MAGIC_SWAP_ALT_GUI: + keymap_config.swap_lalt_lgui = true; + keymap_config.swap_ralt_rgui = true; + break; + case MAGIC_UNSWAP_CONTROL_CAPSLOCK: + keymap_config.swap_control_capslock = false; + break; + case MAGIC_UNCAPSLOCK_TO_CONTROL: + keymap_config.capslock_to_control = false; + break; + case MAGIC_UNSWAP_LALT_LGUI: + keymap_config.swap_lalt_lgui = false; + break; + case MAGIC_UNSWAP_RALT_RGUI: + keymap_config.swap_ralt_rgui = false; + break; + case MAGIC_UNNO_GUI: + keymap_config.no_gui = false; + break; + case MAGIC_UNSWAP_GRAVE_ESC: + keymap_config.swap_grave_esc = false; + break; + case MAGIC_UNSWAP_BACKSLASH_BACKSPACE: + keymap_config.swap_backslash_backspace = false; + break; + case MAGIC_UNHOST_NKRO: + keymap_config.nkro = false; + break; + case MAGIC_UNSWAP_ALT_GUI: + keymap_config.swap_lalt_lgui = false; + keymap_config.swap_ralt_rgui = false; + break; + case MAGIC_TOGGLE_NKRO: + keymap_config.nkro = !keymap_config.nkro; + break; + default: + break; } eeconfig_update_keymap(keymap_config.raw); + clear_keyboard(); // clear to prevent stuck keys + return false; } break; @@ -284,7 +296,7 @@ bool process_record_quantum(keyrecord_t *record) { unregister_mods(MOD_BIT(KC_LSFT)); } return false; - break; + // break; } case KC_RSPC: { @@ -306,7 +318,7 @@ bool process_record_quantum(keyrecord_t *record) { unregister_mods(MOD_BIT(KC_RSFT)); } return false; - break; + // break; } default: { shift_interrupted[0] = true; -- cgit v1.2.3-24-g4f1b