diff --git a/smol_gkos.ino b/smol_gkos.ino index 4307649..ed07201 100644 --- a/smol_gkos.ino +++ b/smol_gkos.ino @@ -3,11 +3,6 @@ #define TRACKBALL_ADDR 0x0A #define TRACKBALL_REG_LEFT 0x04 -// using my own masks here since the inbuilt ones conflict with arrow keys etc. -#define MASK_SHIFT 0x100 -#define MASK_ALTGR 0x200 -#define MASK_CTRL 0x800 - const byte PIN_A = 33; const byte PIN_B = 32; const byte PIN_C = 31; @@ -15,41 +10,60 @@ const byte PIN_D = 24; const byte PIN_E = 25; const byte PIN_F = 26; -const byte PIN_MOUSE_UL = 27; -const byte PIN_MOUSE_UR = 30; -const byte PIN_MOUSE_DL = 28; -const byte PIN_MOUSE_DR = 29; +const byte PIN_MOUSE_UPPER_LEFT = 27; +const byte PIN_MOUSE_UPPER_RIGHT = 30; +const byte PIN_MOUSE_LOWER_LEFT = 28; +const byte PIN_MOUSE_LOWER_RIGHT = 29; const byte PIN_LED1 = 6; const byte PIN_LED2 = 1; const byte PIN_LED3 = 3; -const byte PIN_BALL_SDA = 18; -const byte PIN_BALL_SCL = 19; +// unused here, but the trackball is wired to i2c bus 0 with these pins +// const byte PIN_TRACKBALL_SDA = 18; +// const byte PIN_TRACKBALL_SCL = 19; + +// custom masks for forcing modifiers for keypresses +// teensy's inbuilt ones (eg. SHIFT_MASK) conflict with arrow keys etc. +#define MASK_SHIFT 0x100 +#define MASK_ALTGR 0x200 +#define MASK_CTRL 0x800 enum Button { A, B, C, D, E, F, MouseUL, MouseUR, MouseDL, MouseDR }; const int button_pins[10] = { PIN_A, PIN_B, PIN_C, PIN_D, PIN_E, PIN_F, - PIN_MOUSE_UL, PIN_MOUSE_UR, PIN_MOUSE_DL, PIN_MOUSE_DR + PIN_MOUSE_UPPER_LEFT, PIN_MOUSE_UPPER_RIGHT, + PIN_MOUSE_LOWER_LEFT, PIN_MOUSE_LOWER_RIGHT }; +// how many update cycles a button has to stay pressed before +// it counts as being pressed const int debounce_time = 50; int button_timers[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -// different actions that the keyboard can take +// different actions the keyboard can take // - press (and release) a key // - toggle a modifier enum ActionType { PressKey, ToggleModifier }; -const int button_characters[6] = { KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F }; -const int button_characters_symbol[6] = { +/************************************************* + KEYBOARD KEYS (ON THEIR OWN) +*************************************************/ +const int keys[6] = { KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F }; +const int keys_symbol[6] = { KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6 }; -const int button_characters_function[6] = { +const int keys_function[6] = { KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6 }; +/************************************************* + CHORDS AND KEYS THAT CAN BE CHORDED INTO +*************************************************/ /* -backspace, space (keep those two first since they overlap with the rest ) +defined as a 6-bit number with the physical buttons corresponding to +each of the bits (A = 1, B = 2, C = 4, D = 8, E = 16, F = 32) + +backspace, space (keep those two first since they overlap with the rest) g, k, o, s, w, native */ const byte chords[8] = { 7, 56, 24, 48, 3, 6, 40, 5 }; @@ -80,16 +94,16 @@ const int chord_targets_symbol[32] = { 0, 0, 0, 0, 0, 0, 0, 0, KEY_0, KEY_7, KEY_8, KEY_9, -// # @ ½ & - KEY_BACKSLASH, KEY_QUOTE + MASK_SHIFT, KEY_5 + MASK_ALTGR, KEY_7 + MASK_SHIFT, -// + % = ^ - KEY_EQUAL + MASK_SHIFT, KEY_5 + MASK_SHIFT, KEY_EQUAL, KEY_6 + MASK_SHIFT, -// * $ € £ - KEY_8 + MASK_SHIFT, KEY_4 + MASK_SHIFT, KEY_4 + MASK_ALTGR, KEY_3 + MASK_SHIFT, -// ( [ < { - KEY_9 + MASK_SHIFT, KEY_LEFT_BRACE, KEY_COMMA + MASK_SHIFT, KEY_LEFT_BRACE + MASK_SHIFT, -// ) ] > } - KEY_0 + MASK_SHIFT, KEY_RIGHT_BRACE, KEY_PERIOD + MASK_SHIFT, KEY_RIGHT_BRACE + MASK_SHIFT, + KEY_BACKSLASH, KEY_QUOTE + MASK_SHIFT, // # @ + KEY_5 + MASK_ALTGR, KEY_7 + MASK_SHIFT, // ½ & + KEY_EQUAL + MASK_SHIFT, KEY_5 + MASK_SHIFT, // + % + KEY_EQUAL, KEY_6 + MASK_SHIFT, // = ^ + KEY_8 + MASK_SHIFT, KEY_4 + MASK_SHIFT, // * $ + KEY_4 + MASK_ALTGR, KEY_3 + MASK_SHIFT, // € £ + KEY_9 + MASK_SHIFT, KEY_LEFT_BRACE, // ( [ + KEY_COMMA + MASK_SHIFT, KEY_LEFT_BRACE + MASK_SHIFT, // < { + KEY_0 + MASK_SHIFT, KEY_RIGHT_BRACE, // ) ] + KEY_PERIOD + MASK_SHIFT, KEY_RIGHT_BRACE + MASK_SHIFT, // > } }; const int chord_targets_function[32] = { KEY_MEDIA_PLAY_PAUSE, 0, KEY_MEDIA_PREV_TRACK, 0, @@ -102,32 +116,34 @@ const int chord_targets_function[32] = { 0, 0, 0, 0 }; +/************************************************* + SPECIAL KEY COMBINATIONS +*************************************************/ /* dash, backslash, slash, apostrophe, comma, exclamation point, question mark, period, up, down, page up, page down, shift, symbol shift, switch keyset, escape, control, alt, delete, function, gui, tab, enter */ -// TODO: add the middle specials for function keys instead of the weird symbols const byte specials[23] = { 17, 51, 30, 10, 20, 12, 33, 34, 9, 36, 27, 54, 18, 45, 63, 31, 47, 55, 62, 29, 43, 61, 59 }; enum Modifier { Shift, SymbolShift, Keyset, Control, Alt, Gui, Function }; const int special_action_targets[23] = { -// - \ / ' - KEY_MINUS, KEY_MINUS + MASK_ALTGR, KEY_SLASH, KEY_QUOTE, -// , ! ? . - KEY_COMMA, KEY_1 + MASK_SHIFT, KEY_SLASH + MASK_SHIFT, KEY_PERIOD, + KEY_MINUS, KEY_MINUS + MASK_ALTGR, // - \. + KEY_SLASH, KEY_QUOTE, // / ' + KEY_COMMA, KEY_1 + MASK_SHIFT, // , ! + KEY_SLASH + MASK_SHIFT, KEY_PERIOD, // ! ? KEY_UP, KEY_DOWN, KEY_PAGE_UP, KEY_PAGE_DOWN, Modifier::Shift, Modifier::SymbolShift, Modifier::Keyset, KEY_ESC, Modifier::Control, Modifier::Alt, KEY_DELETE, Modifier::Function, Modifier::Gui, KEY_TAB, KEY_ENTER }; const int special_action_targets_symbol[23] = { -// _ ` ´ " - KEY_MINUS + MASK_SHIFT, KEY_TILDE, KEY_SEMICOLON + MASK_ALTGR, KEY_2 + MASK_SHIFT, -// ; | ~ : - KEY_SEMICOLON, KEY_TILDE + MASK_ALTGR, KEY_BACKSLASH + MASK_SHIFT, KEY_SEMICOLON + MASK_SHIFT, + KEY_MINUS + MASK_SHIFT, KEY_TILDE, // _ ` + KEY_SEMICOLON + MASK_ALTGR, KEY_2 + MASK_SHIFT, // ´ " + KEY_SEMICOLON, KEY_TILDE + MASK_ALTGR, // ; | + KEY_BACKSLASH + MASK_SHIFT, KEY_SEMICOLON + MASK_SHIFT, // ~ : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -145,11 +161,14 @@ const byte special_action_target_types[23] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0 }; +// bitwise variables, see line 63 byte key_pressed = 0; byte key_pressed_total = 0; bool chord_used = false; bool chorded_pressed = false; +// modifiers that can be toggled +// these get unset after each keypress (save for the locks) bool mod_shift = false; bool mod_shift_lock = false; bool mod_symbol = false; @@ -169,6 +188,10 @@ byte mouse_left = 0; byte mouse_right = 0; bool mouse_button = false; +/* +we do a rudimentary form of mouse acceleration by adjusting movement speed +based on the distance moved during the last [num_mouse_samples] updates +*/ const int num_mouse_samples = 10; int current_mouse_sample = 0; int mouse_movement_sample = 0; @@ -188,10 +211,10 @@ void setup() { pinMode(PIN_E, INPUT_PULLUP); pinMode(PIN_F, INPUT_PULLUP); - pinMode(PIN_MOUSE_UL, INPUT_PULLUP); - pinMode(PIN_MOUSE_UR, INPUT_PULLUP); - pinMode(PIN_MOUSE_DL, INPUT_PULLUP); - pinMode(PIN_MOUSE_DR, INPUT_PULLUP); + pinMode(PIN_MOUSE_UPPER_LEFT, INPUT_PULLUP); + pinMode(PIN_MOUSE_UPPER_RIGHT, INPUT_PULLUP); + pinMode(PIN_MOUSE_LOWER_LEFT, INPUT_PULLUP); + pinMode(PIN_MOUSE_LOWER_RIGHT, INPUT_PULLUP); pinMode(PIN_LED1, OUTPUT); pinMode(PIN_LED2, OUTPUT); @@ -204,9 +227,9 @@ void setup() { } void loop() { - /* - BUTTONS - */ + /******************* + BUTTONS + *******************/ for (byte b = 0; b < 10; b++) { // button is pressed if (!digitalRead(button_pins[b])) { @@ -238,12 +261,11 @@ void loop() { } // button is released else { - // if the button had been debounced, it counts as a press + // if the button was debounced, it counts as a press if (button_timers[b] >= debounce_time) { // gkos key released if (b < 6) { key_pressed &= ~(1 << b); - // check if it completed a chord key_released(b); update_leds(); if (key_pressed == 0) { @@ -276,9 +298,9 @@ void loop() { } } - /* - TRACKBALL - */ + /******************* + TRACKBALL + *******************/ noInterrupts(); if (trackball_update) { Wire.beginTransmission(TRACKBALL_ADDR); @@ -295,6 +317,7 @@ void loop() { int mouse_x = mouse_right - mouse_left; int mouse_y = mouse_down - mouse_up; + // calculate mouse acceleration every [num_mouse_samples] updates mouse_movement_sample += abs(mouse_x) + abs(mouse_y); current_mouse_sample++; if (current_mouse_sample > num_mouse_samples) { @@ -303,6 +326,7 @@ void loop() { mouse_movement_sample = 0; } + // scroll with the middle mouse button if (mouse_middle_pressed) { mouse_scroll_dist += mouse_y; if (abs(mouse_scroll_dist) > mouse_scroll_sensitivity) { @@ -319,16 +343,15 @@ void loop() { interrupts(); } -// returns true if a keypress was completed void key_released(byte key) { int target = 0; - /* - SPECIALS - */ + /************************************************* + SPECIAL KEY COMBINATIONS + *************************************************/ bool is_special = false; byte special = 0; - for (byte b = 0; b < 22; b++) { + for (byte b = 0; b < 23; b++) { if (key_pressed_total == specials[b]) { is_special = true; special = b; @@ -391,9 +414,9 @@ void key_released(byte key) { return; } - /* - CHORDS - */ + /************************************************* + CHORDS AND KEYS THAT CAN BE CHORDED INTO + *************************************************/ bool is_chord = false; byte chord = 0; for (byte b = 0; b < 8; b++) { @@ -442,23 +465,19 @@ void key_released(byte key) { return; } - /* - REGULAR KEYS - */ - // keypress - if (mod_function && button_characters_function[key] != 0) - press_key(button_characters_function[key]); + /************************************************* + KEYBOARD KEYS (ON THEIR OWN) + *************************************************/ + if (mod_function && keys_function[key] != 0) + press_key(keys_function[key]); else if (mod_symbol || mod_symbol_lock) - press_key(button_characters_symbol[key]); + press_key(keys_symbol[key]); else - press_key(button_characters[key]); + press_key(keys[key]); return; } void press_key(int key) { - Serial.print("press key "); - Serial.println(key); - // check if modifiers need to be forced if (key & MASK_SHIFT) { mod_shift = true; @@ -473,7 +492,7 @@ void press_key(int key) { key &= ~(MASK_CTRL); } - // modifiers + // press modifiers if (mod_shift || mod_shift_lock) Keyboard.press(KEY_LEFT_SHIFT); if (mod_control)