diff --git a/Makefile.common b/Makefile.common index 5c34be4e..ae2a562c 100644 --- a/Makefile.common +++ b/Makefile.common @@ -1,4 +1,5 @@ SRC += keyboard.c \ + command.c \ layer.c \ timer.c \ print.c \ diff --git a/hhkb/Makefile b/hhkb/Makefile index f008b6ec..8e771d95 100644 --- a/hhkb/Makefile +++ b/hhkb/Makefile @@ -9,7 +9,6 @@ TARGET_DIR = . # keyboard dependent files TARGET_SRC = tmk.c \ - key_process.c \ host_pjrc.c \ keymap.c \ matrix.c \ diff --git a/hhkb/keymap.c b/hhkb/keymap.c index 8b43b2a0..137ab7de 100644 --- a/hhkb/keymap.c +++ b/hhkb/keymap.c @@ -4,7 +4,7 @@ #include #include #include -#include "keyboard.h" +#include "host.h" #include "usb_keycodes.h" #include "print.h" #include "debug.h" @@ -177,5 +177,5 @@ uint8_t keymap_fn_keycode(uint8_t fn_bits) // define a condition to enter special function mode bool keymap_is_special_mode(uint8_t fn_bits) { - return keyboard_get_mods() == (BIT_LSHIFT | BIT_RSHIFT) || keyboard_get_mods() == (BIT_LCTRL | BIT_RSHIFT); + return host_get_mods() == (BIT_LSHIFT | BIT_RSHIFT) || host_get_mods() == (BIT_LCTRL | BIT_RSHIFT); } diff --git a/host.h b/host.h index fa7e7991..f2c8085c 100644 --- a/host.h +++ b/host.h @@ -4,7 +4,21 @@ #include -#define REPORT_KEYS 6 +/* keyboard Modifiers in boot protocol report */ +#define BIT_LCTRL (1<<0) +#define BIT_LSHIFT (1<<1) +#define BIT_LALT (1<<2) +#define BIT_LGUI (1<<3) +#define BIT_RCTRL (1<<4) +#define BIT_RSHIFT (1<<5) +#define BIT_RALT (1<<6) +#define BIT_RGUI (1<<7) +#define BIT_LCTL BIT_LCTRL +#define BIT_RCTL BIT_RCTRL +#define BIT_LSFT BIT_LSHIFT +#define BIT_RSFT BIT_RSHIFT + +/* mouse buttons */ #define MOUSE_BTN1 (1<<0) #define MOUSE_BTN2 (1<<1) #define MOUSE_BTN3 (1<<2) @@ -12,9 +26,10 @@ #define MOUSE_BTN5 (1<<4) +#define REPORT_KEYS 6 typedef struct { uint8_t mods; - uint8_t rserved; // not used + uint8_t rserved; uint8_t keys[REPORT_KEYS]; } report_keyboard_t; @@ -29,8 +44,24 @@ typedef struct { } report_mouse_t; -extern uint8_t host_keyboard_led; -void host_keyboard_send(report_keyboard_t *report); +extern report_keyboard_t *keyboard_report; +extern report_keyboard_t *keyboard_report_prev; + + +/* keyboard report operations */ +void host_add_key(uint8_t key); +void host_add_mod_bit(uint8_t mod); +void host_set_mods(uint8_t mods); +void host_add_code(uint8_t code); +void host_swap_keyboard_report(void); +void host_clear_keyboard_report(void); +uint8_t host_has_anykey(void); +uint8_t *host_get_keys(void); +uint8_t host_get_mods(void); + + +void host_send_keyboard_report(void); +void host_send_mouse_report(void); void host_mouse_send(report_mouse_t *report); #endif diff --git a/keyboard.c b/keyboard.c index 6bf2b3a9..cb1c745e 100644 --- a/keyboard.c +++ b/keyboard.c @@ -1,93 +1,132 @@ -#include "usb_keycodes.h" +#include "keyboard.h" #include "host.h" +#include "layer.h" +#include "matrix_skel.h" #include "led.h" -#include "keyboard.h" +#include "usb_keycodes.h" +#include "timer.h" #include "print.h" +#include "debug.h" +#include "command.h" +#ifdef MOUSEKEY_ENABLE +#include "mousekey.h" +#endif -static report_keyboard_t report0; -static report_keyboard_t report1; -report_keyboard_t *keyboard_report = &report0; -report_keyboard_t *keyboard_report_prev = &report1; +static uint8_t last_led = 0; -void keyboard_set_led(uint8_t usb_led) -{ - led_set(usb_led); -} -void keyboard_send(void) +void keyboard_init(void) { - host_keyboard_send(keyboard_report); + timer_init(); + matrix_init(); +#ifdef PS2_MOUSE_ENABLE + ps2_mouse_init(); +#endif } -void keyboard_add_key(uint8_t code) +void keyboard_proc(void) { - int8_t i = 0; - int8_t empty = -1; - for (; i < REPORT_KEYS; i++) { - if (keyboard_report_prev->keys[i] == code) { - keyboard_report->keys[i] = code; - break; - } - if (empty == -1 && keyboard_report_prev->keys[i] == KB_NO && keyboard_report->keys[i] == KB_NO) { - empty = i; - } + uint8_t fn_bits = 0; + + matrix_scan(); + + if (matrix_is_modified()) { + if (debug_matrix) matrix_print(); +#ifdef DEBUG_LED + // LED flash for debug + DEBUG_LED_CONFIG; + DEBUG_LED_ON; +#endif } - if (i == REPORT_KEYS && empty != -1) { - keyboard_report->keys[empty] = code; + + if (matrix_has_ghost()) { + // should send error? + debug("matrix has ghost!!\n"); + return; } -} -void keyboard_add_mod_bit(uint8_t mod) -{ - keyboard_report->mods |= mod; -} + host_swap_keyboard_report(); + host_clear_keyboard_report(); + for (int row = 0; row < matrix_rows(); row++) { + for (int col = 0; col < matrix_cols(); col++) { + if (!matrix_is_on(row, col)) continue; -void keyboard_set_mods(uint8_t mods) -{ - keyboard_report->mods = mods; -} - -void keyboard_add_code(uint8_t code) -{ - if (IS_MOD(code)) { - keyboard_add_mod_bit(MOD_BIT(code)); - } else { - keyboard_add_key(code); + uint8_t code = layer_get_keycode(row, col); + if (code == KB_NO) { + // do nothing + } else if (IS_MOD(code)) { + host_add_mod_bit(MOD_BIT(code)); + } else if (IS_FN(code)) { + fn_bits |= FN_BIT(code); + } +#ifdef USB_EXTRA_ENABLE +/* TODO: use new API + // audio control & system control + else if (code == KB_MUTE) { + usb_extra_audio_send(AUDIO_MUTE); + usb_extra_audio_send(0); + _delay_ms(500); + } else if (code == KB_VOLU) { + usb_extra_audio_send(AUDIO_VOL_UP); + usb_extra_audio_send(0); + _delay_ms(200); + } else if (code == KB_VOLD) { + usb_extra_audio_send(AUDIO_VOL_DOWN); + usb_extra_audio_send(0); + _delay_ms(200); + } else if (code == KB_PWR) { + if (suspend && remote_wakeup) { + usb_remote_wakeup(); + } else { + usb_extra_system_send(SYSTEM_POWER_DOWN); + } + _delay_ms(1000); + } +*/ +#endif + else if (IS_KEY(code)) { + host_add_key(code); + } +#ifdef MOUSEKEY_ENABLE + else if (IS_MOUSEKEY(code)) { + mousekey_decode(code); + } +#endif + else { + debug("ignore keycode: "); debug_hex(code); debug("\n"); + } + } } -} -void keyboard_swap_report(void) -{ - report_keyboard_t *tmp = keyboard_report_prev; - keyboard_report_prev = keyboard_report; - keyboard_report = tmp; -} + layer_switching(fn_bits); -void keyboard_clear_report(void) -{ - keyboard_report->mods = 0; - for (int8_t i = 0; i < REPORT_KEYS; i++) { - keyboard_report->keys[i] = 0; + if (command_proc()) { + // not send report + return; } -} -uint8_t keyboard_has_anykey(void) -{ - uint8_t cnt = 0; - for (int i = 0; i < REPORT_KEYS; i++) { - if (keyboard_report->keys[i]) - cnt++; + if (matrix_is_modified()) { + host_send_keyboard_report(); +#ifdef DEBUG_LED + // LED flash for debug + DEBUG_LED_CONFIG; + DEBUG_LED_OFF; +#endif } - return cnt; -} -uint8_t *keyboard_get_keys(void) -{ - return keyboard_report->keys; -} +#ifdef MOUSEKEY_ENABLE + mousekey_send(); +#endif -uint8_t keyboard_get_mods(void) -{ - return keyboard_report->mods; +#ifdef PS2_MOUSE_ENABLE + // TODO: should comform new API + if (ps2_mouse_read() == 0) + ps2_mouse_usb_send(); +#endif + + if (last_led != host_keyboard_led()) { + led_set(host_keyboard_led()); + last_led = host_keyboard_led(); + } } diff --git a/keyboard.h b/keyboard.h index 2c2d43ac..5d269e96 100644 --- a/keyboard.h +++ b/keyboard.h @@ -1,42 +1,9 @@ #ifndef KEYBOARD_H #define KEYBOARD_H -#include -#include -#include "host.h" - -/* keyboard Modifiers in boot protocol report */ -#define BIT_LCTRL (1<<0) -#define BIT_LSHIFT (1<<1) -#define BIT_LALT (1<<2) -#define BIT_LGUI (1<<3) -#define BIT_RCTRL (1<<4) -#define BIT_RSHIFT (1<<5) -#define BIT_RALT (1<<6) -#define BIT_RGUI (1<<7) -#define BIT_LCTL BIT_LCTRL -#define BIT_RCTL BIT_RCTRL -#define BIT_LSFT BIT_LSHIFT -#define BIT_RSFT BIT_RSHIFT - - -extern report_keyboard_t *keyboard_report; -extern report_keyboard_t *keyboard_report_prev; - -void keyboard_set_led(uint8_t led); -void keyboard_send(void); - -void keyboard_add_key(uint8_t key); -void keyboard_add_mod_bit(uint8_t mod); -void keyboard_set_mods(uint8_t mods); -void keyboard_add_code(uint8_t code); -void keyboard_swap_report(void); -void keyboard_clear_report(void); - -uint8_t keyboard_has_anykey(void); -uint8_t *keyboard_get_keys(void); -uint8_t keyboard_get_mods(void); +void keyboard_init(void); +void keyboard_proc(void); #endif diff --git a/layer.c b/layer.c index 0e88d53d..7138c0ed 100644 --- a/layer.c +++ b/layer.c @@ -1,5 +1,5 @@ #include "keymap_skel.h" -#include "keyboard.h" +#include "host.h" #include "debug.h" #include "timer.h" #include "layer.h" @@ -98,23 +98,23 @@ void layer_switching(uint8_t fn_bits) debug(" -> "); debug_hex(current_layer); debug("\n"); } } else { - if (keyboard_has_anykey()) { // other keys is pressed + if (host_has_anykey()) { // other keys is pressed uint8_t _fn_to_send = BIT_SUBT(fn_bits, sent_fn); if (_fn_to_send) { debug("Fn case: 4(send Fn before other key pressed)\n"); // send only Fn key first - keyboard_swap_report(); - keyboard_clear_report(); - keyboard_add_code(keymap_fn_keycode(_fn_to_send)); // TODO: do all Fn keys - keyboard_set_mods(last_mods); - keyboard_send(); - keyboard_swap_report(); + host_swap_keyboard_report(); + host_clear_keyboard_report(); + host_add_code(keymap_fn_keycode(_fn_to_send)); // TODO: do all Fn keys + host_set_mods(last_mods); + host_send_keyboard_report(); + host_swap_keyboard_report(); sent_fn |= _fn_to_send; } } } // add Fn keys to send - //keyboard_add_code(keymap_fn_keycode(fn_bits&sent_fn)); // TODO: do all Fn keys + //host_add_code(keymap_fn_keycode(fn_bits&sent_fn)); // TODO: do all Fn keys } } else { // Fn state is changed(edge) uint8_t fn_changed = 0; @@ -128,7 +128,7 @@ void layer_switching(uint8_t fn_bits) // pressed Fn if ((fn_changed = BIT_SUBT(fn_bits, last_fn))) { debug("fn_changed: "); debug_bin(fn_changed); debug("\n"); - if (keyboard_has_anykey()) { + if (host_has_anykey()) { debug("Fn case: 5(pressed Fn with other key)\n"); sent_fn |= fn_changed; } else if (fn_changed & sent_fn) { // pressed same Fn in a row @@ -149,12 +149,12 @@ void layer_switching(uint8_t fn_bits) if (BIT_SUBT(fn_changed, sent_fn)) { // layer not used && Fn not sent debug("Fn case: 2(send Fn one shot: released Fn during LAYER_SEND_FN_TERM)\n"); // send only Fn key first - keyboard_swap_report(); - keyboard_clear_report(); - keyboard_add_code(keymap_fn_keycode(fn_changed)); // TODO: do all Fn keys - keyboard_set_mods(last_mods); - keyboard_send(); - keyboard_swap_report(); + host_swap_keyboard_report(); + host_clear_keyboard_report(); + host_add_code(keymap_fn_keycode(fn_changed)); // TODO: do all Fn keys + host_set_mods(last_mods); + host_send_keyboard_report(); + host_swap_keyboard_report(); sent_fn |= fn_changed; } } @@ -171,7 +171,7 @@ void layer_switching(uint8_t fn_bits) // send Fn keys for (uint8_t i = 0; i < 8; i++) { if ((sent_fn & fn_bits) & (1< -uint8_t default_layer; -uint8_t current_layer; +extern uint8_t default_layer; +extern uint8_t current_layer; /* return keycode for switch */ uint8_t layer_get_keycode(uint8_t row, uint8_t col); diff --git a/mousekey.c b/mousekey.c index 38a8c2e4..2e9b8cb1 100644 --- a/mousekey.c +++ b/mousekey.c @@ -1,18 +1,20 @@ #include #include #include "usb_keycodes.h" -#include "usb_mouse.h" +#include "host.h" +#include "timer.h" +#include "print.h" +#include "debug.h" #include "mousekey.h" -static int8_t mousekey_x = 0; -static int8_t mousekey_y = 0; -static int8_t mousekey_v = 0; -static int8_t mousekey_h = 0; -static uint8_t mousekey_btn = 0; -static uint8_t mousekey_btn_prev = 0; +static report_mouse_t report; +static report_mouse_t report_prev; + static uint8_t mousekey_repeat = 0; +static void mousekey_debug(void); + /* * TODO: fix acceleration algorithm @@ -25,51 +27,95 @@ static uint8_t mousekey_repeat = 0; static inline uint8_t move_unit(void) { - return 10 + (mousekey_repeat < 50 ? mousekey_repeat/5 : 10); + uint16_t unit = 10 + (mousekey_repeat); + return (unit > 127 ? 127 : unit); } void mousekey_decode(uint8_t code) { - if (code == KB_MS_UP) mousekey_y -= move_unit(); - else if (code == KB_MS_DOWN) mousekey_y += move_unit(); - else if (code == KB_MS_LEFT) mousekey_x -= move_unit(); - else if (code == KB_MS_RIGHT) mousekey_x += move_unit(); - else if (code == KB_MS_BTN1) mousekey_btn |= MOUSE_BTN1; - else if (code == KB_MS_BTN2) mousekey_btn |= MOUSE_BTN2; - else if (code == KB_MS_BTN3) mousekey_btn |= MOUSE_BTN3; - else if (code == KB_MS_BTN4) mousekey_btn |= MOUSE_BTN4; - else if (code == KB_MS_BTN5) mousekey_btn |= MOUSE_BTN5; - else if (code == KB_MS_WH_UP) mousekey_v += 1; - else if (code == KB_MS_WH_DOWN) mousekey_v -= 1; - else if (code == KB_MS_WH_LEFT) mousekey_h -= 1; - else if (code == KB_MS_WH_RIGHT) mousekey_h += 1; + if (code == KB_MS_UP) report.y = -move_unit(); + else if (code == KB_MS_DOWN) report.y = move_unit(); + else if (code == KB_MS_LEFT) report.x = -move_unit(); + else if (code == KB_MS_RIGHT) report.x = move_unit(); + else if (code == KB_MS_BTN1) report.buttons |= MOUSE_BTN1; + else if (code == KB_MS_BTN2) report.buttons |= MOUSE_BTN2; + else if (code == KB_MS_BTN3) report.buttons |= MOUSE_BTN3; +/* + else if (code == KB_MS_BTN4) report.buttons |= MOUSE_BTN4; + else if (code == KB_MS_BTN5) report.buttons |= MOUSE_BTN5; + else if (code == KB_MS_WH_UP) report.v += 1; + else if (code == KB_MS_WH_DOWN) report.v -= 1; + else if (code == KB_MS_WH_LEFT) report.h -= 1; + else if (code == KB_MS_WH_RIGHT)report.h += 1; +*/ } bool mousekey_changed(void) { - return (mousekey_x || mousekey_y || mousekey_v || mousekey_h || mousekey_btn != mousekey_btn_prev); + return (report.buttons != report_prev.buttons || + report.x != report_prev.x || + report.y != report_prev.y || + report.x || report.y); + //return (report.buttons != report_prev.buttons || report.x || report.y); } -void mousekey_usb_send(void) +void mousekey_send(void) { - if (mousekey_changed()) { - mousekey_btn_prev = mousekey_btn; - if (mousekey_x && mousekey_y) - usb_mouse_send(mousekey_x*0.7, mousekey_y*0.7, mousekey_v, mousekey_h, mousekey_btn); - else - usb_mouse_send(mousekey_x, mousekey_y, mousekey_v, mousekey_h, mousekey_btn); - - usb_mouse_print(mousekey_x, mousekey_y, mousekey_v, mousekey_h, mousekey_btn); - - if (mousekey_x || mousekey_y || mousekey_v || mousekey_h) - _delay_ms(MOUSEKEY_DELAY_TIME >> (mousekey_repeat < 5 ? mousekey_repeat : 4)); - mousekey_repeat++; - } else { + static uint16_t last_timer = 0; + + if (!mousekey_changed()) { mousekey_repeat = 0; + return; } - mousekey_x = 0; - mousekey_y = 0; - mousekey_v = 0; - mousekey_h = 0; - mousekey_btn = 0; + + // send immediately when buttun state is changed + if (report.buttons == report_prev.buttons) { + // TODO: delay parameter setting + if ((timer_elapsed(last_timer) < (mousekey_repeat == 1 ? 20 : 5))) { + return; + } + } + + if (report.x && report.y) { + report.x *= 0.7; + report.y *= 0.7; + } + + /* + print("mousekey_repeat: "); phex(mousekey_repeat); print("\n"); + print("timer: "); phex16(timer_read()); print("\n"); + print("last_timer: "); phex16(last_timer); print("\n"); + print("mousekey: "); phex(report.buttons); print(" "); phex(report.x); print(" "); phex(report.y); print("\n"); + */ + + mousekey_debug(); + + host_mouse_send(&report); + report_prev.buttons = report.buttons; + report_prev.x = report.x; + report_prev.y = report.y; + if (mousekey_repeat != 0xFF) mousekey_repeat++; + last_timer = timer_read(); + mousekey_clear_report(); +} + +void mousekey_clear_report(void) +{ + report.buttons = 0; + report.x = 0; + report.y = 0; +} + +static void mousekey_debug(void) +{ + if (!debug_mouse) return; + print("mousekey[btn|x y v h]: "); + phex(report.buttons); print("|"); + phex(report.x); print(" "); + phex(report.y); print(" "); +/* + phex(report.v); print(" "); + phex(report.h); +*/ + print("\n"); } diff --git a/mousekey.c.bak b/mousekey.c.bak new file mode 100644 index 00000000..38a8c2e4 --- /dev/null +++ b/mousekey.c.bak @@ -0,0 +1,75 @@ +#include +#include +#include "usb_keycodes.h" +#include "usb_mouse.h" +#include "mousekey.h" + + +static int8_t mousekey_x = 0; +static int8_t mousekey_y = 0; +static int8_t mousekey_v = 0; +static int8_t mousekey_h = 0; +static uint8_t mousekey_btn = 0; +static uint8_t mousekey_btn_prev = 0; +static uint8_t mousekey_repeat = 0; + + +/* + * TODO: fix acceleration algorithm + * see wikipedia http://en.wikipedia.org/wiki/Mouse_keys + */ +#ifndef MOUSEKEY_DELAY_TIME +# define MOUSEKEY_DELAY_TIME 255 +#endif + + +static inline uint8_t move_unit(void) +{ + return 10 + (mousekey_repeat < 50 ? mousekey_repeat/5 : 10); +} + +void mousekey_decode(uint8_t code) +{ + if (code == KB_MS_UP) mousekey_y -= move_unit(); + else if (code == KB_MS_DOWN) mousekey_y += move_unit(); + else if (code == KB_MS_LEFT) mousekey_x -= move_unit(); + else if (code == KB_MS_RIGHT) mousekey_x += move_unit(); + else if (code == KB_MS_BTN1) mousekey_btn |= MOUSE_BTN1; + else if (code == KB_MS_BTN2) mousekey_btn |= MOUSE_BTN2; + else if (code == KB_MS_BTN3) mousekey_btn |= MOUSE_BTN3; + else if (code == KB_MS_BTN4) mousekey_btn |= MOUSE_BTN4; + else if (code == KB_MS_BTN5) mousekey_btn |= MOUSE_BTN5; + else if (code == KB_MS_WH_UP) mousekey_v += 1; + else if (code == KB_MS_WH_DOWN) mousekey_v -= 1; + else if (code == KB_MS_WH_LEFT) mousekey_h -= 1; + else if (code == KB_MS_WH_RIGHT) mousekey_h += 1; +} + +bool mousekey_changed(void) +{ + return (mousekey_x || mousekey_y || mousekey_v || mousekey_h || mousekey_btn != mousekey_btn_prev); +} + +void mousekey_usb_send(void) +{ + if (mousekey_changed()) { + mousekey_btn_prev = mousekey_btn; + if (mousekey_x && mousekey_y) + usb_mouse_send(mousekey_x*0.7, mousekey_y*0.7, mousekey_v, mousekey_h, mousekey_btn); + else + usb_mouse_send(mousekey_x, mousekey_y, mousekey_v, mousekey_h, mousekey_btn); + + usb_mouse_print(mousekey_x, mousekey_y, mousekey_v, mousekey_h, mousekey_btn); + + if (mousekey_x || mousekey_y || mousekey_v || mousekey_h) + _delay_ms(MOUSEKEY_DELAY_TIME >> (mousekey_repeat < 5 ? mousekey_repeat : 4)); + mousekey_repeat++; + } else { + mousekey_repeat = 0; + } + mousekey_x = 0; + mousekey_y = 0; + mousekey_v = 0; + mousekey_h = 0; + mousekey_btn = 0; +} diff --git a/mousekey.h b/mousekey.h index c5d4561c..ea9b4f27 100644 --- a/mousekey.h +++ b/mousekey.h @@ -2,10 +2,11 @@ #define MOUSEKEY_H #include +#include "host.h" void mousekey_decode(uint8_t code); bool mousekey_changed(void); -void mousekey_usb_send(void); +void mousekey_send(void); +void mousekey_clear_report(void); #endif - diff --git a/ps2_vusb/mousekey.h b/mousekey.h.bak similarity index 63% rename from ps2_vusb/mousekey.h rename to mousekey.h.bak index ea9b4f27..c5d4561c 100644 --- a/ps2_vusb/mousekey.h +++ b/mousekey.h.bak @@ -2,11 +2,10 @@ #define MOUSEKEY_H #include -#include "host.h" void mousekey_decode(uint8_t code); bool mousekey_changed(void); -void mousekey_send(void); -void mousekey_clear_report(void); +void mousekey_usb_send(void); #endif + diff --git a/ps2.c b/ps2.c index f7aaf96e..6d76538f 100644 --- a/ps2.c +++ b/ps2.c @@ -190,7 +190,7 @@ static inline void pbuf_enqueue(uint8_t data) pbuf[pbuf_head] = data; pbuf_head = next; } else { - print("pbuf: full\n"); + debug("pbuf: full\n"); } } static inline uint8_t pbuf_dequeue(void) @@ -214,14 +214,12 @@ uint8_t ps2_host_recv(void) ISR(PS2_INT_VECT) { -PORTC = 0xFF; /* interrupt means start bit comes */ pbuf_enqueue(recv_data()); /* release lines(idle state) */ idle(); _delay_us(5); -PORTC = 0x00; } #endif diff --git a/ps2_mouse.c b/ps2_mouse.c index 7ff98824..d6db0902 100644 --- a/ps2_mouse.c +++ b/ps2_mouse.c @@ -50,6 +50,8 @@ uint8_t ps2_mouse_init(void) { if (!ps2_mouse_enable) return 1; + ps2_host_init(); + // Reset rcv = ps2_host_send(0xFF); print("ps2_mouse_init: send 0xFF: "); diff --git a/ps2_vusb/config.h b/ps2_vusb/config.h index 639a1ac7..b037bbe9 100644 --- a/ps2_vusb/config.h +++ b/ps2_vusb/config.h @@ -23,6 +23,12 @@ # define MOUSEKEY_DELAY_TIME 255 #endif +#define IS_COMMAND() ( \ + keyboard_report->mods == (BIT_LSHIFT | BIT_RSHIFT) || \ + keyboard_report->mods == (BIT_LCTRL | BIT_RSHIFT) \ +) + + /* PS/2 lines */ #define PS2_CLOCK_PORT PORTD #define PS2_CLOCK_PIN PIND @@ -39,6 +45,7 @@ EICRA |= ((1<keys[i] == code) { + keyboard_report->keys[i] = code; + break; + } + if (empty == -1 && keyboard_report_prev->keys[i] == KB_NO && keyboard_report->keys[i] == KB_NO) { + empty = i; + } + } + if (i == REPORT_KEYS && empty != -1) { + keyboard_report->keys[empty] = code; + } +} + +void host_add_mod_bit(uint8_t mod) +{ + keyboard_report->mods |= mod; +} + +void host_set_mods(uint8_t mods) +{ + keyboard_report->mods = mods; +} + +void host_add_code(uint8_t code) +{ + if (IS_MOD(code)) { + host_add_mod_bit(MOD_BIT(code)); + } else { + host_add_key(code); + } +} + +void host_swap_keyboard_report(void) +{ + report_keyboard_t *tmp = keyboard_report_prev; + keyboard_report_prev = keyboard_report; + keyboard_report = tmp; +} + +void host_clear_keyboard_report(void) +{ + keyboard_report->mods = 0; + for (int8_t i = 0; i < REPORT_KEYS; i++) { + keyboard_report->keys[i] = 0; + } +} + +uint8_t host_has_anykey(void) +{ + uint8_t cnt = 0; + for (int i = 0; i < REPORT_KEYS; i++) { + if (keyboard_report->keys[i]) + cnt++; + } + return cnt; +} + +uint8_t *host_get_keys(void) +{ + return keyboard_report->keys; +} + +uint8_t host_get_mods(void) +{ + return keyboard_report->mods; +} + + +/*------------------------------------------------------------------* + * Keyboard report send buffer + *------------------------------------------------------------------*/ #define KBUF_SIZE 16 static report_keyboard_t kbuf[KBUF_SIZE]; static uint8_t kbuf_head = 0; static uint8_t kbuf_tail = 0; - -void host_vusb_keyboard_send() +void host_vusb_keyboard_send(void) { while (usbInterruptIsReady() && kbuf_head != kbuf_tail) { usbSetInterrupt((void *)&kbuf[kbuf_tail], sizeof(report_keyboard_t)); @@ -20,30 +113,32 @@ void host_vusb_keyboard_send() } } -void host_keyboard_send(report_keyboard_t *report) +void host_send_keyboard_report(void) { uint8_t next = (kbuf_head + 1) % KBUF_SIZE; if (next != kbuf_tail) { - kbuf[kbuf_head] = *report; + kbuf[kbuf_head] = *keyboard_report; kbuf_head = next; - print("kbuf: "); phex(kbuf_head); phex(kbuf_tail); print("\n"); } else { - print("kbuf: full\n"); + debug("kbuf: full\n"); } } + void host_mouse_send(report_mouse_t *report) { if (usbInterruptIsReady3()) { usbSetInterrupt3((void *)report, sizeof(*report)); } else { - print("Int3 not ready\n"); + debug("Int3 not ready\n"); } } - +/*------------------------------------------------------------------* + * Request from host * + *------------------------------------------------------------------*/ static struct { uint16_t len; enum { @@ -52,47 +147,36 @@ static struct { } kind; } last_req; -uint8_t host_keyboard_led = 0; -static uchar idleRate; - usbMsgLen_t usbFunctionSetup(uchar data[8]) { usbRequest_t *rq = (void *)data; - //print("Setup: "); if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){ /* class request type */ - /* - print("CLASS: "); - phex(rq->bRequest); print(" "); - phex16(rq->wValue.word); print(" "); - phex16(rq->wIndex.word); print(" "); - phex16(rq->wLength.word); print(" "); - */ if(rq->bRequest == USBRQ_HID_GET_REPORT){ - print(" GET_REPORT"); + debug(" GET_REPORT"); /* we only have one report type, so don't look at wValue */ usbMsgPtr = (void *)keyboard_report; return sizeof(*keyboard_report); }else if(rq->bRequest == USBRQ_HID_GET_IDLE){ - print(" GET_IDLE: "); - phex(idleRate); + debug(" GET_IDLE: "); + debug_hex(idleRate); usbMsgPtr = &idleRate; return 1; }else if(rq->bRequest == USBRQ_HID_SET_IDLE){ idleRate = rq->wValue.bytes[1]; - print(" SET_IDLE: "); - phex(idleRate); + debug(" SET_IDLE: "); + debug_hex(idleRate); }else if(rq->bRequest == USBRQ_HID_SET_REPORT){ - //print(" SET_REPORT: "); + //debug(" SET_REPORT: "); if (rq->wValue.word == 0x0200 && rq->wIndex.word == 0) { last_req.kind = SET_LED; last_req.len = rq->wLength.word; } return USB_NO_MSG; // to get data in usbFunctionWrite } - print("\n"); + debug("\n"); }else{ - print("VENDOR\n"); + debug("VENDOR\n"); /* no vendor specific requests implemented */ } return 0; /* default for not implemented requests: return no data back to host */ @@ -105,8 +189,8 @@ uchar usbFunctionWrite(uchar *data, uchar len) } switch (last_req.kind) { case SET_LED: - //print("SET_LED\n"); - host_keyboard_led = data[0]; + //debug("SET_LED\n"); + keyboard_led = data[0]; last_req.len = 0; return 1; break; @@ -119,6 +203,16 @@ uchar usbFunctionWrite(uchar *data, uchar len) } + +/*------------------------------------------------------------------* + * Descriptors * + *------------------------------------------------------------------*/ + +/* + * Report Descriptor for keyboard + * + * from an example in HID spec appendix + */ PROGMEM uchar keyboard_hid_report[] = { 0x05, 0x01, // Usage Page (Generic Desktop), 0x09, 0x06, // Usage (Keyboard), @@ -154,10 +248,14 @@ PROGMEM uchar keyboard_hid_report[] = { 0xc0 // End Collection }; -// Mouse Protocol 1, HID 1.11 spec, Appendix B, page 59-60, with wheel extension -// http://www.microchip.com/forums/tm.aspx?high=&m=391435&mpage=1#391521 -// http://www.keil.com/forum/15671/ -// http://www.microsoft.com/whdc/device/input/wheel.mspx +/* + * Report Descriptor for mouse + * + * Mouse Protocol 1, HID 1.11 spec, Appendix B, page 59-60, with wheel extension + * http://www.microchip.com/forums/tm.aspx?high=&m=391435&mpage=1#391521 + * http://www.keil.com/forum/15671/ + * http://www.microsoft.com/whdc/device/input/wheel.mspx + */ PROGMEM uchar mouse_hid_report[] = { /* from HID 1.11 spec example */ 0x05, 0x01, // Usage Page (Generic Desktop), @@ -261,7 +359,11 @@ PROGMEM uchar mouse_hid_report[] = { }; -/* Descriptor for compite device: Keyboard + Mouse */ +/* + * Descriptor for compite device: Keyboard + Mouse + * + * contains: device, interface, HID and endpoint descriptors + */ #if USB_CFG_DESCR_PROPS_CONFIGURATION PROGMEM char usbDescriptorConfiguration[] = { /* USB configuration descriptor */ 9, /* sizeof(usbDescriptorConfiguration): length of descriptor in bytes */ @@ -343,16 +445,17 @@ PROGMEM char usbDescriptorConfiguration[] = { /* USB configuration descriptor }; #endif + USB_PUBLIC usbMsgLen_t usbFunctionDescriptor(struct usbRequest *rq) { usbMsgLen_t len = 0; - print("usbFunctionDescriptor: "); - phex(rq->bmRequestType); print(" "); - phex(rq->bRequest); print(" "); - phex16(rq->wValue.word); print(" "); - phex16(rq->wIndex.word); print(" "); - phex16(rq->wLength.word); print("\n"); + debug("usbFunctionDescriptor: "); + debug_hex(rq->bmRequestType); debug(" "); + debug_hex(rq->bRequest); debug(" "); + debug_hex16(rq->wValue.word); debug(" "); + debug_hex16(rq->wIndex.word); debug(" "); + debug_hex16(rq->wLength.word); debug("\n"); switch (rq->wValue.bytes[1]) { #if USB_CFG_DESCR_PROPS_CONFIGURATION @@ -379,6 +482,6 @@ USB_PUBLIC usbMsgLen_t usbFunctionDescriptor(struct usbRequest *rq) } break; } - print("desc len: "); phex(len); print("\n"); + debug("desc len: "); debug_hex(len); debug("\n"); return len; } diff --git a/ps2_vusb/keymap.c b/ps2_vusb/keymap.c index dfbbee6e..d64e377b 100644 --- a/ps2_vusb/keymap.c +++ b/ps2_vusb/keymap.c @@ -5,7 +5,7 @@ #include #include #include "usb_keycodes.h" -#include "keyboard.h" +#include "host.h" #include "print.h" #include "debug.h" #include "util.h" @@ -185,5 +185,5 @@ uint8_t keymap_fn_keycode(uint8_t fn_bits) // define a condition to enter special function mode bool keymap_is_special_mode(uint8_t fn_bits) { - return keyboard_get_mods() == (BIT_LSHIFT | BIT_RSHIFT) || keyboard_get_mods() == (BIT_LCTRL | BIT_RSHIFT); + return host_get_mods() == (BIT_LSHIFT | BIT_RSHIFT) || host_get_mods() == (BIT_LCTRL | BIT_RSHIFT); } diff --git a/ps2_vusb/main.c b/ps2_vusb/main.c index eefa9e6d..74c7a17e 100644 --- a/ps2_vusb/main.c +++ b/ps2_vusb/main.c @@ -19,7 +19,6 @@ #include "matrix_skel.h" #include "keymap_skel.h" #include "mousekey.h" -#include "keyboard.h" #include "layer.h" #include "print.h" #include "debug.h" @@ -27,11 +26,13 @@ #include "host.h" #include "host_vusb.h" #include "timer.h" +#include "led.h" +#include "keyboard.h" #define DEBUGP_INIT() do { DDRC = 0xFF; } while (0) #define DEBUGP(x) do { PORTC = x; } while (0) -static uint8_t last_led = 0; +//static uint8_t last_led = 0; int main(void) { DEBUGP_INIT(); @@ -49,8 +50,7 @@ int main(void) print_enable = true; //debug_enable = true; - timer_init(); - matrix_init(); + keyboard_init(); /* enforce re-enumeration, do this while interrupts are disabled! */ usbDeviceDisconnect(); @@ -62,7 +62,7 @@ int main(void) usbDeviceConnect(); sei(); - uint8_t fn_bits = 0; + //uint8_t fn_bits = 0; while (1) { /* main event loop */ DEBUGP(0x01); wdt_reset(); @@ -70,10 +70,13 @@ int main(void) host_vusb_keyboard_send(); DEBUGP(0x02); + keyboard_proc(); + DEBUGP(0x03); +/* matrix_scan(); fn_bits = 0; - keyboard_swap_report(); - keyboard_clear_report(); + host_swap_keyboard_report(); + host_clear_keyboard_report(); mousekey_clear_report(); for (int row = 0; row < matrix_rows(); row++) { for (int col = 0; col < matrix_cols(); col++) { @@ -84,10 +87,10 @@ int main(void) // do nothing } else if (IS_MOD(code)) { - keyboard_add_mod_bit(MOD_BIT(code)); + host_add_mod_bit(MOD_BIT(code)); } else if (IS_KEY(code)) { - keyboard_add_key(code); + host_add_key(code); } else if (IS_FN(code)) { fn_bits |= FN_BIT(code); @@ -103,13 +106,14 @@ int main(void) DEBUGP(0x03); layer_switching(fn_bits); if (matrix_is_modified()) { - keyboard_send(); + host_send_keyboard_report(); } mousekey_send(); - if (last_led != host_keyboard_led) { - keyboard_set_led(host_keyboard_led); - last_led = host_keyboard_led; + if (last_led != host_keyboard_led()) { + led_set(host_keyboard_led()); + last_led = host_keyboard_led(); } +*/ } } diff --git a/ps2_vusb/matrix.c b/ps2_vusb/matrix.c index 1058b004..ca3e0ef3 100644 --- a/ps2_vusb/matrix.c +++ b/ps2_vusb/matrix.c @@ -9,7 +9,6 @@ #include "util.h" #include "debug.h" #include "ps2.h" -#include "keyboard.h" #include "matrix_skel.h" diff --git a/ps2_vusb/mousekey.c b/ps2_vusb/mousekey.c deleted file mode 100644 index a311eecc..00000000 --- a/ps2_vusb/mousekey.c +++ /dev/null @@ -1,102 +0,0 @@ -#include -#include -#include "usb_keycodes.h" -#include "host.h" -#include "timer.h" -#include "print.h" -#include "mousekey.h" - - -static report_mouse_t report; -static report_mouse_t report_prev; - -static uint8_t mousekey_repeat = 0; - - -/* - * TODO: fix acceleration algorithm - * see wikipedia http://en.wikipedia.org/wiki/Mouse_keys - */ -#ifndef MOUSEKEY_DELAY_TIME -# define MOUSEKEY_DELAY_TIME 255 -#endif - - -static inline uint8_t move_unit(void) -{ - uint8_t unit = (10 + (mousekey_repeat)); - return unit > 127 ? 127 : unit; -} - -void mousekey_decode(uint8_t code) -{ - if (code == KB_MS_UP) report.y -= move_unit(); - else if (code == KB_MS_DOWN) report.y += move_unit(); - else if (code == KB_MS_LEFT) report.x -= move_unit(); - else if (code == KB_MS_RIGHT) report.x += move_unit(); - else if (code == KB_MS_BTN1) report.buttons |= MOUSE_BTN1; - else if (code == KB_MS_BTN2) report.buttons |= MOUSE_BTN2; - else if (code == KB_MS_BTN3) report.buttons |= MOUSE_BTN3; -/* - else if (code == KB_MS_BTN4) report.buttons |= MOUSE_BTN4; - else if (code == KB_MS_BTN5) report.buttons |= MOUSE_BTN5; - else if (code == KB_MS_WH_UP) report.v += 1; - else if (code == KB_MS_WH_DOWN) report.v -= 1; - else if (code == KB_MS_WH_LEFT) report.h -= 1; - else if (code == KB_MS_WH_RIGHT)report.h += 1; -*/ -} - -bool mousekey_changed(void) -{ - return (report.buttons != report_prev.buttons || - report.x != report_prev.x || - report.y != report_prev.y || - report.x || report.y); - //return (report.buttons != report_prev.buttons || report.x || report.y); -} - -void mousekey_send(void) -{ - static uint16_t last_timer = 0; - - if (!mousekey_changed()) { - mousekey_repeat = 0; - return; - } - - // send immediately when buttun state is changed - if (report.buttons == report_prev.buttons) { - // TODO: delay parameter setting - if ((timer_elapsed(last_timer) < (mousekey_repeat == 1 ? 20 : 5))) { - return; - } - } - - if (report.x && report.y) { - report.x *= 0.7; - report.y *= 0.7; - } - - /* - print("mousekey_repeat: "); phex(mousekey_repeat); print("\n"); - print("timer: "); phex16(timer_read()); print("\n"); - print("last_timer: "); phex16(last_timer); print("\n"); - print("mousekey: "); phex(report.buttons); print(" "); phex(report.x); print(" "); phex(report.y); print("\n"); - */ - - host_mouse_send(&report); - report_prev.buttons = report.buttons; - report_prev.x = report.x; - report_prev.y = report.y; - if (mousekey_repeat != 0xFF) mousekey_repeat++; - last_timer = timer_read(); - mousekey_clear_report(); -} - -void mousekey_clear_report(void) -{ - report.buttons = 0; - report.x = 0; - report.y = 0; -} diff --git a/tmk.c b/tmk.c index 2248a7d7..00b571d5 100644 --- a/tmk.c +++ b/tmk.c @@ -28,16 +28,14 @@ #include #include #include +#include "keyboard.h" #include "usb.h" #include "matrix_skel.h" -#include "key_process.h" #include "print.h" #include "debug.h" #include "util.h" -#include "timer.h" #include "jump_bootloader.h" #ifdef PS2_MOUSE_ENABLE -# include "ps2.h" # include "ps2_mouse.h" #endif @@ -65,9 +63,7 @@ int main(void) usb_init(); while (!usb_configured()) /* wait */ ; - timer_init(); - - matrix_init(); + keyboard_init(); matrix_scan(); if (matrix_key_count() >= 3) { #ifdef DEBUG_LED @@ -94,12 +90,8 @@ int main(void) jump_bootloader(); // not return } -#ifdef PS2_MOUSE_ENABLE - ps2_host_init(); - ps2_mouse_init(); -#endif while (1) { - proc_matrix(); + keyboard_proc(); } }