Browse Source

Add PS/2 mouse support to connect TrackPoint Unit.

Change build options:  Makefile and config.h. See README.
tmk 15 năm trước cách đây
mục cha
commit
2a562a4191
27 tập tin đã thay đổi với 952 bổ sung312 xóa
  1. 30 28
      Makefile.common
  2. 41 0
      README
  3. 14 0
      USB_NKRO.txt
  4. 7 10
      hhkb/Makefile
  5. 40 0
      hhkb/config.h
  6. 0 12
      hhkb/controller.h
  7. 1 2
      hhkb/keymap.c
  8. 2 3
      hhkb/matrix.c
  9. 18 13
      jump_bootloader.c
  10. 55 55
      key_process.c
  11. 7 6
      macway/Makefile
  12. 38 0
      macway/config.h
  13. 0 12
      macway/controller.h
  14. 31 31
      macway/keymap.c
  15. 32 68
      macway/matrix.c
  16. 74 0
      mousekey.c
  17. 11 0
      mousekey.h
  18. 248 0
      ps2.c
  19. 72 0
      ps2.h
  20. 161 0
      ps2_mouse.c
  21. 26 0
      ps2_mouse.h
  22. 9 2
      tmk.c
  23. 8 8
      usb.c
  24. 5 5
      usb_keyboard.c
  25. 1 1
      usb_keyboard.h
  26. 13 44
      usb_mouse.c
  27. 8 12
      usb_mouse.h

+ 30 - 28
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 $(<F)
+#	$(CC) -E $(ALL_CFLAGS) $<
+
 # Change the build target to build a HEX file or a library.
 build: elf hex eep lss sym
 #build: lib

+ 41 - 0
README

@@ -31,6 +31,47 @@ $ make
 http://winavr.sourceforge.net/
 
 
+Build Options
+-------------
+Makefile:
+Comment out to disable the option
+    # USB NKey Rollover
+    USB_NKRO_ENABLE = yes
+
+    # mouse keys
+    MOUSEKEY_ENABLE = yes
+
+    # PS/2 mouse support
+    PS2_MOUSE_ENABLE = yes
+
+config.h:
+    /* USB ID */
+    #define VENDOR_ID       0xFEED
+    #define PRODUCT_ID      0xBEEF
+    /* device description */
+    #define MANUFACTURER    t.m.k.
+    #define PRODUCT         Macway mod
+    #define DESCRIPTION     t.m.k. keyboard firmware for Macway mod
+    /* matrix size */
+    #define MATRIX_ROWS 8
+    #define MATRIX_COLS 8
+    /* mouse keys repeat delay */
+    #define MOUSEKEY_DELAY_TIME 192
+    /* PS/2 lines */
+    #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
+
+
+Configuration
+-------------
+
+
 Debuging & Rescue
 -----------------
 Use PJRC's hid_listen.exe to see debug messages.

+ 14 - 0
USB_NKRO.txt

@@ -143,4 +143,18 @@ This problem will be reportedly fixed soon.(2010/12/05)
     http://forums.anandtech.com/showpost.php?p=30873364&postcount=17
 
 
+Tools for testing NKRO
+----------------------
+Browser App:
+http://www.microsoft.com/appliedsciences/content/projects/KeyboardGhostingDemo.aspx
+http://random.xem.us/rollover.html
+
+Windows:
+AquaKeyTest.exe http://geekhack.org/showthread.php?t=6643
+
+Linux:
+xkeycaps
+xev
+showkeys
+
 EOF

+ 7 - 10
hhkb/Makefile

@@ -39,16 +39,6 @@
 # To rebuild project do "make clean" then "make all".
 #----------------------------------------------------------------------------
 
-# TODO: use config.h for build options?
-VENDOR_ID = 0xFEED
-PRODUCT_ID = 0xCAFE
-MANUFACTURER = 't.m.k.'
-PRODUCT = 'HHKB Mod'
-DESCRIPTION = 't.m.k. firmware for HHKB pro'
-
-MOUSE_DELAY_TIME = 127
-NKRO_ENABLE = true
-
 # Target file name (without extension).
 TARGET = tmk_hhkb
 
@@ -78,4 +68,11 @@ MCU = at90usb1286      # 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

+ 40 - 0
hhkb/config.h

