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 d9aaafd616..6480e33c60 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 3ce940895d..786bcb2383 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 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 6480e33c60..426cfa12b2 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 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 426cfa12b2..bc63fb614b 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 786bcb2383..69277b9e32 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 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 00d3e81142..0000000000 --- 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 f101eb7a67..8772b09200 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 39f9f59d10..baaeef4731 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 4121fd860c..0000000000 --- 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 0000000000..4121fd860c --- /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 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 bc63fb614b..0a900aac28 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 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 412662a794..4f1564ac87 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 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 3ca249fdf5..ead5fbf3e9 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 328a253a7e..f820eec1be 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 0000000000..6d90781a17 --- /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 0000000000..c41c08706c --- /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 0000000000..203a82d954 --- /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 0000000000..979ab2da10 --- /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 ba7269388b..0000000000 --- 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 c72c0bc29d..0000000000 --- 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 1ab2d63ddd..4c30960547 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 8a418c6159..b8d6157484 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 93e355bf91..e855056e83 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 d3884c19a1..3fd9713575 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 e03a121a2b..2a44c80b14 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 eb31bfb4d0..004d73ee23 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 dbad26f8a6..3f9ae8bade 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 0874abf7dd..6a782bcd7b 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 ee725bad5e..b2040a278a 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 a35ba55a55..b54cb74b90 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 7ef41fb791..3acb8b6983 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 98e57ab7b1..9b88f7d84d 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 7f980afbcf..512d8a374b 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 5b4bd3c0d4..5c5d951791 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 ac45d25892..46049b9875 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 0a900aac28..a310608e00 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 69277b9e32..e15003805b 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 8537e3b4be..b8e7a0456b 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 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 979ab2da10..43efab7f3f 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 a310608e00..49ac20d61f 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 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 8772b09200..87e4c2d2bb 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 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 8c9ad77364..c29ffedc38 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 37e207578c..64f92523e0 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 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 43efab7f3f..6ac3d2ace6 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 b2040a278a..f63f066183 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 208e348f34..2634ab2f61 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 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 b54cb74b90..80439af347 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 018bfeae59..0000000000 --- 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 0000000000..018bfeae59 --- /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 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 baaeef4731..d6b0ac936c 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 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 49ac20d61f..006464e5a8 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 e15003805b..1f78f37177 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 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 02f11d979c..09a4fe7010 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 6ac3d2ace6..41fa394ab6 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 2634ab2f61..0000000000 --- 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 006464e5a8..3f2edfc92c 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 87e4c2d2bb..3f6d133c9b 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 d6b0ac936c..0000000000 --- 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 cad3e3260a..b02f0c7ebc 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 0000000000..f4671a9d11 --- /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 0000000000..df06a26206 --- /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 4121fd860c..e28a4723e9 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 0000000000..21aa663d55 --- /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 0000000000..b2fb4dd98d --- /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 649072eb2e..dcc4b0a221 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 b8e7a0456b..cd78a54e3e 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 5f355256de..0000000000 --- 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 0000000000..5f355256de --- /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 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 3f2edfc92c..9c0f9691ff 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 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 203a82d954..74fd518c9b 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 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 00d45f7ac1..47f326ea0a 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 6e9f92727f..f5744658cf 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 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 41fa394ab6..a994f4f2e5 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 46049b9875..0000000000 --- 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 3a2bf3afff..0000000000 --- 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 0000000000..d7814629f3 --- /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 0000000000..49c97db3bc --- /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 0000000000..e53d221e75 --- /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 0000000000..c83db8abbd --- /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 0000000000..d6ab9c6264 --- /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 0000000000..acd4fc1b16 --- /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 0000000000..c8f3ddb900 --- /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 0000000000..318b3e3875 --- /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 0000000000..9b172e1b6c --- /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 0000000000..b9d7c7fcf4 --- /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 0000000000..ad5d7f86b7 --- /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 0000000000..ca17f8f669 --- /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 9c0f9691ff..c0580e0aa5 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 7795294d50..ad180c71f8 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 756ec8bc3f..0000000000 --- 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 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 c0580e0aa5..224bfb7951 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 ad180c71f8..dd290ac00c 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 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 224bfb7951..270b976e36 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 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 dd290ac00c..9b5d310bd4 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 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 c41c08706c..6216eefc90 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 74fd518c9b..0000000000 --- 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 a994f4f2e5..73f99f8211 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 0000000000..76872ac592 --- /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 f5744658cf..a38c13f15b 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 270b976e36..d59bd5a3f8 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 9b5d310bd4..3a0b742028 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 From 132c04746910f7230b63ed33717c4ed65599ed1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20D=C3=ADaz-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 512d8a374b..af76e39fcb 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 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 a38c13f15b..0949170255 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 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 d59bd5a3f8..65290338d0 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 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 65290338d0..71c3c723ba 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 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 0949170255..3174e07390 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 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 2d68e206e8..0000000000 --- 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 991cfe96d7..0000000000 --- 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 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 6b31a3f923..0000000000 --- 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 f76165244c..0000000000 --- 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 d4d438dda1..0000000000 --- a/quantum/serial_link/cgreen/cgreen +++ /dev/null @@ -1 +0,0 @@ -Subproject commit d4d438dda1b7131f0bd0530b2c258e9dea6a2a9f -- cgit v1.2.3 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 94af9125ce..e8490e290d 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 0000000000..fb4c45a8dc --- /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 0000000000..2cc88beb42 --- /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 0000000000..04b8c2e75c --- /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 0000000000..712250ff35 --- /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 0000000000..474f80ee8e --- /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 0000000000..4a910d510b --- /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 0000000000..425e06cdd2 --- /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 0000000000..f418d11ceb --- /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 0000000000..9a052d8809 --- /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 0000000000..e3e8989d30 --- /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 0000000000..2e57db3f50 --- /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 e164cc5ff3..0000000000 --- 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 fb4c45a8dc..0000000000 --- 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 2cc88beb42..0000000000 --- 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 04b8c2e75c..0000000000 --- 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 712250ff35..0000000000 --- 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 474f80ee8e..0000000000 --- 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 4a910d510b..0000000000 --- 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 425e06cdd2..0000000000 --- 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 f418d11ceb..0000000000 --- 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 9a052d8809..0000000000 --- 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 e3e8989d30..0000000000 --- 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 2e57db3f50..0000000000 --- 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 75c7e77a76..0000000000 --- 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 351e03877b..0000000000 --- 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 1b072c6f1d..0000000000 --- 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 64b170e8c1..0000000000 --- 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 d20947e2c9..0000000000 --- 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 358e1b9fd4..0000000000 --- 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 6f7c82b468..0000000000 --- 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 e292f582a9..0000000000 --- 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 0000000000..75c7e77a76 --- /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 0000000000..351e03877b --- /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 0000000000..1b072c6f1d --- /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 0000000000..64b170e8c1 --- /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 0000000000..d20947e2c9 --- /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 0000000000..358e1b9fd4 --- /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 0000000000..6f7c82b468 --- /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 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 b320458c0e..0000000000 --- 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 e221a69061..0000000000 --- a/quantum/visualizer/ugfx +++ /dev/null @@ -1 +0,0 @@ -Subproject commit e221a690616e20f87e0b0088baffdbd5427be862 -- cgit v1.2.3 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 c240734055..abca22d85f 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 45cfa9aa97..53e250725c 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 56525ffd93..b5dfad8e1a 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 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 d59bd5a3f8..d8e43a4655 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 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 c2ea30b55b..a9abace8df 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 b5dfad8e1a..149968de72 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 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 abca22d85f..dfa2ff4eea 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 149968de72..379496fb66 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 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 dfa2ff4eea..54f6faaa42 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 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 379496fb66..449957d63f 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 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 449957d63f..2f4a41d66f 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 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 dcc4b0a221..3057557eae 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 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 f20043067e..401845e855 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 c29ffedc38..b1b0f035d5 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 64f92523e0..def26c428c 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 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 3057557eae..5ef349583c 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 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 76872ac592..d0a8312c1e 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 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 73f99f8211..a158651839 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 d8e43a4655..5c0b53e221 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 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 5c0b53e221..09daa47127 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 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 71c3c723ba..d91b8f2d06 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 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 d5b9753b76..bc2da510f2 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 3a0b742028..7ebfb24e30 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 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 2a44c80b14..4fd1f61ae0 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 5c5d951791..1458d64a9a 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 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 3fd9713575..87d4bb24cf 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 4fd1f61ae0..834c69650e 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 3f9ae8bade..7e2e0ed44e 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 6a782bcd7b..b66d582a44 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 3acb8b6983..f8cf4e2e43 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 af76e39fcb..4ba568af23 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 1458d64a9a..00c87afc3e 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 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 e855056e83..17f2059774 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 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 9b172e1b6c..186889bc29 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 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 186889bc29..40fba2a6a6 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 b9d7c7fcf4..bf925df0f6 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 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 40fba2a6a6..93b326b5fc 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 bf925df0f6..7b820584a8 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 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 93b326b5fc..bab6bb81b3 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 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 bab6bb81b3..58192413fb 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 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 58192413fb..b9b836df2e 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 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 b9b836df2e..097440405c 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 7b820584a8..d457db9b3c 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 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 097440405c..94b6af1305 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 d457db9b3c..e2c74efe91 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 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 94b6af1305..d240dc2e66 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 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 4c30960547..e5ef39552a 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 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 c8f3ddb900..2d52e47a72 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 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 d0a8312c1e..833e5a8f8d 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 d6ab9c6264..8784e64f36 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 From b6fa762234fb5a3590d0ff91ffdf5aa3ae322c8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Lindh=C3=A9?= 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 018bfeae59..5c4e8c4955 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 From 283ebbe14298fe75128765fa42c46f02534fb761 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Lindh=C3=A9?= 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 f8cf4e2e43..da5c829757 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 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 d240dc2e66..5429e34383 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 e2c74efe91..6a1258067e 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 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 7ebfb24e30..6e3fbcc792 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 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 fc6fcdeef1..8022ca6729 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