SRC += keyboard.c \ | SRC += keyboard.c \ | ||||
command.c \ | |||||
layer.c \ | layer.c \ | ||||
timer.c \ | timer.c \ | ||||
print.c \ | print.c \ |
# keyboard dependent files | # keyboard dependent files | ||||
TARGET_SRC = tmk.c \ | TARGET_SRC = tmk.c \ | ||||
key_process.c \ | |||||
host_pjrc.c \ | host_pjrc.c \ | ||||
keymap.c \ | keymap.c \ | ||||
matrix.c \ | matrix.c \ |
#include <stdint.h> | #include <stdint.h> | ||||
#include <stdbool.h> | #include <stdbool.h> | ||||
#include <avr/pgmspace.h> | #include <avr/pgmspace.h> | ||||
#include "keyboard.h" | |||||
#include "host.h" | |||||
#include "usb_keycodes.h" | #include "usb_keycodes.h" | ||||
#include "print.h" | #include "print.h" | ||||
#include "debug.h" | #include "debug.h" | ||||
// define a condition to enter special function mode | // define a condition to enter special function mode | ||||
bool keymap_is_special_mode(uint8_t fn_bits) | 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); | |||||
} | } |
#include <stdint.h> | #include <stdint.h> | ||||
#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_BTN1 (1<<0) | ||||
#define MOUSE_BTN2 (1<<1) | #define MOUSE_BTN2 (1<<1) | ||||
#define MOUSE_BTN3 (1<<2) | #define MOUSE_BTN3 (1<<2) | ||||
#define MOUSE_BTN5 (1<<4) | #define MOUSE_BTN5 (1<<4) | ||||
#define REPORT_KEYS 6 | |||||
typedef struct { | typedef struct { | ||||
uint8_t mods; | uint8_t mods; | ||||
uint8_t rserved; // not used | |||||
uint8_t rserved; | |||||
uint8_t keys[REPORT_KEYS]; | uint8_t keys[REPORT_KEYS]; | ||||
} report_keyboard_t; | } report_keyboard_t; | ||||
} report_mouse_t; | } 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); | void host_mouse_send(report_mouse_t *report); | ||||
#endif | #endif |
#include "usb_keycodes.h" | |||||
#include "keyboard.h" | |||||
#include "host.h" | #include "host.h" | ||||
#include "layer.h" | |||||
#include "matrix_skel.h" | |||||
#include "led.h" | #include "led.h" | ||||
#include "keyboard.h" | |||||
#include "usb_keycodes.h" | |||||
#include "timer.h" | |||||
#include "print.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(); | |||||
} | |||||
} | } |
#ifndef KEYBOARD_H | #ifndef KEYBOARD_H | ||||
#define KEYBOARD_H | #define KEYBOARD_H | ||||
#include <stdint.h> | |||||
#include <stdbool.h> | |||||
#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 | #endif | ||||
#include "keymap_skel.h" | #include "keymap_skel.h" | ||||
#include "keyboard.h" | |||||
#include "host.h" | |||||
#include "debug.h" | #include "debug.h" | ||||
#include "timer.h" | #include "timer.h" | ||||
#include "layer.h" | #include "layer.h" | ||||
debug(" -> "); debug_hex(current_layer); debug("\n"); | debug(" -> "); debug_hex(current_layer); debug("\n"); | ||||
} | } | ||||
} else { | } 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); | uint8_t _fn_to_send = BIT_SUBT(fn_bits, sent_fn); | ||||
if (_fn_to_send) { | if (_fn_to_send) { | ||||
debug("Fn case: 4(send Fn before other key pressed)\n"); | debug("Fn case: 4(send Fn before other key pressed)\n"); | ||||
// send only Fn key first | // 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; | sent_fn |= _fn_to_send; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
// add Fn keys 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) | } else { // Fn state is changed(edge) | ||||
uint8_t fn_changed = 0; | uint8_t fn_changed = 0; | ||||
// pressed Fn | // pressed Fn | ||||
if ((fn_changed = BIT_SUBT(fn_bits, last_fn))) { | if ((fn_changed = BIT_SUBT(fn_bits, last_fn))) { | ||||
debug("fn_changed: "); debug_bin(fn_changed); debug("\n"); | 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"); | debug("Fn case: 5(pressed Fn with other key)\n"); | ||||
sent_fn |= fn_changed; | sent_fn |= fn_changed; | ||||
} else if (fn_changed & sent_fn) { // pressed same Fn in a row | } else if (fn_changed & sent_fn) { // pressed same Fn in a row | ||||
if (BIT_SUBT(fn_changed, sent_fn)) { // layer not used && Fn not sent | 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"); | debug("Fn case: 2(send Fn one shot: released Fn during LAYER_SEND_FN_TERM)\n"); | ||||
// send only Fn key first | // 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; | sent_fn |= fn_changed; | ||||
} | } | ||||
} | } | ||||
// send Fn keys | // send Fn keys | ||||
for (uint8_t i = 0; i < 8; i++) { | for (uint8_t i = 0; i < 8; i++) { | ||||
if ((sent_fn & fn_bits) & (1<<i)) { | if ((sent_fn & fn_bits) & (1<<i)) { | ||||
keyboard_add_code(keymap_fn_keycode(1<<i)); | |||||
host_add_code(keymap_fn_keycode(1<<i)); | |||||
} | } | ||||
} | } | ||||
} | } |
#include <stdint.h> | #include <stdint.h> | ||||
uint8_t default_layer; | |||||
uint8_t current_layer; | |||||
extern uint8_t default_layer; | |||||
extern uint8_t current_layer; | |||||
/* return keycode for switch */ | /* return keycode for switch */ | ||||
uint8_t layer_get_keycode(uint8_t row, uint8_t col); | uint8_t layer_get_keycode(uint8_t row, uint8_t col); |
#include <stdint.h> | #include <stdint.h> | ||||
#include <util/delay.h> | #include <util/delay.h> | ||||
#include "usb_keycodes.h" | #include "usb_keycodes.h" | ||||
#include "usb_mouse.h" | |||||
#include "host.h" | |||||
#include "timer.h" | |||||
#include "print.h" | |||||
#include "debug.h" | |||||
#include "mousekey.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 uint8_t mousekey_repeat = 0; | ||||
static void mousekey_debug(void); | |||||
/* | /* | ||||
* TODO: fix acceleration algorithm | * TODO: fix acceleration algorithm | ||||
static inline uint8_t move_unit(void) | 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) | 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) | 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; | 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"); | |||||
} | } |
#include <stdint.h> | |||||
#include <util/delay.h> | |||||
#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; | |||||
} |
#define MOUSEKEY_H | #define MOUSEKEY_H | ||||
#include <stdbool.h> | #include <stdbool.h> | ||||
#include "host.h" | |||||
void mousekey_decode(uint8_t code); | void mousekey_decode(uint8_t code); | ||||
bool mousekey_changed(void); | bool mousekey_changed(void); | ||||
void mousekey_usb_send(void); | |||||
void mousekey_send(void); | |||||
void mousekey_clear_report(void); | |||||
#endif | #endif | ||||
#define MOUSEKEY_H | #define MOUSEKEY_H | ||||
#include <stdbool.h> | #include <stdbool.h> | ||||
#include "host.h" | |||||
void mousekey_decode(uint8_t code); | void mousekey_decode(uint8_t code); | ||||
bool mousekey_changed(void); | bool mousekey_changed(void); | ||||
void mousekey_send(void); | |||||
void mousekey_clear_report(void); | |||||
void mousekey_usb_send(void); | |||||
#endif | #endif | ||||
pbuf[pbuf_head] = data; | pbuf[pbuf_head] = data; | ||||
pbuf_head = next; | pbuf_head = next; | ||||
} else { | } else { | ||||
print("pbuf: full\n"); | |||||
debug("pbuf: full\n"); | |||||
} | } | ||||
} | } | ||||
static inline uint8_t pbuf_dequeue(void) | static inline uint8_t pbuf_dequeue(void) | ||||
ISR(PS2_INT_VECT) | ISR(PS2_INT_VECT) | ||||
{ | { | ||||
PORTC = 0xFF; | |||||
/* interrupt means start bit comes */ | /* interrupt means start bit comes */ | ||||
pbuf_enqueue(recv_data()); | pbuf_enqueue(recv_data()); | ||||
/* release lines(idle state) */ | /* release lines(idle state) */ | ||||
idle(); | idle(); | ||||
_delay_us(5); | _delay_us(5); | ||||
PORTC = 0x00; | |||||
} | } | ||||
#endif | #endif | ||||
if (!ps2_mouse_enable) return 1; | if (!ps2_mouse_enable) return 1; | ||||
ps2_host_init(); | |||||
// Reset | // Reset | ||||
rcv = ps2_host_send(0xFF); | rcv = ps2_host_send(0xFF); | ||||
print("ps2_mouse_init: send 0xFF: "); | print("ps2_mouse_init: send 0xFF: "); |
# define MOUSEKEY_DELAY_TIME 255 | # define MOUSEKEY_DELAY_TIME 255 | ||||
#endif | #endif | ||||
#define IS_COMMAND() ( \ | |||||
keyboard_report->mods == (BIT_LSHIFT | BIT_RSHIFT) || \ | |||||
keyboard_report->mods == (BIT_LCTRL | BIT_RSHIFT) \ | |||||
) | |||||
/* PS/2 lines */ | /* PS/2 lines */ | ||||
#define PS2_CLOCK_PORT PORTD | #define PS2_CLOCK_PORT PORTD | ||||
#define PS2_CLOCK_PIN PIND | #define PS2_CLOCK_PIN PIND | ||||
EICRA |= ((1<<ISC11) | (0<<ISC10)); \ | EICRA |= ((1<<ISC11) | (0<<ISC10)); \ | ||||
EIFR |= (1<<INTF1); \ | EIFR |= (1<<INTF1); \ | ||||
} while (0) | } while (0) | ||||
#define PS2_INT_DISABLE() do { \ | #define PS2_INT_DISABLE() do { \ | ||||
EIMSK &= ~(1<<INT1); \ | EIMSK &= ~(1<<INT1); \ | ||||
} while (0) | } while (0) | ||||
PCICR |= (1<<PCIE2); \ | PCICR |= (1<<PCIE2); \ | ||||
PCIFR |= (1<<PCIF2); \ | PCIFR |= (1<<PCIF2); \ | ||||
} while (0) | } while (0) | ||||
#define PS2_INT_DISABLE() do { \ | #define PS2_INT_DISABLE() do { \ | ||||
PCMSK2 &= ~(1<<PCINT22); \ | PCMSK2 &= ~(1<<PCINT22); \ | ||||
PCICR &= ~(1<<PCIE); \ | PCICR &= ~(1<<PCIE); \ |
#include "usbdrv.h" | #include "usbdrv.h" | ||||
#include "usbconfig.h" | #include "usbconfig.h" | ||||
#include "keyboard.h" | |||||
#include "print.h" | #include "print.h" | ||||
#include "usb_keycodes.h" | |||||
#include "host.h" | #include "host.h" | ||||
#include "host_vusb.h" | #include "host_vusb.h" | ||||
#include "debug.h" | |||||
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 keyboard_led = 0; | |||||
static uchar idleRate = 0; | |||||
uint8_t host_keyboard_led(void) | |||||
{ | |||||
return keyboard_led; | |||||
} | |||||
/*------------------------------------------------------------------* | |||||
* Keyboard report operations | |||||
*------------------------------------------------------------------*/ | |||||
void host_add_key(uint8_t code) | |||||
{ | |||||
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; | |||||
} | |||||
} | |||||
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 | #define KBUF_SIZE 16 | ||||
static report_keyboard_t kbuf[KBUF_SIZE]; | static report_keyboard_t kbuf[KBUF_SIZE]; | ||||
static uint8_t kbuf_head = 0; | static uint8_t kbuf_head = 0; | ||||
static uint8_t kbuf_tail = 0; | static uint8_t kbuf_tail = 0; | ||||
void host_vusb_keyboard_send() | |||||
void host_vusb_keyboard_send(void) | |||||
{ | { | ||||
while (usbInterruptIsReady() && kbuf_head != kbuf_tail) { | while (usbInterruptIsReady() && kbuf_head != kbuf_tail) { | ||||
usbSetInterrupt((void *)&kbuf[kbuf_tail], sizeof(report_keyboard_t)); | usbSetInterrupt((void *)&kbuf[kbuf_tail], sizeof(report_keyboard_t)); | ||||
} | } | ||||
} | } | ||||
void host_keyboard_send(report_keyboard_t *report) | |||||
void host_send_keyboard_report(void) | |||||
{ | { | ||||
uint8_t next = (kbuf_head + 1) % KBUF_SIZE; | uint8_t next = (kbuf_head + 1) % KBUF_SIZE; | ||||
if (next != kbuf_tail) { | if (next != kbuf_tail) { | ||||
kbuf[kbuf_head] = *report; | |||||
kbuf[kbuf_head] = *keyboard_report; | |||||
kbuf_head = next; | kbuf_head = next; | ||||
print("kbuf: "); phex(kbuf_head); phex(kbuf_tail); print("\n"); | |||||
} else { | } else { | ||||
print("kbuf: full\n"); | |||||
debug("kbuf: full\n"); | |||||
} | } | ||||
} | } | ||||
void host_mouse_send(report_mouse_t *report) | void host_mouse_send(report_mouse_t *report) | ||||
{ | { | ||||
if (usbInterruptIsReady3()) { | if (usbInterruptIsReady3()) { | ||||
usbSetInterrupt3((void *)report, sizeof(*report)); | usbSetInterrupt3((void *)report, sizeof(*report)); | ||||
} else { | } else { | ||||
print("Int3 not ready\n"); | |||||
debug("Int3 not ready\n"); | |||||
} | } | ||||
} | } | ||||
/*------------------------------------------------------------------* | |||||
* Request from host * | |||||
*------------------------------------------------------------------*/ | |||||
static struct { | static struct { | ||||
uint16_t len; | uint16_t len; | ||||
enum { | enum { | ||||
} kind; | } kind; | ||||
} last_req; | } last_req; | ||||
uint8_t host_keyboard_led = 0; | |||||
static uchar idleRate; | |||||
usbMsgLen_t usbFunctionSetup(uchar data[8]) | usbMsgLen_t usbFunctionSetup(uchar data[8]) | ||||
{ | { | ||||
usbRequest_t *rq = (void *)data; | usbRequest_t *rq = (void *)data; | ||||
//print("Setup: "); | |||||
if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){ /* class request type */ | 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){ | 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 */ | /* we only have one report type, so don't look at wValue */ | ||||
usbMsgPtr = (void *)keyboard_report; | usbMsgPtr = (void *)keyboard_report; | ||||
return sizeof(*keyboard_report); | return sizeof(*keyboard_report); | ||||
}else if(rq->bRequest == USBRQ_HID_GET_IDLE){ | }else if(rq->bRequest == USBRQ_HID_GET_IDLE){ | ||||
print(" GET_IDLE: "); | |||||
phex(idleRate); | |||||
debug(" GET_IDLE: "); | |||||
debug_hex(idleRate); | |||||
usbMsgPtr = &idleRate; | usbMsgPtr = &idleRate; | ||||
return 1; | return 1; | ||||
}else if(rq->bRequest == USBRQ_HID_SET_IDLE){ | }else if(rq->bRequest == USBRQ_HID_SET_IDLE){ | ||||
idleRate = rq->wValue.bytes[1]; | idleRate = rq->wValue.bytes[1]; | ||||
print(" SET_IDLE: "); | |||||
phex(idleRate); | |||||
debug(" SET_IDLE: "); | |||||
debug_hex(idleRate); | |||||
}else if(rq->bRequest == USBRQ_HID_SET_REPORT){ | }else if(rq->bRequest == USBRQ_HID_SET_REPORT){ | ||||
//print(" SET_REPORT: "); | |||||
//debug(" SET_REPORT: "); | |||||
if (rq->wValue.word == 0x0200 && rq->wIndex.word == 0) { | if (rq->wValue.word == 0x0200 && rq->wIndex.word == 0) { | ||||
last_req.kind = SET_LED; | last_req.kind = SET_LED; | ||||
last_req.len = rq->wLength.word; | last_req.len = rq->wLength.word; | ||||
} | } | ||||
return USB_NO_MSG; // to get data in usbFunctionWrite | return USB_NO_MSG; // to get data in usbFunctionWrite | ||||
} | } | ||||
print("\n"); | |||||
debug("\n"); | |||||
}else{ | }else{ | ||||
print("VENDOR\n"); | |||||
debug("VENDOR\n"); | |||||
/* no vendor specific requests implemented */ | /* no vendor specific requests implemented */ | ||||
} | } | ||||
return 0; /* default for not implemented requests: return no data back to host */ | return 0; /* default for not implemented requests: return no data back to host */ | ||||
} | } | ||||
switch (last_req.kind) { | switch (last_req.kind) { | ||||
case SET_LED: | case SET_LED: | ||||
//print("SET_LED\n"); | |||||
host_keyboard_led = data[0]; | |||||
//debug("SET_LED\n"); | |||||
keyboard_led = data[0]; | |||||
last_req.len = 0; | last_req.len = 0; | ||||
return 1; | return 1; | ||||
break; | break; | ||||
} | } | ||||
/*------------------------------------------------------------------* | |||||
* Descriptors * | |||||
*------------------------------------------------------------------*/ | |||||
/* | |||||
* Report Descriptor for keyboard | |||||
* | |||||
* from an example in HID spec appendix | |||||
*/ | |||||
PROGMEM uchar keyboard_hid_report[] = { | PROGMEM uchar keyboard_hid_report[] = { | ||||
0x05, 0x01, // Usage Page (Generic Desktop), | 0x05, 0x01, // Usage Page (Generic Desktop), | ||||
0x09, 0x06, // Usage (Keyboard), | 0x09, 0x06, // Usage (Keyboard), | ||||
0xc0 // End Collection | 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[] = { | PROGMEM uchar mouse_hid_report[] = { | ||||
/* from HID 1.11 spec example */ | /* from HID 1.11 spec example */ | ||||
0x05, 0x01, // Usage Page (Generic Desktop), | 0x05, 0x01, // Usage Page (Generic Desktop), | ||||
}; | }; | ||||
/* 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 | #if USB_CFG_DESCR_PROPS_CONFIGURATION | ||||
PROGMEM char usbDescriptorConfiguration[] = { /* USB configuration descriptor */ | PROGMEM char usbDescriptorConfiguration[] = { /* USB configuration descriptor */ | ||||
9, /* sizeof(usbDescriptorConfiguration): length of descriptor in bytes */ | 9, /* sizeof(usbDescriptorConfiguration): length of descriptor in bytes */ | ||||
}; | }; | ||||
#endif | #endif | ||||
USB_PUBLIC usbMsgLen_t usbFunctionDescriptor(struct usbRequest *rq) | USB_PUBLIC usbMsgLen_t usbFunctionDescriptor(struct usbRequest *rq) | ||||
{ | { | ||||
usbMsgLen_t len = 0; | 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]) { | switch (rq->wValue.bytes[1]) { | ||||
#if USB_CFG_DESCR_PROPS_CONFIGURATION | #if USB_CFG_DESCR_PROPS_CONFIGURATION | ||||
} | } | ||||
break; | break; | ||||
} | } | ||||
print("desc len: "); phex(len); print("\n"); | |||||
debug("desc len: "); debug_hex(len); debug("\n"); | |||||
return len; | return len; | ||||
} | } |
#include <stdbool.h> | #include <stdbool.h> | ||||
#include <avr/pgmspace.h> | #include <avr/pgmspace.h> | ||||
#include "usb_keycodes.h" | #include "usb_keycodes.h" | ||||
#include "keyboard.h" | |||||
#include "host.h" | |||||
#include "print.h" | #include "print.h" | ||||
#include "debug.h" | #include "debug.h" | ||||
#include "util.h" | #include "util.h" | ||||
// define a condition to enter special function mode | // define a condition to enter special function mode | ||||
bool keymap_is_special_mode(uint8_t fn_bits) | 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); | |||||
} | } |
#include "matrix_skel.h" | #include "matrix_skel.h" | ||||
#include "keymap_skel.h" | #include "keymap_skel.h" | ||||
#include "mousekey.h" | #include "mousekey.h" | ||||
#include "keyboard.h" | |||||
#include "layer.h" | #include "layer.h" | ||||
#include "print.h" | #include "print.h" | ||||
#include "debug.h" | #include "debug.h" | ||||
#include "host.h" | #include "host.h" | ||||
#include "host_vusb.h" | #include "host_vusb.h" | ||||
#include "timer.h" | #include "timer.h" | ||||
#include "led.h" | |||||
#include "keyboard.h" | |||||
#define DEBUGP_INIT() do { DDRC = 0xFF; } while (0) | #define DEBUGP_INIT() do { DDRC = 0xFF; } while (0) | ||||
#define DEBUGP(x) do { PORTC = x; } 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) | int main(void) | ||||
{ | { | ||||
DEBUGP_INIT(); | DEBUGP_INIT(); | ||||
print_enable = true; | print_enable = true; | ||||
//debug_enable = true; | //debug_enable = true; | ||||
timer_init(); | |||||
matrix_init(); | |||||
keyboard_init(); | |||||
/* enforce re-enumeration, do this while interrupts are disabled! */ | /* enforce re-enumeration, do this while interrupts are disabled! */ | ||||
usbDeviceDisconnect(); | usbDeviceDisconnect(); | ||||
usbDeviceConnect(); | usbDeviceConnect(); | ||||
sei(); | sei(); | ||||
uint8_t fn_bits = 0; | |||||
//uint8_t fn_bits = 0; | |||||
while (1) { /* main event loop */ | while (1) { /* main event loop */ | ||||
DEBUGP(0x01); | DEBUGP(0x01); | ||||
wdt_reset(); | wdt_reset(); | ||||
host_vusb_keyboard_send(); | host_vusb_keyboard_send(); | ||||
DEBUGP(0x02); | DEBUGP(0x02); | ||||
keyboard_proc(); | |||||
DEBUGP(0x03); | |||||
/* | |||||
matrix_scan(); | matrix_scan(); | ||||
fn_bits = 0; | fn_bits = 0; | ||||
keyboard_swap_report(); | |||||
keyboard_clear_report(); | |||||
host_swap_keyboard_report(); | |||||
host_clear_keyboard_report(); | |||||
mousekey_clear_report(); | mousekey_clear_report(); | ||||
for (int row = 0; row < matrix_rows(); row++) { | for (int row = 0; row < matrix_rows(); row++) { | ||||
for (int col = 0; col < matrix_cols(); col++) { | for (int col = 0; col < matrix_cols(); col++) { | ||||
// do nothing | // do nothing | ||||
} | } | ||||
else if (IS_MOD(code)) { | else if (IS_MOD(code)) { | ||||
keyboard_add_mod_bit(MOD_BIT(code)); | |||||
host_add_mod_bit(MOD_BIT(code)); | |||||
} | } | ||||
else if (IS_KEY(code)) { | else if (IS_KEY(code)) { | ||||
keyboard_add_key(code); | |||||
host_add_key(code); | |||||
} | } | ||||
else if (IS_FN(code)) { | else if (IS_FN(code)) { | ||||
fn_bits |= FN_BIT(code); | fn_bits |= FN_BIT(code); | ||||
DEBUGP(0x03); | DEBUGP(0x03); | ||||
layer_switching(fn_bits); | layer_switching(fn_bits); | ||||
if (matrix_is_modified()) { | if (matrix_is_modified()) { | ||||
keyboard_send(); | |||||
host_send_keyboard_report(); | |||||
} | } | ||||
mousekey_send(); | 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(); | |||||
} | } | ||||
*/ | |||||
} | } | ||||
} | } |
#include "util.h" | #include "util.h" | ||||
#include "debug.h" | #include "debug.h" | ||||
#include "ps2.h" | #include "ps2.h" | ||||
#include "keyboard.h" | |||||
#include "matrix_skel.h" | #include "matrix_skel.h" | ||||
#include <stdint.h> | |||||
#include <util/delay.h> | |||||
#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; | |||||
} |
#include <avr/io.h> | #include <avr/io.h> | ||||
#include <avr/interrupt.h> | #include <avr/interrupt.h> | ||||
#include <util/delay.h> | #include <util/delay.h> | ||||
#include "keyboard.h" | |||||
#include "usb.h" | #include "usb.h" | ||||
#include "matrix_skel.h" | #include "matrix_skel.h" | ||||
#include "key_process.h" | |||||
#include "print.h" | #include "print.h" | ||||
#include "debug.h" | #include "debug.h" | ||||
#include "util.h" | #include "util.h" | ||||
#include "timer.h" | |||||
#include "jump_bootloader.h" | #include "jump_bootloader.h" | ||||
#ifdef PS2_MOUSE_ENABLE | #ifdef PS2_MOUSE_ENABLE | ||||
# include "ps2.h" | |||||
# include "ps2_mouse.h" | # include "ps2_mouse.h" | ||||
#endif | #endif | ||||
usb_init(); | usb_init(); | ||||
while (!usb_configured()) /* wait */ ; | while (!usb_configured()) /* wait */ ; | ||||
timer_init(); | |||||
matrix_init(); | |||||
keyboard_init(); | |||||
matrix_scan(); | matrix_scan(); | ||||
if (matrix_key_count() >= 3) { | if (matrix_key_count() >= 3) { | ||||
#ifdef DEBUG_LED | #ifdef DEBUG_LED | ||||
jump_bootloader(); // not return | jump_bootloader(); // not return | ||||
} | } | ||||
#ifdef PS2_MOUSE_ENABLE | |||||
ps2_host_init(); | |||||
ps2_mouse_init(); | |||||
#endif | |||||
while (1) { | while (1) { | ||||
proc_matrix(); | |||||
keyboard_proc(); | |||||
} | } | ||||
} | } |