@@ -0,0 +1,40 @@
+#ifndef CONFIG_H
+#define CONFIG_H
+
+#define VENDOR_ID       0xFEED
+#define PRODUCT_ID      0xCAFE
+#define MANUFACTURER    t.m.k.
+#define PRODUCT         HHKB mod
+#define DESCRIPTION     t.m.k. keyboard firmware for HHKB mod
+
+/* controller */
+#include "controller_teensy.h"
+
+/* matrix size */
+#define MATRIX_ROWS 8
+#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

+ 0 - 12
hhkb/controller.h

@@ -1,12 +0,0 @@
-#ifndef CONTROLLER_H
-#define CONTROLLER_H 1
-
-#include "controller_teensy.h"
-
-
-/* matrix row size */
-#define MATRIX_ROWS 8
-/* matrix column size */
-#define MATRIX_COLS 8
-
-#endif

+ 1 - 2
hhkb/keymap.c

@@ -9,7 +9,6 @@
 #include "print.h"
 #include "debug.h"
 #include "util.h"
-#include "controller.h"
 #include "keymap_skel.h"
 
 
@@ -75,7 +74,7 @@ static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
      * |-----------------------------------------------------------|
      * |Caps |   |   |   |   |   |   |   |Psc|Slk|Pus|Up |   |Backs|
      * |-----------------------------------------------------------|
