From 06eb50be07ff16e4bfb046e4773185d9bcf048e9 Mon Sep 17 00:00:00 2001 From: tmk Date: Sun, 24 Oct 2010 01:17:26 +0900 Subject: [PATCH] hhkb: refactored --- Makefile.common | 2 +- hhkb/keymap.c | 130 ++++++++++++++++++------------ hhkb/keymap.h | 13 +-- hhkb/matrix.c | 36 ++++++++- hhkb/matrix.h | 15 ++++ key_process.c | 207 ++++++++++++++++++++---------------------------- key_process.h | 1 + keymap_skel.h | 17 ++++ matrix.h | 15 ---- matrix_skel.h | 24 ++++++ tmk.c | 2 +- usb_keyboard.c | 43 ++++++++++ usb_keyboard.h | 13 ++- usb_keycodes.h | 6 +- usb_mouse.c | 21 +++++ usb_mouse.h | 4 + 16 files changed, 343 insertions(+), 206 deletions(-) create mode 100644 hhkb/matrix.h create mode 100644 keymap_skel.h delete mode 100644 matrix.h create mode 100644 matrix_skel.h diff --git a/Makefile.common b/Makefile.common index 8037b077..879e5238 100644 --- a/Makefile.common +++ b/Makefile.common @@ -51,10 +51,10 @@ # List C source files here. (C dependencies are automatically generated.) SRC = tmk.c \ key_process.c \ - usb.c \ usb_keyboard.c \ usb_mouse.c \ usb_debug.c \ + usb.c \ jump_bootloader.c \ print.c SRC += $(TARGET_SRC) diff --git a/hhkb/keymap.c b/hhkb/keymap.c index 572f530b..6838a08a 100644 --- a/hhkb/keymap.c +++ b/hhkb/keymap.c @@ -3,12 +3,18 @@ */ #include #include +#include "usb_keyboard.h" #include "matrix.h" #include "keymap.h" -#include "usb_keyboard.h" +#include "print.h" -int current_layer = 0; -bool key_sent = false; +#define FN_KEYCODE(fn) (pgm_read_byte(&fn_keycode[(fn)])) +#define FN_LAYER(fn) (pgm_read_byte(&fn_layer[(fn)])) +#define KEYMAPS(layer, row, col) (pgm_read_byte(&keymaps[(layer)][(row)][(col)])) + +static int current_layer = 0; +static bool layer_used = false; +static int onbit(uint8_t bits); /* * Layer0(Default Layer) @@ -66,15 +72,21 @@ bool key_sent = false; * Mc: Mouse Cursor / Mb: Mouse Button / Mw: Mouse Wheel */ -/* keycode sent when Fn key released without using layer keys. */ -static const uint8_t PROGMEM FnKey[] = { - KB_NO, // this must be KB_NO. (not used) +/* keycode to sent when Fn key released without using layer keys. */ +static const uint8_t PROGMEM fn_keycode[] = { + KB_NO, // FN_0 KB_NO, // FN_1 KB_RALT, // FN_2 KB_SCOLON, // FN_3 + KB_NO, // FN_4 + KB_NO, // FN_5 + KB_NO, // FN_6 + KB_NO, // FN_7 }; +/* layer to change into while Fn key pressed */ +static const int PROGMEM fn_layer[] = { 0, 1, 2, 3, 0, 0, 0, 0 }; -static const uint8_t PROGMEM Keymap[][MATRIX_ROWS][MATRIX_COLS] = { +static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { /* plain keymap { { KB_2, KB_Q, KB_W, KB_S, KB_A, KB_Z, KB_X, KB_C }, @@ -134,61 +146,77 @@ static const uint8_t PROGMEM Keymap[][MATRIX_ROWS][MATRIX_COLS] = { }; -uint8_t get_keycode(int layer, int row, int col) +uint8_t keymap_get_keycode(int row, int col) { - if (row >= MATRIX_ROWS) - return KB_NO; - if (col >= MATRIX_COLS) - return KB_NO; - return pgm_read_byte(&Keymap[layer][row][col]); + return keymap_get_keycodel(current_layer, row, col); } -int get_layer(void) { - // keep modifier state when Fn key pressed - static uint8_t preserved_modifiers = 0; - int layer = 0; - uint8_t modifiers = 0; - for (int row = 0; row < MATRIX_ROWS; row++) { - for (int col = 0; col < MATRIX_ROWS; col++) { - if (matrix[row] & 1<> 4) { bits >>= 4; n += 4;} + if (bits >> 2) { bits >>= 2; n += 2;} + if (bits >> 1) { bits >>= 1; n += 1;} + return n; } diff --git a/hhkb/keymap.h b/hhkb/keymap.h index be78609e..a577c79b 100644 --- a/hhkb/keymap.h +++ b/hhkb/keymap.h @@ -4,17 +4,6 @@ #include #include #include "usb_keycodes.h" - - -#define MATRIX_ROWS 8 -#define MATRIX_COLS 8 - - -extern int current_layer; -extern bool key_sent; - - -int get_layer(void); -uint8_t get_keycode(int layer, int row, int col); +#include "keymap_skel.h" #endif diff --git a/hhkb/matrix.c b/hhkb/matrix.c index 3034a636..a1917793 100644 --- a/hhkb/matrix.c +++ b/hhkb/matrix.c @@ -31,6 +31,19 @@ static uint8_t _matrix0[MATRIX_ROWS]; static uint8_t _matrix1[MATRIX_ROWS]; +static bool matrix_has_ghost_in_row(int row); + + +inline +int matrix_rows(void) { + return MATRIX_ROWS; +} + +inline +int matrix_cols(void) { + return MATRIX_COLS; +} + // this must be called once before matrix_scan. void matrix_init(void) { @@ -48,7 +61,7 @@ void matrix_init(void) matrix_prev = _matrix1; } -uint8_t matrix_scan(void) +int matrix_scan(void) { uint8_t *tmp; @@ -82,10 +95,29 @@ bool matrix_is_modified(void) { return false; } +inline bool matrix_has_ghost(void) { return false; } -bool matrix_has_ghost_in_row(uint8_t row) { +inline +uint16_t matrix_get_row(int row) { + return matrix[row]; +} + +void matrix_print(void) { + print("\nr/c 01234567\n"); + for (int row = 0; row < matrix_rows(); row++) { + phex(row); print(": "); + pbin_reverse(matrix_get_row(row)); + if (matrix_has_ghost_in_row(row)) { + print(" +#include "matrix_skel.h" + + +#define MATRIX_ROWS 8 +#define MATRIX_COLS 8 + + +extern uint8_t *matrix; +extern uint8_t *matrix_prev; + +#endif diff --git a/key_process.c b/key_process.c index 4a9e81b7..8006ae72 100644 --- a/key_process.c +++ b/key_process.c @@ -8,7 +8,7 @@ #include "usb_keyboard.h" #include "usb_mouse.h" #include "print.h" -#include "matrix.h" +#include "matrix_skel.h" #include "keymap.h" #include "jump_bootloader.h" @@ -25,150 +25,113 @@ #define MOUSE_DELAY_ACC 5 - -static void print_matrix(void); -static void print_keys(void); -static void print_mouse(int8_t mouse_x, int8_t mouse_y, int8_t wheel_v, int8_t wheel_h); - void proc_matrix(void) { static int mouse_repeat = 0; bool modified = false; - bool has_ghost = false; - int layer = 0; + //bool has_ghost = false; int key_index = 0; uint8_t mouse_btn = 0; int8_t mouse_x = 0; int8_t mouse_y = 0; int8_t mouse_wheel = 0; int8_t mouse_hwheel = 0; + int fn_bits = 0; - matrix_scan(); - modified = matrix_is_modified(); - has_ghost = matrix_has_ghost(); - layer = get_layer(); + matrix_scan(); + modified = matrix_is_modified(); - // print matrix state for debug - if (modified) { - print_matrix(); + if (modified) { + matrix_print(); - // LED flash for debug - LED_CONFIG; - LED_ON; - } + // LED flash for debug + LED_CONFIG; + LED_ON; + } - keyboard_modifier_keys = 0; - for (int i = 0; i < 6; i++) keyboard_keys[i] = KB_NO; - key_index = 0; - mouse_btn = 0; - mouse_x = 0; - mouse_y = 0; - mouse_wheel = 0; - mouse_hwheel = 0; - - // convert matrix state to HID report - for (int row = 0; row < MATRIX_ROWS; row++) { - for (int col = 0; col < MATRIX_COLS; col++) { - if (matrix[row] & 1<= MS_UP) { - // mouse - if (code == MS_UP) mouse_y -= MOUSE_MOVE_UNIT + (mouse_repeat < 50 ? mouse_repeat/5 : 10); - if (code == MS_DOWN) mouse_y += MOUSE_MOVE_UNIT + (mouse_repeat < 50 ? mouse_repeat/5 : 10); - if (code == MS_LEFT) mouse_x -= MOUSE_MOVE_UNIT + (mouse_repeat < 50 ? mouse_repeat/5 : 10); - if (code == MS_RIGHT) mouse_x += MOUSE_MOVE_UNIT + (mouse_repeat < 50 ? mouse_repeat/5 : 10); - if (code == MS_BTN1) mouse_btn |= 1<<0; - if (code == MS_BTN2) mouse_btn |= 1<<1; - if (code == MS_BTN3) mouse_btn |= 1<<2; - if (code == MS_BTN4) mouse_btn |= 1<<3; - if (code == MS_BTN5) mouse_btn |= 1<<4; - if (code == MS_WH_UP) mouse_wheel += 1; - if (code == MS_WH_DOWN) mouse_wheel -= 1; - if (code == MS_WH_LEFT) mouse_hwheel -= 1; - if (code == MS_WH_RIGHT) mouse_hwheel += 1; - } else { - // normal keys - if (key_index < 6) - keyboard_keys[key_index] = code; - key_index++; + if (matrix_has_ghost()) { + // should send error? + print("matrix has ghost!!\n"); + return; + } + + usb_keyboard_clear(); + for (int row = 0; row < matrix_rows(); row++) { + for (int col = 0; col < matrix_cols(); col++) { + if (matrix_get_row(row) & 1<= MS_UP) { + // mouse + if (code == MS_UP) mouse_y -= MOUSE_MOVE_UNIT + (mouse_repeat < 50 ? mouse_repeat/5 : 10); + if (code == MS_DOWN) mouse_y += MOUSE_MOVE_UNIT + (mouse_repeat < 50 ? mouse_repeat/5 : 10); + if (code == MS_LEFT) mouse_x -= MOUSE_MOVE_UNIT + (mouse_repeat < 50 ? mouse_repeat/5 : 10); + if (code == MS_RIGHT) mouse_x += MOUSE_MOVE_UNIT + (mouse_repeat < 50 ? mouse_repeat/5 : 10); + if (code == MS_BTN1) mouse_btn |= 1<<0; + if (code == MS_BTN2) mouse_btn |= 1<<1; + if (code == MS_BTN3) mouse_btn |= 1<<2; + if (code == MS_BTN4) mouse_btn |= 1<<3; + if (code == MS_BTN5) mouse_btn |= 1<<4; + if (code == MS_WH_UP) mouse_wheel += 1; + if (code == MS_WH_DOWN) mouse_wheel -= 1; + if (code == MS_WH_LEFT) mouse_hwheel -= 1; + if (code == MS_WH_RIGHT) mouse_hwheel += 1; + } else if (FN_0 <= code && code <= FN_7) { + fn_bits |= 1<<(code - FN_0); + } else { + // normal keys + if (key_index < 6) + keyboard_keys[key_index] = code; + key_index++; } } + } + keymap_fn_proc(fn_bits); - if (!has_ghost) { - // when 4 left modifier keys down - if (keyboard_modifier_keys == (MOD_LCTRL | MOD_LSHIFT | MOD_LALT | MOD_LGUI)) { - // cancel all keys - keyboard_modifier_keys = 0; - for (int i = 0; i < 6; i++) keyboard_keys[i] = KB_NO; - usb_keyboard_send(); - - print("jump to bootloader...\n"); - _delay_ms(100); - jump_bootloader(); // not return - } - - if (mouse_x || mouse_y || mouse_wheel || mouse_hwheel || mouse_btn != mouse_buttons) { - mouse_buttons = mouse_btn; - usb_mouse_move(mouse_x, mouse_y, mouse_wheel, mouse_hwheel); - print_mouse(mouse_x, mouse_y, mouse_wheel, mouse_hwheel); - key_sent = true; + // when 4 left modifier keys down + if (keyboard_modifier_keys == (MOD_LCTRL | MOD_LSHIFT | MOD_LALT | MOD_LGUI)) { + // cancel all keys + keyboard_modifier_keys = 0; + for (int i = 0; i < 6; i++) keyboard_keys[i] = KB_NO; + usb_keyboard_send(); - // acceleration - _delay_ms(MOUSE_DELAY_MS >> (mouse_repeat < MOUSE_DELAY_ACC ? mouse_repeat : MOUSE_DELAY_ACC)); - mouse_repeat++; - } else { - mouse_repeat = 0; - } + print("jump to bootloader...\n"); + _delay_ms(100); + jump_bootloader(); // not return + } - // send keys to host - if (modified) { - if (key_index > 6) { - //Rollover - } - usb_keyboard_send(); - if (keyboard_keys[0]) - key_sent = true; - - print_keys(); - // LED flash for debug - LED_CONFIG; - LED_OFF; - } - } -} + if (mouse_x || mouse_y || mouse_wheel || mouse_hwheel || mouse_btn != mouse_buttons) { + mouse_buttons = mouse_btn; + usb_mouse_move(mouse_x, mouse_y, mouse_wheel, mouse_hwheel); + usb_mouse_print(mouse_x, mouse_y, mouse_wheel, mouse_hwheel); -static void print_matrix(void) { - print("\nr/c 01234567\n"); - for (int row = 0; row < MATRIX_ROWS; row++) { - phex(row); print(": "); - pbin_reverse(matrix[row]); - if (matrix_has_ghost_in_row(row)) { - print(" > (mouse_repeat < MOUSE_DELAY_ACC ? mouse_repeat : MOUSE_DELAY_ACC)); + mouse_repeat++; + } else { + mouse_repeat = 0; } -} -static void print_keys(void) { - print("\nkeys: "); - for (int i = 0; i < 6; i++) { phex(keyboard_keys[i]); print(" "); } - print("\n"); - print("mods: "); phex(keyboard_modifier_keys); print("\n"); -} -static void print_mouse(int8_t mouse_x, int8_t mouse_y, int8_t wheel_v, int8_t wheel_h) { - print("\nmouse_x y v h: "); - phex(mouse_x); print(" "); - phex(mouse_y); print(" "); - phex(wheel_v); print(" "); - phex(wheel_h); print("\n"); - print("buttons: "); phex(mouse_buttons); print("\n"); + // send keys to host + if (modified) { + if (key_index > 6) { + //Rollover + } + usb_keyboard_send(); + + usb_keyboard_print(); + // LED flash for debug + LED_CONFIG; + LED_OFF; + } } diff --git a/key_process.h b/key_process.h index 10577dd5..bfc0218f 100644 --- a/key_process.h +++ b/key_process.h @@ -1,6 +1,7 @@ #ifndef KEY_PROCESS_H #define KEY_PROCESS_H 1 + void proc_matrix(void); #endif diff --git a/keymap_skel.h b/keymap_skel.h new file mode 100644 index 00000000..51906d36 --- /dev/null +++ b/keymap_skel.h @@ -0,0 +1,17 @@ +#ifndef KEYMAP_SKEL_H +#define KEYMAP_SKEL_H 1 + +#include +#include +#include "usb_keycodes.h" + + +uint8_t keymap_get_keycode(int row, int col); +uint8_t keymap_get_keycodel(int layer, int row, int col); +int keymap_get_layer(void); +int keymap_set_layer(int layer); + +/* process Fn keys. This.should be called every scan. */ +void keymap_fn_proc(int fn_bits); + +#endif diff --git a/matrix.h b/matrix.h deleted file mode 100644 index 74b5f894..00000000 --- a/matrix.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef MATRIX_H -#define MATRIX_H 1 - -#include - -extern uint8_t *matrix; -extern uint8_t *matrix_prev; - -void matrix_init(void); -uint8_t matrix_scan(void); -bool matrix_is_modified(void); -bool matrix_has_ghost(void); -bool matrix_has_ghost_in_row(uint8_t row); - -#endif diff --git a/matrix_skel.h b/matrix_skel.h new file mode 100644 index 00000000..0d483034 --- /dev/null +++ b/matrix_skel.h @@ -0,0 +1,24 @@ +#ifndef MATRIX_SKEL_H +#define MATRIX_SKEL_H 1 + +#include + +/* number of matrix rows */ +int matrix_rows(void); +/* number of matrix columns */ +int matrix_cols(void); +/* intialize matrix for scaning. should be called once. */ +void matrix_init(void); +/* scan all key states on matrix */ +int matrix_scan(void); +/* whether modified from previous scan. used after matrix_scan. */ +bool matrix_is_modified(void); +/* whether ghosting occur on matrix. */ +bool matrix_has_ghost(void); +/* matrix state on row */ +uint16_t matrix_get_row(int row); +/* print matrix for debug */ +void matrix_print(void); + + +#endif diff --git a/tmk.c b/tmk.c index c0197251..cd52d318 100644 --- a/tmk.c +++ b/tmk.c @@ -34,7 +34,7 @@ #include "usb_keyboard.h" #include "usb_mouse.h" #include "print.h" -#include "matrix.h" +#include "matrix_skel.h" #include "keymap.h" #include "jump_bootloader.h" diff --git a/usb_keyboard.c b/usb_keyboard.c index 9d41e8bc..44365bb8 100644 --- a/usb_keyboard.c +++ b/usb_keyboard.c @@ -1,8 +1,11 @@ #include #include #include "usb_keyboard.h" +#include "print.h" +static bool is_sent = false; + // which modifier keys are currently pressed // 1=left ctrl, 2=left shift, 4=left alt, 8=left gui // 16=right ctrl, 32=right shift, 64=right alt, 128=right gui @@ -72,5 +75,45 @@ int8_t usb_keyboard_send(void) UEINTX = 0x3A; keyboard_idle_count = 0; SREG = intr_state; + is_sent = true; return 0; } + +void usb_keyboard_init(void) { + usb_keyboard_clear(); + is_sent = false; +} + +void usb_keyboard_clear(void) { + usb_keyboard_clear_key(); + usb_keyboard_clear_mod(); +} + +void usb_keyboard_clear_key(void) { + for (int i = 0; i < 6; i++) keyboard_keys[i] = 0; +} + +void usb_keyboard_clear_mod(void) { + keyboard_modifier_keys = 0; +} + +bool usb_keyboard_is_sent(void) { + return is_sent; +} + +bool usb_keyboard_has_key(void) { + uint8_t keys = 0; + for (int i = 0; i < 6; i++) keys |= keyboard_keys[i]; + return keys ? true : false; +} + +bool usb_keyboard_has_mod(void) { + return keyboard_modifier_keys ? true : false; +} + +void usb_keyboard_print(void) { + print("\nkeys: "); + for (int i = 0; i < 6; i++) { phex(keyboard_keys[i]); print(" "); } + print("\n"); + print("mods: "); phex(keyboard_modifier_keys); print("\n"); +} diff --git a/usb_keyboard.h b/usb_keyboard.h index 90c2c5af..2420745e 100644 --- a/usb_keyboard.h +++ b/usb_keyboard.h @@ -2,6 +2,7 @@ #define USB_KEYBOARD_H 1 #include +#include #include "usb.h" @@ -10,6 +11,7 @@ #define KEYBOARD_SIZE 8 #define KEYBOARD_BUFFER EP_DOUBLE_BUFFER +// TODO: move to usb_keycodes.h ? // modifier bits #define MOD_LCTRL (1<<0) #define MOD_LSHIFT (1<<1) @@ -21,15 +23,24 @@ #define MOD_RGUI (1<<7) +// TODO: change variable name: usb_keyboard_ or usb_kb_ extern uint8_t keyboard_modifier_keys; extern uint8_t keyboard_keys[6]; extern uint8_t keyboard_protocol; extern uint8_t keyboard_idle_config; extern uint8_t keyboard_idle_count; -extern volatile uint8_t keyboard_leds; +extern volatile uint8_t keyboard_leds; // TODO: delete NOT USED? int8_t usb_keyboard_press(uint8_t key, uint8_t modifier); int8_t usb_keyboard_send(void); +void usb_keyboard_init(void); +void usb_keyboard_clear(void); +void usb_keyboard_clear_key(void); +void usb_keyboard_clear_mod(void); +bool usb_keyboard_is_sent(void); +bool usb_keyboard_has_key(void); +bool usb_keyboard_has_mod(void); +void usb_keyboard_print(void); #endif diff --git a/usb_keycodes.h b/usb_keycodes.h index 9573344c..3652bcab 100644 --- a/usb_keycodes.h +++ b/usb_keycodes.h @@ -262,10 +262,14 @@ enum keycodes { KB_RGUI, /* 0x80 */ /* extensions for internal use */ - FN_1 = 0xE8, + FN_0 = 0xE8, + FN_1, FN_2, FN_3, FN_4, + FN_5, + FN_6, + FN_7, MS_UP = 0xF0, MS_DOWN, MS_LEFT, diff --git a/usb_mouse.c b/usb_mouse.c index c2617a5e..6eb47dde 100644 --- a/usb_mouse.c +++ b/usb_mouse.c @@ -1,8 +1,11 @@ #include #include #include "usb_mouse.h" +#include "print.h" +static bool is_sent = false; + // which buttons are currently pressed uint8_t mouse_buttons=0; @@ -60,5 +63,23 @@ int8_t usb_mouse_move(int8_t x, int8_t y, int8_t wheel, int8_t hwheel) UEINTX = 0x3A; SREG = intr_state; + is_sent = true; return 0; } + +void usb_mouse_clear(void) { + is_sent = false; +} + +bool usb_mouse_is_sent(void) { + return is_sent; +} + +void usb_mouse_print(int8_t mouse_x, int8_t mouse_y, int8_t wheel_v, int8_t wheel_h) { + print("mouse btn|x y v h: "); + phex(mouse_buttons); print("|"); + phex(mouse_x); print(" "); + phex(mouse_y); print(" "); + phex(wheel_v); print(" "); + phex(wheel_h); print("\n"); +} diff --git a/usb_mouse.h b/usb_mouse.h index 81edabcb..b62dde13 100644 --- a/usb_mouse.h +++ b/usb_mouse.h @@ -2,6 +2,7 @@ #define USB_MOUSE_H 1 #include +#include #include "usb.h" @@ -16,5 +17,8 @@ extern uint8_t mouse_protocol; int8_t usb_mouse_buttons(uint8_t left, uint8_t middle, uint8_t right); int8_t usb_mouse_move(int8_t x, int8_t y, int8_t wheel, int8_t hwheel); +void usb_mouse_clear(void); +bool usb_mouse_is_sent(void); +void usb_mouse_print(int8_t mouse_x, int8_t mouse_y, int8_t wheel_v, int8_t wheel_h); #endif