From 2a562a4191a5b9e88731efb5eabd921821f25f7e Mon Sep 17 00:00:00 2001 From: tmk Date: Sun, 2 Jan 2011 23:52:13 +0900 Subject: [PATCH] Add PS/2 mouse support to connect TrackPoint Unit. Change build options: Makefile and config.h. See README. --- Makefile.common | 58 ++++++----- README | 41 ++++++++ USB_NKRO.txt | 14 +++ hhkb/Makefile | 17 ++- hhkb/config.h | 40 +++++++ hhkb/controller.h | 12 --- hhkb/keymap.c | 3 +- hhkb/matrix.c | 5 +- jump_bootloader.c | 31 +++--- key_process.c | 110 ++++++++++---------- macway/Makefile | 13 +-- macway/config.h | 38 +++++++ macway/controller.h | 12 --- macway/keymap.c | 62 +++++------ macway/matrix.c | 100 ++++++------------ mousekey.c | 74 +++++++++++++ mousekey.h | 11 ++ ps2.c | 248 ++++++++++++++++++++++++++++++++++++++++++++ ps2.h | 72 +++++++++++++ ps2_mouse.c | 161 ++++++++++++++++++++++++++++ ps2_mouse.h | 26 +++++ tmk.c | 11 +- usb.c | 16 +-- usb_keyboard.c | 10 +- usb_keyboard.h | 2 +- usb_mouse.c | 57 +++------- usb_mouse.h | 20 ++-- 27 files changed, 952 insertions(+), 312 deletions(-) create mode 100644 hhkb/config.h delete mode 100644 hhkb/controller.h create mode 100644 macway/config.h delete mode 100644 macway/controller.h create mode 100644 mousekey.c create mode 100644 mousekey.h create mode 100644 ps2.c create mode 100644 ps2.h create mode 100644 ps2_mouse.c create mode 100644 ps2_mouse.h diff --git a/Makefile.common b/Makefile.common index d2124243..9e995c90 100644 --- a/Makefile.common +++ b/Makefile.common @@ -62,6 +62,13 @@ SRC = tmk.c \ timer.c \ util.c SRC += $(TARGET_SRC) +ifdef MOUSEKEY_ENABLE + SRC += mousekey.c +endif +ifdef PS2_MOUSE_ENABLE + SRC += ps2.c \ + ps2_mouse.c +endif # C source file search path VPATH = $(TARGET_DIR):$(COMMON_DIR) @@ -119,45 +126,32 @@ EXTRAINCDIRS = $(TARGET_DIR) $(COMMON_DIR) CSTANDARD = -std=gnu99 -# Place -D or -U options here for C sources -CDEFS = -DF_CPU=$(F_CPU)UL -CDEFS += -DDESCRIPTION=$(DESCRIPTION) -CDEFS += -DVENDOR_ID=$(VENDOR_ID) -CDEFS += -DPRODUCT_ID=$(PRODUCT_ID) -CDEFS += -DMANUFACTURER=$(MANUFACTURER) -CDEFS += -DPRODUCT=$(PRODUCT) -ifdef MOUSE_DELAY_TIME -CDEFS += -DMOUSE_DELAY_TIME=$(MOUSE_DELAY_TIME) +OPT_DEFS = +ifdef USB_NKRO_ENABLE + OPT_DEFS += -DUSB_NKRO_ENABLE +endif +ifdef MOUSEKEY_ENABLE + OPT_DEFS += -DMOUSEKEY_ENABLE endif -ifdef NKRO_ENABLE -CDEFS += -DNKRO_ENABLE +ifdef PS2_MOUSE_ENABLE + OPT_DEFS += -DPS2_MOUSE_ENABLE endif +# Place -D or -U options here for C sources +CDEFS = -DF_CPU=$(F_CPU)UL +CDEFS += $(OPT_DEFS) + # Place -D or -U options here for ASM sources ADEFS = -DF_CPU=$(F_CPU) -ADEFS += -DDESCRIPTION=$(DESCRIPTION) -ADEFS += -DVENDOR_ID=$(VENDOR_ID) -ADEFS += -DPRODUCT_ID=$(PRODUCT_ID) -ADEFS += -DMANUFACTURER=$(MANUFACTURER) -ADEFS += -DPRODUCT=$(PRODUCT) -ifdef MOUSE_DELAY_TIME -ADEFS += -DMOUSE_DELAY_TIME=$(MOUSE_DELAY_TIME) -endif +ADEFS += $(OPT_DEFS) # Place -D or -U options here for C++ sources -CPPDEFS = -DF_CPU=$(F_CPU)UL -DDESCRIPTION=$(DESCRIPTION) -DVENDOR_ID=$(VENDOR_ID) -DPRODUCT_ID=$(PRODUCT_ID) +CPPDEFS = -DF_CPU=$(F_CPU)UL #CPPDEFS += -D__STDC_LIMIT_MACROS #CPPDEFS += -D__STDC_CONSTANT_MACROS -CPPDEFS += -DDESCRIPTION=$(DESCRIPTION) -CPPDEFS += -DVENDOR_ID=$(VENDOR_ID) -CPPDEFS += -DPRODUCT_ID=$(PRODUCT_ID) -CPPDEFS += -DMANUFACTURER=$(MANUFACTURER) -CPPDEFS += -DPRODUCT=$(PRODUCT) -ifdef MOUSE_DELAY_TIME -CPPDEFS += -DMOUSE_DELAY_TIME=$(MOUSE_DELAY_TIME) -endif +CPPDEFS += $(OPT_DEFS) @@ -186,6 +180,7 @@ CFLAGS += -Wstrict-prototypes CFLAGS += -Wa,-adhlns=$(@:%.o=$(OBJDIR)/%.lst) CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS)) CFLAGS += $(CSTANDARD) +CFLAGS += -include config.h #---------------- Compiler Options C++ ---------------- @@ -213,6 +208,7 @@ CPPFLAGS += -Wundef CPPFLAGS += -Wa,-adhlns=$(<:%.cpp=$(OBJDIR)/%.lst) CPPFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS)) #CPPFLAGS += $(CSTANDARD) +CPPFLAGS += -include config.h #---------------- Assembler Options ---------------- @@ -225,6 +221,7 @@ CPPFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS)) # -listing-cont-lines: Sets the maximum number of continuation lines of hex # dump that will be displayed for a given single line of source input. ASFLAGS = $(ADEFS) -Wa,-adhlns=$(<:%.S=$(OBJDIR)/%.lst),-gstabs,--listing-cont-lines=100 +ASFLAGS += -include config.h #---------------- Library Options ---------------- @@ -421,6 +418,11 @@ ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) # Default target. all: begin gccversion sizebefore build sizeafter end +depend: tmk.c + @echo $< + @echo $( #include "print.h" #include "util.h" -#include "controller.h" #include "matrix_skel.h" // matrix is active low. (key on: 0/key off: 1) @@ -22,7 +21,7 @@ // KEY_PREV: (on: 1/ off: 0) // PE6,PE7(KEY, KEY_PREV) #define COL_ENABLE (1<<6) -#define KEY_SELELCT(ROW, COL) (PORTB = COL_ENABLE|(((COL)&0x07)<<3)|((ROW)&0x07)) +#define KEY_SELELCT(ROW, COL) (PORTB = (PORTB&(1<<7))|COL_ENABLE|(((COL)&0x07)<<3)|((ROW)&0x07)) #define KEY_ENABLE (PORTB &= ~COL_ENABLE) #define KEY_UNABLE (PORTB |= COL_ENABLE) #define KEY_STATE (PINE&(1<<6)) @@ -53,7 +52,7 @@ void matrix_init(void) { // row & col output(PB0-6) DDRB = 0xFF; - PORTB = KEY_SELELCT(0, 0); + KEY_SELELCT(0, 0); // KEY: input with pullup(PE6) // KEY_PREV: output(PE7) DDRE = 0xBF; diff --git a/jump_bootloader.c b/jump_bootloader.c index e4c0b967..5710e052 100644 --- a/jump_bootloader.c +++ b/jump_bootloader.c @@ -13,23 +13,28 @@ void jump_bootloader(void) { UCSR1B = 0; _delay_ms(5); #if defined(__AVR_AT90USB162__) // Teensy 1.0 + EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; + TIMSK0 = 0; TIMSK1 = 0; UCSR1B = 0; DDRB = 0; DDRC = 0; DDRD = 0; - TIMSK0 = 0; TIMSK1 = 0; - asm volatile("jmp 0x1F00"); + PORTB = 0; PORTC = 0; PORTD = 0; + asm volatile("jmp 0x3E00"); #elif defined(__AVR_ATmega32U4__) // Teensy 2.0 - DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0; - TIMSK0 = 0; TIMSK1 = 0; TIMSK3 = 0; TIMSK4 = 0; - ADCSRA = 0; - asm volatile("jmp 0x3F00"); + EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; ADCSRA = 0; + TIMSK0 = 0; TIMSK1 = 0; TIMSK3 = 0; TIMSK4 = 0; UCSR1B = 0; TWCR = 0; + DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0; TWCR = 0; + PORTB = 0; PORTC = 0; PORTD = 0; PORTE = 0; PORTF = 0; + asm volatile("jmp 0x7E00"); #elif defined(__AVR_AT90USB646__) // Teensy++ 1.0 + EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; ADCSRA = 0; + TIMSK0 = 0; TIMSK1 = 0; TIMSK2 = 0; TIMSK3 = 0; UCSR1B = 0; TWCR = 0; DDRA = 0; DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0; - TIMSK0 = 0; TIMSK1 = 0; TIMSK2 = 0; TIMSK3 = 0; - ADCSRA = 0; - asm volatile("jmp 0x7E00"); + PORTA = 0; PORTB = 0; PORTC = 0; PORTD = 0; PORTE = 0; PORTF = 0; + asm volatile("jmp 0xFC00"); #elif defined(__AVR_AT90USB1286__) // Teensy++ 2.0 + EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; ADCSRA = 0; + TIMSK0 = 0; TIMSK1 = 0; TIMSK2 = 0; TIMSK3 = 0; UCSR1B = 0; TWCR = 0; DDRA = 0; DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0; - TIMSK0 = 0; TIMSK1 = 0; TIMSK2 = 0; TIMSK3 = 0; - ADCSRA = 0; - asm volatile("jmp 0xFE00"); -#endif + PORTA = 0; PORTB = 0; PORTC = 0; PORTD = 0; PORTE = 0; PORTF = 0; + asm volatile("jmp 0x1FC00"); +#endif } diff --git a/key_process.c b/key_process.c index bb1bca02..f3b65d10 100644 --- a/key_process.c +++ b/key_process.c @@ -15,29 +15,18 @@ #include "layer.h" #include "matrix_skel.h" #include "keymap_skel.h" -#include "controller.h" #include "key_process.h" - - -#define MOUSE_MOVE_UNIT 10 -#define MOUSE_MOVE_ACCEL (mouse_repeat < 50 ? mouse_repeat/5 : 10) - -#ifndef MOUSE_DELAY_TIME -# define MOUSE_DELAY_TIME 255 +#ifdef MOUSEKEY_ENABLE +# include "mousekey.h" +#endif +#ifdef PS2_MOUSE_ENABLE +# include "ps2_mouse.h" #endif -#define MOUSE_DELAY_MS (MOUSE_DELAY_TIME >> (mouse_repeat < 5 ? mouse_repeat : 4)) // TODO: refactoring void proc_matrix(void) { - static int mouse_repeat = 0; - bool modified = false; - uint8_t mouse_btn = 0; - int8_t mouse_x = 0; - int8_t mouse_y = 0; - int8_t mouse_vwheel = 0; - int8_t mouse_hwheel = 0; uint8_t fn_bits = 0; matrix_scan(); @@ -73,19 +62,9 @@ void proc_matrix(void) { } else if (IS_FN(code)) { fn_bits |= FN_BIT(code); } else if (IS_MOUSE(code)) { - if (code == MS_UP) mouse_y -= MOUSE_MOVE_UNIT + MOUSE_MOVE_ACCEL; - if (code == MS_DOWN) mouse_y += MOUSE_MOVE_UNIT + MOUSE_MOVE_ACCEL; - if (code == MS_LEFT) mouse_x -= MOUSE_MOVE_UNIT + MOUSE_MOVE_ACCEL; - if (code == MS_RGHT) mouse_x += MOUSE_MOVE_UNIT + MOUSE_MOVE_ACCEL; - if (code == MS_BTN1) mouse_btn |= BIT_BTN1; - if (code == MS_BTN2) mouse_btn |= BIT_BTN2; - if (code == MS_BTN3) mouse_btn |= BIT_BTN3; - if (code == MS_BTN4) mouse_btn |= BIT_BTN4; - if (code == MS_BTN5) mouse_btn |= BIT_BTN5; - if (code == MS_WH_U) mouse_vwheel += 1; - if (code == MS_WH_D) mouse_vwheel -= 1; - if (code == MS_WH_L) mouse_hwheel -= 1; - if (code == MS_WH_R) mouse_hwheel += 1; +#ifdef MOUSEKEY_ENABLE + mousekey_decode(code); +#endif } // audio control & system control @@ -143,13 +122,39 @@ void proc_matrix(void) { print("t: print timer count\n"); print("s: print status\n"); print("`: toggle protcol(boot/report)\n"); -#ifdef NKRO_ENABLE - print("n: toggle NKRO\n"); +#ifdef USB_NKRO_ENABLE + print("n: toggle USB_NKRO\n"); #endif print("ESC: power down/wake up\n"); +#ifdef PS2_MOUSE_ENABLE + print("1: ps2_mouse_init \n"); + print("2: ps2_mouse_read \n"); +#endif _delay_ms(500); print_enable = false; break; +#ifdef PS2_MOUSE_ENABLE + case KB_1: + usb_keyboard_clear_report(); + usb_keyboard_send(); + print_enable = true; + print("ps2_mouse_init...\n"); + _delay_ms(500); + ps2_mouse_init(); + break; + case KB_2: + usb_keyboard_clear_report(); + usb_keyboard_send(); + print_enable = true; + print("ps2_mouse_read[btn x y]: "); + _delay_ms(100); + ps2_mouse_read(); + phex(ps2_mouse_btn); print(" "); + phex(ps2_mouse_x); print(" "); + phex(ps2_mouse_y); print("\n"); + print("ps2_mouse_error_count: "); phex(ps2_mouse_error_count); print("\n"); + break; +#endif case KB_B: // bootloader usb_keyboard_clear_report(); usb_keyboard_send(); @@ -243,29 +248,29 @@ void proc_matrix(void) { print("usb_keyboard_protocol:"); phex(usb_keyboard_protocol); print("\n"); print("usb_keyboard_idle_config:"); phex(usb_keyboard_idle_config); print("\n"); print("usb_keyboard_idle_count:"); phex(usb_keyboard_idle_count); print("\n"); - print("mouse_protocol:"); phex(mouse_protocol); print("\n"); - if (usb_keyboard_nkro) print("NKRO: enabled\n"); else print("NKRO: disabled\n"); + print("usb_mouse_protocol:"); phex(usb_mouse_protocol); print("\n"); + if (usb_keyboard_nkro) print("USB_NKRO: enabled\n"); else print("USB_NKRO: disabled\n"); _delay_ms(500); break; case KB_GRV: usb_keyboard_clear_report(); usb_keyboard_send(); usb_keyboard_protocol = !usb_keyboard_protocol; - mouse_protocol = !mouse_protocol; + usb_mouse_protocol = !usb_mouse_protocol; print("keyboard protcol: "); if (usb_keyboard_protocol) print("report"); else print("boot"); print("\n"); print("mouse protcol: "); - if (mouse_protocol) print("report"); else print("boot"); + if (usb_mouse_protocol) print("report"); else print("boot"); print("\n"); _delay_ms(1000); break; -#ifdef NKRO_ENABLE +#ifdef USB_NKRO_ENABLE case KB_N: usb_keyboard_clear_report(); usb_keyboard_send(); usb_keyboard_nkro = !usb_keyboard_nkro; - if (usb_keyboard_nkro) print("NKRO: enabled\n"); else print("NKRO: disabled\n"); + if (usb_keyboard_nkro) print("USB_NKRO: enabled\n"); else print("USB_NKRO: disabled\n"); _delay_ms(1000); break; #endif @@ -283,25 +288,20 @@ void proc_matrix(void) { } - // send mouse packet to host - if (mouse_x || mouse_y || mouse_vwheel || mouse_hwheel || mouse_btn != mouse_buttons) { - mouse_buttons = mouse_btn; - if (mouse_x && mouse_y) - usb_mouse_move(mouse_x*0.7, mouse_y*0.7, mouse_vwheel, mouse_hwheel); - else - usb_mouse_move(mouse_x, mouse_y, mouse_vwheel, mouse_hwheel); - usb_mouse_print(mouse_x, mouse_y, mouse_vwheel, mouse_hwheel); - - // acceleration - _delay_ms(MOUSE_DELAY_MS); - mouse_repeat++; - } else { - mouse_repeat = 0; - } - - - // send key packet to host if (modified) { usb_keyboard_send(); } + +#ifdef MOUSEKEY_ENABLE + // mouse keys + mousekey_usb_send(); +#endif + +#ifdef PS2_MOUSE_ENABLE + // ps2 mouse + //if (ps2_mouse_error_count > 10) { + ps2_mouse_read(); + ps2_mouse_usb_send(); + //} +#endif } diff --git a/macway/Makefile b/macway/Makefile index b69b2d2e..fffe1ad5 100644 --- a/macway/Makefile +++ b/macway/Makefile @@ -39,12 +39,6 @@ # To rebuild project do "make clean" then "make all". #---------------------------------------------------------------------------- -VENDOR_ID = 0xFEED -PRODUCT_ID = 0xBEEF -MANUFACTURER = 't.m.k.' -PRODUCT = 't.m.k. Macway mod' -DESCRIPTION = 't.m.k. firmware for Macway mod' - # Target file name (without extension). TARGET = tmk_macway @@ -74,4 +68,11 @@ MCU = atmega32u4 # Teensy 2.0 # examples use this variable to calculate timings. Do not add a "UL" here. F_CPU = 16000000 + +# Options +# comment out to disable +#USB_NKRO_ENABLE = yes +MOUSEKEY_ENABLE = yes +PS2_MOUSE_ENABLE = yes + include $(COMMON_DIR)/Makefile.common diff --git a/macway/config.h b/macway/config.h new file mode 100644 index 00000000..de9fc78b --- /dev/null +++ b/macway/config.h @@ -0,0 +1,38 @@ +#ifndef CONFIG_H +#define CONFIG_H + +#define VENDOR_ID 0xFEED +#define PRODUCT_ID 0xBEEF +#define MANUFACTURER t.m.k. +#define PRODUCT Macway mod +#define DESCRIPTION t.m.k. keyboard firmware for Macway mod + +/* controller */ +#include "controller_teensy.h" + +/* matrix size */ +#define MATRIX_ROWS 9 +#define MATRIX_COLS 8 + +/* USB NKey Rollover */ +#ifdef USB_NKRO_ENABLE +#endif + +/* mouse keys */ +#ifdef MOUSEKEY_ENABLE +# define MOUSEKEY_DELAY_TIME 192 +#endif + +/* PS/2 mouse */ +#ifdef PS2_MOUSE_ENABLE +# define PS2_CLOCK_PORT PORTF +# define PS2_CLOCK_PIN PINF +# define PS2_CLOCK_DDR DDRF +# define PS2_CLOCK_BIT 0 +# define PS2_DATA_PORT PORTF +# define PS2_DATA_PIN PINF +# define PS2_DATA_DDR DDRF +# define PS2_DATA_BIT 1 +#endif + +#endif diff --git a/macway/controller.h b/macway/controller.h deleted file mode 100644 index 22fd694f..00000000 --- a/macway/controller.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef CONTROLLER_H -#define CONTROLLER_H 1 - -#include "controller_teensy.h" - - -/* matrix row size */ -#define MATRIX_ROWS 9 -/* matrix column size */ -#define MATRIX_COLS 8 - -#endif diff --git a/macway/keymap.c b/macway/keymap.c index e78d6b7d..0e71e3f7 100644 --- a/macway/keymap.c +++ b/macway/keymap.c @@ -10,7 +10,6 @@ #include "print.h" #include "debug.h" #include "util.h" -#include "controller.h" #include "keymap_skel.h" @@ -40,9 +39,9 @@ static const uint8_t PROGMEM fn_layer[] = { 0, 1, 2, 3, 4, 0, 2, 3 }; static const uint8_t PROGMEM fn_keycode[] = { KB_NO, // FN_0 [NOT USED] KB_NO, // FN_1 layer 1 - KB_QUOTE, // FN_2 layer 2 - KB_SCOLON, // FN_3 layer 3 - KB_SPACE, // FN_4 layer 4 + KB_SLSH, // FN_2 layer 2 + KB_SCLN, // FN_3 layer 3 + KB_SPC, // FN_4 layer 4 KB_NO, // FN_5 [NOT USED] KB_NO, // FN_6 layer 2 KB_NO // FN_7 layer 3 @@ -55,38 +54,38 @@ static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { * |-----------------------------------------------------------| * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| | * |-----------------------------------------------------' | - * |Contro| A| S| D| F| G| H| J| K| L|Fn3|Fn2|Return | + * |Contro| A| S| D| F| G| H| J| K| L|Fn3| '|Return | * |-----------------------------------------------------------| * |Shift | Z| X| C| V| B| N| M| ,| .| /|Shift |Fn1| * |-----------------------------------------------------------| - * |Fn7|Gui |Alt |Fn4 |Fn6 |\ |` | | | + * |Fn7|Gui |Alt |Fn4 |Alt |Gui|Fn6|Fn6|Ctr| * `-----------------------------------------------------------' */ KEYMAP(KB_ESC, KB_1, KB_2, KB_3, KB_4, KB_5, KB_6, KB_7, KB_8, KB_9, KB_0, KB_MINS,KB_EQL, KB_BSPC, \ KB_TAB, KB_Q, KB_W, KB_E, KB_R, KB_T, KB_Y, KB_U, KB_I, KB_O, KB_P, KB_LBRC,KB_RBRC, \ - KB_LCTL,KB_A, KB_S, KB_D, KB_F, KB_G, KB_H, KB_J, KB_K, KB_L, FN_3, FN_2, KB_ENT, \ - KB_LSFT,KB_Z, KB_X, KB_C, KB_V, KB_B, KB_N, KB_M, KB_COMM,KB_DOT, KB_SLSH,KB_RSFT,FN_1, \ - FN_7, KB_LGUI,KB_LALT,FN_4, FN_6, KB_BSLS,KB_GRV, KB_NO, KB_NO), + KB_LCTL,KB_A, KB_S, KB_D, KB_F, KB_G, KB_H, KB_J, KB_K, KB_L, FN_3, KB_QUOT,KB_ENT, \ + KB_LSFT,KB_Z, KB_X, KB_C, KB_V, KB_B, KB_N, KB_M, KB_COMM,KB_DOT, FN_2, KB_RSFT,FN_1, \ + FN_7, KB_LGUI,KB_LALT,FN_4, KB_RALT,KB_RGUI,FN_6, FN_6, KB_RCTL), /* Layer 1: HHKB mode (HHKB Fn) * ,-----------------------------------------------------------. - * |Pow| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Delete | + * |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Delete | * |-----------------------------------------------------------| * |Caps | | | | | | | |Psc|Slk|Pus|Up | | | * |-----------------------------------------------------' | - * |Contro| | | | | | *| /|Hom|PgU|Lef|Rig|Enter | + * |Contro|VoD|VoU|Mut| | | *| /|Hom|PgU|Lef|Rig|Enter | * |-----------------------------------------------------------| * |Shift | | | | | | +| -|End|PgD|Dow|Shift |xxx| * |-----------------------------------------------------------| - * | |Gui |Alt | |Alt | | | | | + * | |Gui |Alt | |Alt |Gui| | |Ctr| * `-----------------------------------------------------------' */ - KEYMAP(KB_PWR, KB_F1, KB_F2, KB_F3, KB_F4, KB_F5, KB_F6, KB_F7, KB_F8, KB_F9, KB_F10, KB_F11, KB_F12, KB_DEL, \ + KEYMAP(KB_ESC, KB_F1, KB_F2, KB_F3, KB_F4, KB_F5, KB_F6, KB_F7, KB_F8, KB_F9, KB_F10, KB_F11, KB_F12, KB_DEL, \ KB_CAPS,KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_PSCR,KB_SLCK,KB_BRK, KB_UP, KB_NO, \ - KB_LCTL,KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KP_ASTR,KP_SLSH,KB_HOME,KB_PGUP,KB_LEFT,KB_RGHT,KB_ENT, \ + KB_LCTL,KB_VOLD,KB_VOLU,KB_MUTE,KB_NO, KB_NO, KP_ASTR,KP_SLSH,KB_HOME,KB_PGUP,KB_LEFT,KB_RGHT,KB_ENT, \ KB_LSFT,KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KP_PLUS,KP_MINS,KB_END, KB_PGDN,KB_DOWN,KB_RSFT,FN_1, \ - KB_NO, KB_LGUI,KB_LALT,KB_SPC, KB_RALT,KB_NO, KB_NO, KB_NO, KB_NO), + KB_NO, KB_LGUI,KB_LALT,KB_SPC, KB_RALT,KB_NO, KB_NO, KB_NO, KB_RCTL), /* Layer 2: Vi mode (Quote/Rmeta) @@ -95,27 +94,27 @@ static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { * |-----------------------------------------------------------| * | \ |Hom|PgD|Up |PgU|End|Hom|PgD|PgU|End| | | | | * |-----------------------------------------------------' | - * |Contro| |Lef|Dow|Rig| |Lef|Dow|Up |Rig| |xxx| \ | + * |Contro| |Lef|Dow|Rig| |Lef|Dow|Up |Rig| | | \ | * |-----------------------------------------------------------| - * |Shift | | | | | |Hom|PgD|PgU|End| |Shift | | + * |Shift | | | | | |Hom|PgD|PgU|End|xxx|Shift | | * |-----------------------------------------------------------| - * | |Gui |Alt |Space |xxxxx| | | | | + * | |Gui |Alt |Space |Alt |Gui|Fn6|Fn6|Ctr| * `-----------------------------------------------------------' */ KEYMAP(KB_GRV, KB_F1, KB_F2, KB_F3, KB_F4, KB_F5, KB_F6, KB_F7, KB_F8, KB_F9, KB_F10, KB_F11, KB_F12, KB_GRV, \ KB_BSLS,KB_HOME,KB_PGDN,KB_UP, KB_PGUP,KB_END, KB_HOME,KB_PGDN,KB_PGUP,KB_END, KB_NO, KB_NO, KB_NO, \ - KB_LCTL,KB_NO, KB_LEFT,KB_DOWN,KB_RGHT,KB_NO, KB_LEFT,KB_DOWN,KB_UP, KB_RGHT,KB_NO, FN_2, KB_BSLS, \ - KB_LSFT,KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_RSFT,KB_NO, \ - KB_NO, KB_LGUI,KB_LALT,KB_SPC, FN_6, KB_NO, KB_NO, KB_NO, KB_NO), + KB_LCTL,KB_NO, KB_LEFT,KB_DOWN,KB_RGHT,KB_NO, KB_LEFT,KB_DOWN,KB_UP, KB_RGHT,KB_NO, KB_NO, KB_BSLS, \ + KB_LSFT,KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, FN_2, KB_RSFT,KB_NO, \ + KB_NO, KB_LGUI,KB_LALT,KB_SPC, KB_RALT,KB_RGUI,FN_6, FN_6, KB_RCTL), /* Layer 3: Mouse mode (Semicolon) - * ,-------------------------------------------------------- --. - * |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Delete | + * ,-----------------------------------------------------------. + * | `| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12| ` | * |-----------------------------------------------------------| - * |Tab |MwL|MwD|McU|MwU|MwR|MwL|MwD|MwU|MwR| | | | | + * | \ |MwL|MwD|McU|MwU|MwR|MwL|MwD|MwU|MwR| | | | | * |-----------------------------------------------------' | - * |Contro| |McL|McD|McR| |McL|McD|McU|McR|xxx| |Return | + * |Contro| |McL|McD|McR| |McL|McD|McU|McR|xxx| | \ | * |-----------------------------------------------------------| * |Shift | | |Mb1|Mb2|Mb3|Mb2|Mb1| | | |Shift | | * |-----------------------------------------------------------| @@ -123,9 +122,9 @@ static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { * `-----------------------------------------------------------' * Mc: Mouse Cursor / Mb: Mouse Button / Mw: Mouse Wheel */ - KEYMAP(KB_ESC, KB_F1, KB_F2, KB_F3, KB_F4, KB_F5, KB_F6, KB_F7, KB_F8, KB_F9, KB_F10, KB_F11, KB_F12, KB_DEL, \ - KB_TAB, MS_WH_L,MS_WH_D,MS_UP, MS_WH_U,MS_WH_R,MS_WH_L,MS_WH_D,MS_WH_U,MS_WH_R,KB_NO, KB_NO, KB_NO, \ - KB_LCTL,KB_NO, MS_LEFT,MS_DOWN,MS_RGHT,KB_NO, MS_LEFT,MS_DOWN,MS_UP, MS_RGHT,FN_3, KB_NO, KB_ENT, \ + KEYMAP(KB_GRV, KB_F1, KB_F2, KB_F3, KB_F4, KB_F5, KB_F6, KB_F7, KB_F8, KB_F9, KB_F10, KB_F11, KB_F12, KB_GRV, \ + KB_BSLS,MS_WH_L,MS_WH_D,MS_UP, MS_WH_U,MS_WH_R,MS_WH_L,MS_WH_D,MS_WH_U,MS_WH_R,KB_NO, KB_NO, KB_NO, \ + KB_LCTL,KB_NO, MS_LEFT,MS_DOWN,MS_RGHT,KB_NO, MS_LEFT,MS_DOWN,MS_UP, MS_RGHT,FN_3, KB_NO, KB_BSLS, \ KB_LSFT,KB_NO, KB_NO, MS_BTN1,MS_BTN2,MS_BTN3,MS_BTN2,MS_BTN1,KB_NO, KB_NO, KB_NO, KB_RSFT,KB_NO, \ FN_7, KB_LGUI,KB_LALT,MS_BTN1,KB_RALT,KB_NO, KB_NO, KB_NO, KB_NO), @@ -140,14 +139,14 @@ static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { * |-----------------------------------------------------------| * |Shift | /| .| ,| M| N| B| V| C| X| Z|Shift | | * |-----------------------------------------------------------| - * | |Gui |Alt |xxxxxxxxxxxxxxxxxxxxxx|Alt | | | | | + * | |Gui |Alt |xxxxxxxxxxxxxxxxxxxxxx|Alt |Gui| | |Ctr| * `-----------------------------------------------------------' */ KEYMAP(KB_MINS,KB_0, KB_9, KB_8, KB_7, KB_6, KB_5, KB_4, KB_3, KB_2, KB_1, KB_NO, KB_NO, KB_ESC, \ KB_BSPC,KB_P, KB_O, KB_I, KB_U, KB_Y, KB_T, KB_R, KB_E, KB_W, KB_Q, KB_TAB, KB_TAB, \ KB_LCTL,KB_SCLN,KB_L, KB_K, KB_J, KB_H, KB_G, KB_F, KB_D, KB_S, KB_A, KB_RCTL,KB_RCTL, \ KB_LSFT,KB_SLSH,KB_DOT, KB_COMM,KB_M, KB_N, KB_B, KB_V, KB_C, KB_X, KB_Z, KB_RSFT,KB_NO, \ - KB_NO, KB_LGUI,KB_LALT,FN_4, KB_RALT,KB_NO, KB_NO, KB_NO, KB_NO), + KB_NO, KB_LGUI,KB_LALT,FN_4, KB_RALT,KB_RGUI,KB_NO, KB_NO, KB_RCTL), }; @@ -168,5 +167,6 @@ uint8_t keymap_fn_keycode(uint8_t fn_bits) bool keymap_is_special_mode(uint8_t fn_bits) { - return (usb_keyboard_mods == (BIT_LCTRL | BIT_LSHIFT | BIT_LALT | BIT_LGUI)); + //return (usb_keyboard_mods == (BIT_LCTRL | BIT_LSHIFT | BIT_LALT | BIT_LGUI)); + return (usb_keyboard_mods == (BIT_RSHIFT)); } diff --git a/macway/matrix.c b/macway/matrix.c index c2b3fb8b..7c2a4210 100644 --- a/macway/matrix.c +++ b/macway/matrix.c @@ -7,16 +7,10 @@ #include #include "print.h" #include "util.h" -#include "controller.h" #include "matrix_skel.h" -// matrix is active low. (key on: 0/key off: 1) -// row: Hi-Z(unselected)/low output(selected) -// PD0, PC7, PD7, PF6, PD6, PD1, PD2, PC6, PF7 -// col: input w/pullup -// PB0-PB7 -// matrix state buffer +// matrix state buffer (key on: 1/key off: 0) static uint8_t *matrix; static uint8_t *matrix_prev; static uint8_t _matrix0[MATRIX_ROWS]; @@ -45,6 +39,7 @@ void matrix_init(void) { // initialize row and col unselect_rows(); + // Input with pull-up(DDR:0, PORT:1) DDRB = 0x00; PORTB = 0xFF; @@ -64,11 +59,12 @@ int matrix_scan(void) matrix = tmp; for (int i = 0; i < MATRIX_ROWS; i++) { + unselect_rows(); select_row(i); _delay_us(30); // without this wait read unstable value. matrix[i] = ~read_col(); - unselect_rows(); } + unselect_rows(); return 1; } @@ -145,88 +141,56 @@ static uint8_t read_col(void) static void unselect_rows(void) { - DDRD = 0x00; - PORTD = 0x00; - DDRC = 0x00; - PORTC = 0x00; - DDRF = 0x00; - PORTF = 0x00; + // Hi-Z(DDR:0, PORT:0) to unselect + DDRC &= ~0b11000000; // PC: 7,6 + PORTC &= ~0b11000000; + DDRD &= ~0b11000111; // PD: 7,6,2,1,0 + PORTD &= ~0b11000111; + DDRF &= ~0b11000000; // PF: 7,6 + PORTF &= ~0b11000000; } static void select_row(uint8_t row) { + // Output low(DDR:1, PORT:0) to select + // row: 0 1 2 3 4 5 6 7 8 + // pin: PD0, PC7, PD7, PF6, PD6, PD1, PD2, PC6, PF7 switch (row) { case 0: - DDRD = (1<<0); - PORTD = 0x00; - DDRC = 0x00; - PORTC = 0x00; - DDRF = 0x00; - PORTF = 0x00; + DDRD |= (1<<0); + PORTD &= ~(1<<0); break; case 1: - DDRD = 0x00; - PORTD = 0x00; - DDRC = (1<<7); - PORTC = 0x00; - DDRF = 0x00; - PORTF = 0x00; + DDRC |= (1<<7); + PORTC &= ~(1<<7); break; case 2: - DDRD = (1<<7); - PORTD = 0x00; - DDRC = 0x00; - PORTC = 0x00; - DDRF = 0x00; - PORTF = 0x00; + DDRD |= (1<<7); + PORTD &= ~(1<<7); break; case 3: - DDRD = 0x00; - PORTD = 0x00; - DDRC = 0x00; - PORTC = 0x00; - DDRF = (1<<6); - PORTF = 0x00; + DDRF |= (1<<6); + PORTF &= ~(1<<6); break; case 4: - DDRD = (1<<6); - PORTD = 0x00; - DDRC = 0x00; - PORTC = 0x00; - DDRF = 0x00; - PORTF = 0x00; + DDRD |= (1<<6); + PORTD &= ~(1<<6); break; case 5: - DDRD = (1<<1); - PORTD = 0x00; - DDRC = 0x00; - PORTC = 0x00; - DDRF = 0x00; - PORTF = 0x00; + DDRD |= (1<<1); + PORTD &= ~(1<<1); break; case 6: - DDRD = (1<<2); - PORTD = 0x00; - DDRC = 0x00; - PORTC = 0x00; - DDRF = 0x00; - PORTF = 0x00; + DDRD |= (1<<2); + PORTD &= ~(1<<2); break; case 7: - DDRD = 0x00; - PORTD = 0x00; - DDRC = (1<<6); - PORTC = 0x00; - DDRF = 0x00; - PORTF = 0x00; + DDRC |= (1<<6); + PORTC &= ~(1<<6); break; case 8: - DDRD = 0x00; - PORTD = 0x00; - DDRC = 0x00; - PORTC = 0x00; - DDRF = (1<<7); - PORTF = 0x00; + DDRF |= (1<<7); + PORTF &= ~(1<<7); break; } } diff --git a/mousekey.c b/mousekey.c new file mode 100644 index 00000000..be454e13 --- /dev/null +++ b/mousekey.c @@ -0,0 +1,74 @@ +#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 == MS_UP) mousekey_y -= move_unit(); + else if (code == MS_DOWN) mousekey_y += move_unit(); + else if (code == MS_LEFT) mousekey_x -= move_unit(); + else if (code == MS_RGHT) mousekey_x += move_unit(); + else if (code == MS_BTN1) mousekey_btn |= MOUSE_BTN1; + else if (code == MS_BTN2) mousekey_btn |= MOUSE_BTN2; + else if (code == MS_BTN3) mousekey_btn |= MOUSE_BTN3; + else if (code == MS_BTN4) mousekey_btn |= MOUSE_BTN4; + else if (code == MS_BTN5) mousekey_btn |= MOUSE_BTN5; + else if (code == MS_WH_U) mousekey_v += 1; + else if (code == MS_WH_D) mousekey_v -= 1; + else if (code == MS_WH_L) mousekey_h -= 1; + else if (code == MS_WH_R) 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); + + _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 new file mode 100644 index 00000000..c5d4561c --- /dev/null +++ b/mousekey.h @@ -0,0 +1,11 @@ +#ifndef MOUSEKEY_H +#define MOUSEKEY_H + +#include + +void mousekey_decode(uint8_t code); +bool mousekey_changed(void); +void mousekey_usb_send(void); + +#endif + diff --git a/ps2.c b/ps2.c new file mode 100644 index 00000000..adb425ae --- /dev/null +++ b/ps2.c @@ -0,0 +1,248 @@ +/* +Copyright (c) 2010 Jun WAKO + +This software is licensed with a Modified BSD License. +All of this is supposed to be Free Software, Open Source, DFSG-free, +GPL-compatible, and OK to use in both free and proprietary applications. +Additions and corrections to this file are welcome. + + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + +* Neither the name of the copyright holders nor the names of + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ +#include +#include +#include +#include "ps2.h" +#include "print.h" +#include "debug.h" + + +static inline void clock_lo(void); +static inline void clock_hi(void); +static inline bool clock_in(void); +static inline void data_lo(void); +static inline void data_hi(void); +static inline bool data_in(void); +static inline uint16_t wait_clock_lo(uint16_t us); +static inline uint16_t wait_clock_hi(uint16_t us); +static inline uint16_t wait_data_lo(uint16_t us); +static inline uint16_t wait_data_hi(uint16_t us); + + +/* +Primitive PS/2 Library for AVR +============================== +Host side is only supported now. + + +I/O control +----------- +High state is asserted by input with pull up. + + +PS/2 References +--------------- +http://www.computer-engineering.org/ps2protocol/ +http://www.mcamafia.de/pdf/ibm_hitrc07.pdf +*/ + + +#define WAIT(stat, us, err) do { \ + if (!wait_##stat(us)) { \ + ps2_error = err; \ + goto ERROR; \ + } \ +} while (0) + +#define WAIT_NORETRY(stat, us, err) do { \ + if (!wait_##stat(us)) { \ + ps2_error = err; \ + return 0; \ + } \ +} while (0) + + +uint8_t ps2_error = PS2_ERR_NONE; + + +void ps2_host_init(void) +{ + /* inhibit */ + clock_lo(); + data_hi(); +} + +uint8_t ps2_host_send(uint8_t data) +{ + bool parity = true; + ps2_error = 0; + + /* request to send */ + clock_lo(); + data_lo(); + _delay_us(100); + /* start bit [1] */ + clock_hi(); + WAIT(clock_lo, 15000, 1); + /* data [2-9] */ + for (uint8_t i = 0; i < 8; i++) { + if (data&(1< + +This software is licensed with a Modified BSD License. +All of this is supposed to be Free Software, Open Source, DFSG-free, +GPL-compatible, and OK to use in both free and proprietary applications. +Additions and corrections to this file are welcome. + + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + +* Neither the name of the copyright holders nor the names of + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ +#ifndef PS2_H +#define PS2_H +/* + * Primitive PS/2 Library for AVR + */ + + +/* port settings for clock and data line */ +#if !(defined(PS2_CLOCK_PORT) && \ + defined(PS2_CLOCK_PIN) && \ + defined(PS2_CLOCK_DDR) && \ + defined(PS2_CLOCK_BIT)) +# error "PS/2 clock port setting is required in config.h" +#endif + +#if !(defined(PS2_DATA_PORT) && \ + defined(PS2_DATA_PIN) && \ + defined(PS2_DATA_DDR) && \ + defined(PS2_DATA_BIT)) +# error "PS/2 data port setting is required in config.h" +#endif + +#define PS2_ERR_NONE 0 +#define PS2_ERR_PARITY 0x10 + + +extern uint8_t ps2_error; + +/* host side */ +void ps2_host_init(void); +uint8_t ps2_host_send(uint8_t); +uint8_t ps2_host_recv(void); + +/* TODO: device side */ + +#endif diff --git a/ps2_mouse.c b/ps2_mouse.c new file mode 100644 index 00000000..e22ce633 --- /dev/null +++ b/ps2_mouse.c @@ -0,0 +1,161 @@ +#include +#include +#include +#include "ps2.h" +#include "ps2_mouse.h" +#include "usb_mouse.h" + +#define PS2_MOUSE_DEBUG +#ifdef PS2_MOUSE_DEBUG +# include "print.h" +# include "debug.h" +#else +# define print(s) +# define phex(h) +# define phex16(h) +#endif + +/* +TODO +---- +- Error handling +- Stream mode +- Tracpoint command support: needed +- Middle button + move = Wheel traslation +*/ +uint8_t ps2_mouse_x = 0; +uint8_t ps2_mouse_y = 0; +uint8_t ps2_mouse_btn = 0; +uint8_t ps2_mouse_error_count = 0; +static uint8_t ps2_mouse_btn_prev = 0; + +void ps2_mouse_init(void) { + uint8_t rcv; + + // Reset + rcv = ps2_host_send(0xFF); + print("ps2_mouse_init: send 0xFF: "); + phex(ps2_error); print("\n"); + + // ACK + rcv = ps2_host_recv(); + print("ps2_mouse_init: read ACK: "); + phex(rcv); phex(ps2_error); print("\n"); + + // BAT takes some time + _delay_ms(100); + rcv = ps2_host_recv(); + print("ps2_mouse_init: read BAT: "); + phex(rcv); phex(ps2_error); print("\n"); + + // Device ID + rcv = ps2_host_recv(); + print("ps2_mouse_init: read DevID: "); + phex(rcv); phex(ps2_error); print("\n"); + + // Enable data reporting + ps2_host_send(0xF4); + print("ps2_mouse_init: send 0xF4: "); + phex(ps2_error); print("\n"); + + // ACK + rcv = ps2_host_recv(); + print("ps2_mouse_init: read ACK: "); + phex(rcv); phex(ps2_error); print("\n"); + + // Set Remote mode + ps2_host_send(0xF0); + print("ps2_mouse_init: send 0xF0: "); + phex(ps2_error); print("\n"); + + // ACK + rcv = ps2_host_recv(); + print("ps2_mouse_init: read ACK: "); + phex(rcv); phex(ps2_error); print("\n"); + + if (ps2_error) ps2_mouse_error_count++; +} + +/* +Data format: + bit: 7 6 5 4 3 2 1 0 +----------------------------------------------------------------------- +0 btn: Yovflw Xovflw Ysign Xsign 1 Middle Right Left +1 x: X movement(0-255) +2 y: Y movement(0-255) +*/ +void ps2_mouse_read(void) +{ + uint8_t rcv; + + ps2_host_send(0xEB); + rcv=ps2_host_recv(); + if(rcv==0xFA) { + ps2_mouse_btn = ps2_host_recv(); + ps2_mouse_x = ps2_host_recv(); + ps2_mouse_y = ps2_host_recv(); + } + if (ps2_error) ps2_mouse_error_count++; +} + +bool ps2_mouse_changed(void) +{ + return (ps2_mouse_x || ps2_mouse_y || (ps2_mouse_btn & PS2_MOUSE_BTN_MASK) != ps2_mouse_btn_prev); +} + +#define PS2_MOUSE_SCROLL_BUTTON 0x04 +void ps2_mouse_usb_send(void) +{ + static bool scrolled = false; + if (ps2_mouse_changed()) { + int8_t x, y, v, h; + x = y = v = h = 0; + + // convert scale of X, Y: PS/2(-256/255) -> USB(-127/127) + if (ps2_mouse_btn & (1< 128 ? (int8_t)ps2_mouse_x : -127; + else + x = ps2_mouse_x < 128 ? (int8_t)ps2_mouse_x : 127; + + if (ps2_mouse_btn & (1< 128 ? (int8_t)ps2_mouse_y : -127; + else + y = ps2_mouse_y < 128 ? (int8_t)ps2_mouse_y : 127; + + // Y is needed to reverse + y = -y; + + if (ps2_mouse_btn & PS2_MOUSE_SCROLL_BUTTON) { + // scroll + if (x > 0 || x < 0) h = (x > 64 ? 64 : (x < -64 ? -64 :x)); + if (y > 0 || y < 0) v = (y > 64 ? 64 : (y < -64 ? -64 :y)); + if (h || v) { + scrolled = true; + usb_mouse_send(0,0, -v/16, h/16, 0); + _delay_ms(100); + } + } else if (!scrolled && (ps2_mouse_btn_prev & PS2_MOUSE_SCROLL_BUTTON)) { + usb_mouse_send(0,0,0,0, PS2_MOUSE_SCROLL_BUTTON); + _delay_ms(100); + usb_mouse_send(0,0,0,0, 0); + } else { + scrolled = false; + usb_mouse_send(x, y, 0, 0, ps2_mouse_btn & PS2_MOUSE_BTN_MASK); + } + + ps2_mouse_btn_prev = (ps2_mouse_btn & PS2_MOUSE_BTN_MASK); + ps2_mouse_print(); + } + ps2_mouse_x = 0; + ps2_mouse_y = 0; + ps2_mouse_btn = 0; +} + +void ps2_mouse_print(void) +{ + if (!debug_mouse) return; + print("ps2_mouse[btn|x y]: "); + phex(ps2_mouse_btn); print("|"); + phex(ps2_mouse_x); print(" "); + phex(ps2_mouse_y); print("\n"); +} diff --git a/ps2_mouse.h b/ps2_mouse.h new file mode 100644 index 00000000..f590f3ad --- /dev/null +++ b/ps2_mouse.h @@ -0,0 +1,26 @@ +#ifndef PS2_MOUSE_H +#define PS2_MOUSE_H + +#include + +#define PS2_MOUSE_BTN_MASK 0x07 +#define PS2_MOUSE_BTN_LEFT 0 +#define PS2_MOUSE_BTN_RIGHT 1 +#define PS2_MOUSE_BTN_MIDDLE 2 +#define PS2_MOUSE_X_SIGN 4 +#define PS2_MOUSE_Y_SIGN 5 +#define PS2_MOUSE_X_OVFLW 6 +#define PS2_MOUSE_Y_OVFLW 7 + +extern uint8_t ps2_mouse_x; +extern uint8_t ps2_mouse_y; +extern uint8_t ps2_mouse_btn; +extern uint8_t ps2_mouse_error_count; + +void ps2_mouse_init(void); +void ps2_mouse_read(void); +bool ps2_mouse_changed(void); +void ps2_mouse_usb_send(void); +void ps2_mouse_print(void); + +#endif diff --git a/tmk.c b/tmk.c index b4f76f5d..2248a7d7 100644 --- a/tmk.c +++ b/tmk.c @@ -34,9 +34,12 @@ #include "print.h" #include "debug.h" #include "util.h" -#include "controller.h" #include "timer.h" #include "jump_bootloader.h" +#ifdef PS2_MOUSE_ENABLE +# include "ps2.h" +# include "ps2_mouse.h" +#endif #define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n)) @@ -91,8 +94,12 @@ int main(void) jump_bootloader(); // not return } +#ifdef PS2_MOUSE_ENABLE + ps2_host_init(); + ps2_mouse_init(); +#endif + while (1) { proc_matrix(); - _delay_ms(2); } } diff --git a/usb.c b/usb.c index 803fd340..2ec20ca2 100755 --- a/usb.c +++ b/usb.c @@ -94,7 +94,7 @@ static const uint8_t PROGMEM endpoint_config_table[] = { 1, EP_TYPE_INTERRUPT_IN, EP_SIZE(MOUSE_SIZE) | MOUSE_BUFFER, // 2 1, EP_TYPE_INTERRUPT_IN, EP_SIZE(DEBUG_TX_SIZE) | DEBUG_TX_BUFFER, // 3 1, EP_TYPE_INTERRUPT_IN, EP_SIZE(EXTRA_SIZE) | EXTRA_BUFFER, // 4 -#ifdef NKRO_ENABLE +#ifdef USB_NKRO_ENABLE 1, EP_TYPE_INTERRUPT_IN, EP_SIZE(KBD2_SIZE) | KBD2_BUFFER, // 5 #else 0, // 5 @@ -168,7 +168,7 @@ static uint8_t PROGMEM keyboard_hid_report_desc[] = { 0x81, 0x00, // Input (Data, Array), 0xc0 // End Collection }; -#ifdef NKRO_ENABLE +#ifdef USB_NKRO_ENABLE static uint8_t PROGMEM keyboard2_hid_report_desc[] = { 0x05, 0x01, // Usage Page (Generic Desktop), 0x09, 0x06, // Usage (Keyboard), @@ -336,7 +336,7 @@ static uint8_t PROGMEM extra_hid_report_desc[] = { #define MOUSE_HID_DESC_OFFSET (9+(9+9+7)*1+9) #define DEBUG_HID_DESC_OFFSET (9+(9+9+7)*2+9) #define EXTRA_HID_DESC_OFFSET (9+(9+9+7)*3+9) -#ifdef NKRO_ENABLE +#ifdef USB_NKRO_ENABLE # define NUM_INTERFACES 5 # define KBD2_HID_DESC_OFFSET (9+(9+9+7)*4+9) #else @@ -468,7 +468,7 @@ static uint8_t PROGMEM config1_descriptor[CONFIG1_DESC_SIZE] = { EXTRA_SIZE, 0, // wMaxPacketSize 10, // bInterval -#ifdef NKRO_ENABLE +#ifdef USB_NKRO_ENABLE // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 9, // bLength 4, // bDescriptorType @@ -543,7 +543,7 @@ static struct descriptor_list_struct { {0x2200, DEBUG_INTERFACE, debug_hid_report_desc, sizeof(debug_hid_report_desc)}, {0x2100, EXTRA_INTERFACE, config1_descriptor+EXTRA_HID_DESC_OFFSET, 9}, {0x2200, EXTRA_INTERFACE, extra_hid_report_desc, sizeof(extra_hid_report_desc)}, -#ifdef NKRO_ENABLE +#ifdef USB_NKRO_ENABLE {0x2100, KBD2_INTERFACE, config1_descriptor+KBD2_HID_DESC_OFFSET, 9}, {0x2200, KBD2_INTERFACE, keyboard2_hid_report_desc, sizeof(keyboard2_hid_report_desc)}, #endif @@ -884,7 +884,7 @@ ISR(USB_COM_vect) if (bRequest == HID_GET_REPORT) { if (wValue == HID_REPORT_INPUT) { usb_wait_in_ready(); - UEDATX = mouse_buttons; + UEDATX = 0; UEDATX = 0; UEDATX = 0; UEDATX = 0; @@ -900,14 +900,14 @@ ISR(USB_COM_vect) } if (bRequest == HID_GET_PROTOCOL) { usb_wait_in_ready(); - UEDATX = mouse_protocol; + UEDATX = usb_mouse_protocol; usb_send_in(); return; } } if (bmRequestType == 0x21) { if (bRequest == HID_SET_PROTOCOL) { - mouse_protocol = wValue; + usb_mouse_protocol = wValue; usb_send_in(); return; } diff --git a/usb_keyboard.c b/usb_keyboard.c index 3b071e33..57e23d5f 100644 --- a/usb_keyboard.c +++ b/usb_keyboard.c @@ -28,7 +28,7 @@ uint8_t usb_keyboard_idle_count=0; // 1=num lock, 2=caps lock, 4=scroll lock, 8=compose, 16=kana volatile uint8_t usb_keyboard_leds=0; -// enable NKRO +// enable USB NKRO bool usb_keyboard_nkro = false; @@ -42,7 +42,7 @@ int8_t usb_keyboard_send_report(usb_keyboard_report_t *report) { int8_t result = 0; -#ifdef NKRO_ENABLE +#ifdef USB_NKRO_ENABLE if (usb_keyboard_nkro) result = _send_report(report, KBD2_ENDPOINT, 0, KBD2_REPORT_KEYS); else @@ -106,7 +106,7 @@ static inline void _add_key_byte(uint8_t code); static inline void _add_key_bit(uint8_t code); void usb_keyboard_add_key(uint8_t code) { -#ifdef NKRO_ENABLE +#ifdef USB_NKRO_ENABLE if (usb_keyboard_nkro) { _add_key_bit(code); return; @@ -131,7 +131,7 @@ void usb_keyboard_del_code(uint8_t code) void usb_keyboard_del_key(uint8_t code) { -#ifdef NKRO_ENABLE +#ifdef USB_NKRO_ENABLE if ((code>>3) < KEYS_MAX) { usb_keyboard_keys[code>>3] &= ~(1<<(code&7)); } @@ -169,7 +169,7 @@ bool usb_keyboard_has_mod(void) uint8_t usb_keyboard_get_key(void) { -#ifdef NKRO_ENABLE +#ifdef USB_NKRO_ENABLE if (usb_keyboard_nkro) { uint8_t i = 0; for (; i < KEYS_MAX && !usb_keyboard_keys[i]; i++); diff --git a/usb_keyboard.h b/usb_keyboard.h index ebb3eb04..141efc97 100644 --- a/usb_keyboard.h +++ b/usb_keyboard.h @@ -13,7 +13,7 @@ #define KBD_REPORT_KEYS (KBD_SIZE - 2) // secondary keyboard -#ifdef NKRO_ENABLE +#ifdef USB_NKRO_ENABLE #define KBD2_INTERFACE 4 #define KBD2_ENDPOINT 5 #define KBD2_SIZE 16 diff --git a/usb_mouse.c b/usb_mouse.c index 98292bdd..319b65a1 100644 --- a/usb_mouse.c +++ b/usb_mouse.c @@ -5,40 +5,18 @@ #include "debug.h" -static bool is_sent = false; +uint8_t usb_mouse_protocol=1; -// which buttons are currently pressed -uint8_t mouse_buttons=0; -// protocol setting from the host. We use exactly the same report -// either way, so this variable only stores the setting since we -// are required to be able to report which setting is in use. -uint8_t mouse_protocol=1; - - -// Set the mouse buttons. To create a "click", 2 calls are needed, -// one to push the button down and the second to release it -int8_t usb_mouse_buttons(uint8_t left, uint8_t middle, uint8_t right) -{ - uint8_t mask=0; - - if (left) mask |= 1; - if (middle) mask |= 4; - if (right) mask |= 2; - mouse_buttons = mask; - return usb_mouse_move(0, 0, 0, 0); -} - -// Move the mouse. x, y and wheel are -127 to 127. Use 0 for no movement. -int8_t usb_mouse_move(int8_t x, int8_t y, int8_t wheel, int8_t hwheel) +int8_t usb_mouse_send(int8_t x, int8_t y, int8_t wheel_v, int8_t wheel_h, uint8_t buttons) { uint8_t intr_state, timeout; if (!usb_configured()) return -1; if (x == -128) x = -127; if (y == -128) y = -127; - if (wheel == -128) wheel = -127; - if (hwheel == -128) hwheel = -127; + if (wheel_v == -128) wheel_v = -127; + if (wheel_h == -128) wheel_h = -127; intr_state = SREG; cli(); UENUM = MOUSE_ENDPOINT; @@ -56,34 +34,25 @@ int8_t usb_mouse_move(int8_t x, int8_t y, int8_t wheel, int8_t hwheel) cli(); UENUM = MOUSE_ENDPOINT; } - UEDATX = mouse_buttons; + UEDATX = buttons; UEDATX = x; UEDATX = y; - if (mouse_protocol) { - UEDATX = wheel; - UEDATX = hwheel; + if (usb_mouse_protocol) { + UEDATX = wheel_v; + UEDATX = wheel_h; } 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) { +void usb_mouse_print(int8_t x, int8_t y, int8_t wheel_v, int8_t wheel_h, uint8_t buttons) { if (!debug_mouse) return; - print("mouse btn|x y v h: "); - phex(mouse_buttons); print("|"); - phex(mouse_x); print(" "); - phex(mouse_y); print(" "); + print("usb_mouse[btn|x y v h]: "); + phex(buttons); print("|"); + phex(x); print(" "); + phex(y); print(" "); phex(wheel_v); print(" "); phex(wheel_h); print("\n"); } diff --git a/usb_mouse.h b/usb_mouse.h index da975c26..c092e89f 100644 --- a/usb_mouse.h +++ b/usb_mouse.h @@ -11,21 +11,17 @@ #define MOUSE_SIZE 8 #define MOUSE_BUFFER EP_DOUBLE_BUFFER -#define BIT_BTN1 (1<<0) -#define BIT_BTN2 (1<<1) -#define BIT_BTN3 (1<<2) -#define BIT_BTN4 (1<<3) -#define BIT_BTN5 (1<<4) +#define MOUSE_BTN1 (1<<0) +#define MOUSE_BTN2 (1<<1) +#define MOUSE_BTN3 (1<<2) +#define MOUSE_BTN4 (1<<3) +#define MOUSE_BTN5 (1<<4) -extern uint8_t mouse_buttons; -extern uint8_t mouse_protocol; +extern uint8_t usb_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); +int8_t usb_mouse_send(int8_t x, int8_t y, int8_t wheel_v, int8_t wheel_h, uint8_t buttons); +void usb_mouse_print(int8_t x, int8_t y, int8_t wheel_v, int8_t wheel_h, uint8_t buttons); #endif -- 2.46.2