-     * |Contro|   |   |   |   |   |  *|  /|Hom|PgU|Lef|Rig|Enter   |
+     * |Contro|VoD|VoU|Mut|   |   |  *|  /|Hom|PgU|Lef|Rig|Enter   |
      * |-----------------------------------------------------------|
      * |Shift   |   |   |   |   |   |  +|  -|End|PgD|Dow|Shift |xxx|
      * `-----------------------------------------------------------'

+ 2 - 3
hhkb/matrix.c

@@ -7,7 +7,6 @@
 #include <util/delay.h>
 #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;

+ 18 - 13
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
 }

+ 55 - 55
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
 }

+ 7 - 6
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

+ 38 - 0
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

+ 0 - 12
macway/controller.h

@@ -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

+ 31 - 31
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));
 }

+ 32 - 68
macway/matrix.c

@@ -7,16 +7,10 @@
 #include <util/delay.h>
 #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;
     }
 }

+ 74 - 0
mousekey.c

@@ -0,0 +1,74 @@
+#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 == 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;
+}

+ 11 - 0
mousekey.h

@@ -0,0 +1,11 @@
+#ifndef MOUSEKEY_H
+#define  MOUSEKEY_H
+
+#include <stdbool.h>
+
+void mousekey_decode(uint8_t code);
+bool mousekey_changed(void);
+void mousekey_usb_send(void);
+
+#endif
+

+ 248 - 0
ps2.c

@@ -0,0 +1,248 @@
+/*
+Copyright (c) 2010 Jun WAKO <wakojun@gmail.com>
+
+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 <stdbool.h>
+#include <avr/io.h>
+#include <util/delay.h>
+#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<<i)) {
+            parity = !parity;
+            data_hi();
+        } else {
+            data_lo();
+        }
+        WAIT(clock_hi, 50, 2);
+        WAIT(clock_lo, 50, 3);
+    }
+    /* parity [10] */
+    if (parity) { data_hi(); } else { data_lo(); }
+    WAIT(clock_hi, 50, 4);
+    WAIT(clock_lo, 50, 5);
+    /* stop bit [11] */
+    data_hi();
+    /* ack [12] */
+    WAIT(data_lo, 50, 6);
+    WAIT(clock_lo, 50, 7);
+    WAIT(clock_hi, 50, 8);
+    WAIT(data_hi, 50, 9);
+
+    /* inhibit device to send */
+    clock_lo();
+
+    return 1;
+ERROR:
+    return 0;
+}
+
+uint8_t ps2_host_recv(void)
+{
+    uint8_t data = 0;
+    bool parity = true;
+    ps2_error = 0;
+
+    /* cancel to sync */
+    clock_lo();
+    _delay_us(100);
+
+    /* release lines(idle state) */
+    clock_hi();
+    data_hi();
+
+    /* start bit [1] */
+    WAIT(clock_lo, 20000, 1);
+    WAIT(data_lo, 1, 2);
+    WAIT(clock_hi, 50, 3);
+
+    /* data [2-9] */
+    for (uint8_t i = 0; i < 8; i++) {
+        WAIT(clock_lo, 50, 4);
+        if (data_in()) {
+            parity = !parity;
+            data |= (1<<i);
+        }
+        WAIT(clock_hi, 50, 5);
+    }
+
+    /* parity [10] */
+    WAIT(clock_lo, 50, 6);
+    if (data_in() != parity) {
+        ps2_error = PS2_ERR_PARITY;
+        goto ERROR;
+    }
+    WAIT(clock_hi, 50, 7);
+
+    /* stop bit [11] */
+    WAIT(clock_lo, 50, 8);
+    WAIT(data_hi, 1, 9);
+    WAIT(clock_hi, 50, 10);
+
+    /* inhibit device to send */
+    clock_lo();
+
+    return data;
+ERROR:
+    return 0;
+}
+
+
+static inline void clock_lo()
+{
+    PS2_CLOCK_PORT &= ~(1<<PS2_CLOCK_BIT);
+    PS2_CLOCK_DDR  |=  (1<<PS2_CLOCK_BIT);
+}
+static inline void clock_hi()
+{
+    /* input with pull up */
+    PS2_CLOCK_DDR  &= ~(1<<PS2_CLOCK_BIT);
+    PS2_CLOCK_PORT |=  (1<<PS2_CLOCK_BIT);
+}
+static inline bool clock_in()
+{
+    PS2_CLOCK_DDR  &= ~(1<<PS2_CLOCK_BIT);
+    PS2_CLOCK_PORT |=  (1<<PS2_CLOCK_BIT);
+    return PS2_CLOCK_PIN&(1<<PS2_CLOCK_BIT);
+}
+static inline void data_lo()
+{
+    PS2_DATA_PORT &= ~(1<<PS2_DATA_BIT);
+    PS2_DATA_DDR  |=  (1<<PS2_DATA_BIT);
+}
+static inline void data_hi()
+{
+    /* input with pull up */
+    PS2_DATA_DDR  &= ~(1<<PS2_DATA_BIT);
+    PS2_DATA_PORT |=  (1<<PS2_DATA_BIT);
+}
+static inline bool data_in()
+{
+    PS2_DATA_DDR  &= ~(1<<PS2_DATA_BIT);
+    PS2_DATA_PORT |=  (1<<PS2_DATA_BIT);
+    return PS2_DATA_PIN&(1<<PS2_DATA_BIT);
+}
+
+static inline uint16_t wait_clock_lo(uint16_t us)
+{
+    while (clock_in()  && us) { asm(""); _delay_us(1); us--; }
+    return us;
+}
+static inline uint16_t wait_clock_hi(uint16_t us)
+{
+    while (!clock_in() && us) { asm(""); _delay_us(1); us--; }
+    return us;
+}
+static inline uint16_t wait_data_lo(uint16_t us)
+{
+    while (data_in() && us)  { asm(""); _delay_us(1); us--; }
+    return us;
+}
+static inline uint16_t wait_data_hi(uint16_t us)
+{
+    while (!data_in() && us)  { asm(""); _delay_us(1); us--; }
+    return us;
+}

+ 72 - 0
ps2.h

@@ -0,0 +1,72 @@
+/*
+Copyright (c) 2010 Jun WAKO <wakojun@gmail.com>
+
+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

+ 161 - 0
ps2_mouse.c

@@ -0,0 +1,161 @@
+#include <stdbool.h>
+#include<avr/io.h>
+#include<util/delay.h>
+#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<<PS2_MOUSE_X_SIGN))
+            x = ps2_mouse_x > 128 ? (int8_t)ps2_mouse_x : -127;
+        else
+            x = ps2_mouse_x < 128 ? (int8_t)ps2_mouse_x : 127;
+
+        if (ps2_mouse_btn & (1<<PS2_MOUSE_Y_SIGN))
+            y = ps2_mouse_y > 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");
+}

+ 26 - 0
ps2_mouse.h

@@ -0,0 +1,26 @@
+#ifndef PS2_MOUSE_H
+#define  PS2_MOUSE_H
+
+#include <stdbool.h>
+
+#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

+ 9 - 2
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);
     }
 }

+ 8 - 8
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;
 				}

+ 5 - 5
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++);

+ 1 - 1
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

+ 13 - 44
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");
 }

+ 8 - 12
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