]> git.friedersdorff.com Git - max/tmk_keyboard.git/commitdiff
added initial support of mousekeys to ps2_vusb
authortmk <nobody@nowhere>
Thu, 3 Feb 2011 04:26:44 +0000 (13:26 +0900)
committertmk <nobody@nowhere>
Mon, 21 Feb 2011 18:08:52 +0000 (03:08 +0900)
14 files changed:
Makefile.vusb
ps2_vusb/Makefile
ps2_vusb/host.h [new file with mode: 0644]
ps2_vusb/host_vusb.c [new file with mode: 0644]
ps2_vusb/host_vusb.h [new file with mode: 0644]
ps2_vusb/keyboard.c [new file with mode: 0644]
ps2_vusb/keyboard.h
ps2_vusb/keyboard_vusb.c [deleted file]
ps2_vusb/layer.c
ps2_vusb/main.c
ps2_vusb/matrix.c
ps2_vusb/mousekey.c [new file with mode: 0644]
ps2_vusb/mousekey.h [new file with mode: 0644]
ps2_vusb/usbconfig.h

index b372ce25288003ff0aee786fcac98a9131c16c4e..8ee2209c00a9382334a112fc4ac8ef00811bd913 100644 (file)
@@ -65,7 +65,7 @@ FORMAT = ihex
 # Object files directory
 #     To put object files in current directory, use a dot (.), do NOT make
 #     this an empty or blank macro!
-OBJDIR = .
+OBJDIR = obj
 
 
 # Optimization level, can be [0, 1, 2, 3, s]. 
@@ -347,7 +347,7 @@ AR = avr-ar rcs
 NM = avr-nm
 AVRDUDE = avrdude
 REMOVE = rm -f
-REMOVEDIR = rm -rf
+REMOVEDIR = rmdir
 COPY = cp
 WINSHELL = cmd
 
@@ -601,7 +601,8 @@ clean_list :
        $(REMOVE) $(LST)
        $(REMOVE) $(OBJ:.o=.s)
        $(REMOVE) $(OBJ:.o=.i)
-       $(REMOVEDIR) .dep
+       $(REMOVE) -r .dep
+       $(REMOVEDIR) $(OBJDIR)
 
 
 # Create object files directory
index 48748a7492e8d65926c16c564e9892c62082f709..5b25e5143973bdd5b649725aa2c0c7c239b4d96d 100644 (file)
@@ -9,11 +9,13 @@ TARGET_DIR = .
 
 # keyboard dependent files
 TARGET_SRC =   main.c \
-               keyboard_vusb.c \
+               keyboard.c \
+               mousekey.c \
                layer.c \
                keymap.c \
                matrix.c \
                ps2.c \
+               host_vusb.c \
                print.c \
                util.c \
                timer.c \
diff --git a/ps2_vusb/host.h b/ps2_vusb/host.h
new file mode 100644 (file)
index 0000000..b4b9eef
--- /dev/null
@@ -0,0 +1,35 @@
+#ifndef HOST_H
+#define HOST_H
+
+#include <stdint.h>
+
+
+#define REPORT_KEYS 6
+#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)
+
+
+typedef struct {
+    uint8_t mods;
+    uint8_t rserved;    // not used
+    uint8_t keys[REPORT_KEYS];
+} report_keyboard_t;
+
+typedef struct {
+    uint8_t buttons;
+    int8_t x;
+    int8_t y;
+/*
+    int8_t v;
+    int8_t h;
+ */
+} report_mouse_t;
+
+
+void host_keyboard_send(report_keyboard_t *report);
+void host_mouse_send(report_mouse_t *report);
+
+#endif
diff --git a/ps2_vusb/host_vusb.c b/ps2_vusb/host_vusb.c
new file mode 100644 (file)
index 0000000..cda9048
--- /dev/null
@@ -0,0 +1,345 @@
+#include "usbdrv.h"
+#include "usbconfig.h"
+#include "keyboard.h"
+#include "print.h"
+#include "host.h"
+#include "host_vusb.h"
+
+
+#define KBUF_SIZE 8
+static report_keyboard_t kbuf[KBUF_SIZE];
+static uint8_t kbuf_head = 0;
+static uint8_t kbuf_tail = 0;
+
+
+void host_vusb_keyboard_send()
+{
+    if (kbuf_head != kbuf_tail) {
+        if (usbInterruptIsReady()) {
+            usbSetInterrupt((void *)&kbuf[kbuf_tail], sizeof(report_keyboard_t));
+            kbuf_tail = (kbuf_tail + 1) % KBUF_SIZE;
+        }
+    }
+}
+
+void host_keyboard_send(report_keyboard_t *report)
+{
+    uint8_t next = (kbuf_head + 1) % KBUF_SIZE;
+    if (next != kbuf_tail) {
+        kbuf[kbuf_head] = *report;
+        kbuf_head = next;
+    }
+}
+
+void host_mouse_send(report_mouse_t *report)
+{
+    // dirty hack to send twice a loop :(
+    //while (!usbInterruptIsReady3()) usbPoll();
+
+    if (usbInterruptIsReady3()) {
+        usbSetInterrupt3((void *)report, sizeof(*report));
+    } else {
+        print("Int3 not ready\n");
+    }
+}
+
+
+
+
+
+static uchar    idleRate;   /* repeat rate for keyboards, never used for mice */
+usbMsgLen_t usbFunctionSetup(uchar data[8])
+{
+usbRequest_t    *rq = (void *)data;
+
+    print("Setup: ");
+    if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){    /* class request type */
+        print("CLASS: ");
+        phex(rq->bRequest);
+        if(rq->bRequest == USBRQ_HID_GET_REPORT){
+            print("GET_REPORT");
+            /* we only have one report type, so don't look at wValue */
+            usbMsgPtr = (void *)keyboard_report;
+            return sizeof(*keyboard_report);
+        }else if(rq->bRequest == USBRQ_HID_GET_IDLE){
+            print("GET_IDLE: ");
+            phex(idleRate);
+            usbMsgPtr = &idleRate;
+            return 1;
+        }else if(rq->bRequest == USBRQ_HID_SET_IDLE){
+            idleRate = rq->wValue.bytes[1];
+            print("SET_IDLE: ");
+            phex(idleRate);
+        }
+        print("\n");
+    }else{
+        print("VENDOR\n");
+        /* no vendor specific requests implemented */
+    }
+    return 0;   /* default for not implemented requests: return no data back to host */
+}
+
+
+PROGMEM uchar keyboard_hid_report[] = {
+    0x05, 0x01,          // Usage Page (Generic Desktop),
+    0x09, 0x06,          // Usage (Keyboard),
+    0xA1, 0x01,          // Collection (Application),
+    0x75, 0x01,          //   Report Size (1),
+    0x95, 0x08,          //   Report Count (8),
+    0x05, 0x07,          //   Usage Page (Key Codes),
+    0x19, 0xE0,          //   Usage Minimum (224),
+    0x29, 0xE7,          //   Usage Maximum (231),
+    0x15, 0x00,          //   Logical Minimum (0),
+    0x25, 0x01,          //   Logical Maximum (1),
+    0x81, 0x02,          //   Input (Data, Variable, Absolute), ;Modifier byte
+    0x95, 0x01,          //   Report Count (1),
+    0x75, 0x08,          //   Report Size (8),
+    0x81, 0x03,          //   Input (Constant),                 ;Reserved byte
+    0x95, 0x05,          //   Report Count (5),
+    0x75, 0x01,          //   Report Size (1),
+    0x05, 0x08,          //   Usage Page (LEDs),
+    0x19, 0x01,          //   Usage Minimum (1),
+    0x29, 0x05,          //   Usage Maximum (5),
+    0x91, 0x02,          //   Output (Data, Variable, Absolute), ;LED report
+    0x95, 0x01,          //   Report Count (1),
+    0x75, 0x03,          //   Report Size (3),
+    0x91, 0x03,          //   Output (Constant),                 ;LED report padding
+    0x95, 0x06,          //   Report Count (6),
+    0x75, 0x08,          //   Report Size (8),
+    0x15, 0x00,          //   Logical Minimum (0),
+    0x25, 0xFF,          //   Logical Maximum(255),
+    0x05, 0x07,          //   Usage Page (Key Codes),
+    0x19, 0x00,          //   Usage Minimum (0),
+    0x29, 0xFF,          //   Usage Maximum (255),
+    0x81, 0x00,          //   Input (Data, Array),
+    0xc0                 // End Collection
+};
+
+// Mouse Protocol 1, HID 1.11 spec, Appendix B, page 59-60, with wheel extension
+// http://www.microchip.com/forums/tm.aspx?high=&m=391435&mpage=1#391521
+// http://www.keil.com/forum/15671/
+// http://www.microsoft.com/whdc/device/input/wheel.mspx
+PROGMEM uchar mouse_hid_report[] = {
+    /* from HID 1.11 spec example */
+    0x05, 0x01,     // Usage Page (Generic Desktop),
+    0x09, 0x02,     // Usage (Mouse),
+    0xA1, 0x01,     // Collection (Application),
+    0x09, 0x01,     //   Usage (Pointer),
+    0xA1, 0x00,     //   Collection (Physical),
+    0x05, 0x09,     //     Usage Page (Buttons),
+    0x19, 0x01,     //     Usage Minimum (01),
+    0x29, 0x03,     //     Usage Maximun (03),
+    0x15, 0x00,     //     Logical Minimum (0),
+    0x25, 0x01,     //     Logical Maximum (1),
+    0x95, 0x03,     //     Report Count (3),
+    0x75, 0x01,     //     Report Size (1),
+    0x81, 0x02,     //     Input (Data, Variable, Absolute), ;3 button bits
+    0x95, 0x01,     //     Report Count (1),
+    0x75, 0x05,     //     Report Size (5),
+    0x81, 0x01,     //     Input (Constant), ;5 bit padding
+    0x05, 0x01,     //     Usage Page (Generic Desktop),
+    0x09, 0x30,     //     Usage (X),
+    0x09, 0x31,     //     Usage (Y),
+    0x15, 0x81,     //     Logical Minimum (-127),
+    0x25, 0x7F,     //     Logical Maximum (127),
+    0x75, 0x08,     //     Report Size (8),
+    0x95, 0x02,     //     Report Count (2),
+    0x81, 0x06,     //     Input (Data, Variable, Relative), ;2 position bytes (X & Y)
+    0xC0,           //   End Collection,
+    0xC0,           // End Collection
+/*
+    0x05, 0x01,        // USAGE_PAGE (Generic Desktop)
+    0x09, 0x02,        // USAGE (Mouse)
+    0xa1, 0x01,        // COLLECTION (Application)
+    0x09, 0x02,        //   USAGE (Mouse)
+    0xa1, 0x02,        //   COLLECTION (Logical)
+    0x09, 0x01,        //     USAGE (Pointer)
+    0xa1, 0x00,        //     COLLECTION (Physical)
+                       // ------------------------------  Buttons
+    0x05, 0x09,        //       USAGE_PAGE (Button)
+    0x19, 0x01,        //       USAGE_MINIMUM (Button 1)
+    0x29, 0x05,        //       USAGE_MAXIMUM (Button 5)
+    0x15, 0x00,        //       LOGICAL_MINIMUM (0)
+    0x25, 0x01,        //       LOGICAL_MAXIMUM (1)
+    0x75, 0x01,        //       REPORT_SIZE (1)
+    0x95, 0x05,        //       REPORT_COUNT (5)
+    0x81, 0x02,        //       INPUT (Data,Var,Abs)
+                       // ------------------------------  Padding
+    0x75, 0x03,        //       REPORT_SIZE (3)
+    0x95, 0x01,        //       REPORT_COUNT (1)
+    0x81, 0x03,        //       INPUT (Cnst,Var,Abs)
+                       // ------------------------------  X,Y position
+    0x05, 0x01,        //       USAGE_PAGE (Generic Desktop)
+    0x09, 0x30,        //       USAGE (X)
+    0x09, 0x31,        //       USAGE (Y)
+    0x15, 0x81,        //       LOGICAL_MINIMUM (-127)
+    0x25, 0x7f,        //       LOGICAL_MAXIMUM (127)
+    0x75, 0x08,        //       REPORT_SIZE (8)
+    0x95, 0x02,        //       REPORT_COUNT (2)
+    0x81, 0x06,        //       INPUT (Data,Var,Rel)
+    0xa1, 0x02,        //       COLLECTION (Logical)
+                       // ------------------------------  Vertical wheel res multiplier
+    0x09, 0x48,        //         USAGE (Resolution Multiplier)
+    0x15, 0x00,        //         LOGICAL_MINIMUM (0)
+    0x25, 0x01,        //         LOGICAL_MAXIMUM (1)
+    0x35, 0x01,        //         PHYSICAL_MINIMUM (1)
+    0x45, 0x04,        //         PHYSICAL_MAXIMUM (4)
+    0x75, 0x02,        //         REPORT_SIZE (2)
+    0x95, 0x01,        //         REPORT_COUNT (1)
+    0xa4,              //         PUSH
+    0xb1, 0x02,        //         FEATURE (Data,Var,Abs)
+                       // ------------------------------  Vertical wheel
+    0x09, 0x38,        //         USAGE (Wheel)
+    0x15, 0x81,        //         LOGICAL_MINIMUM (-127)
+    0x25, 0x7f,        //         LOGICAL_MAXIMUM (127)
+    0x35, 0x00,        //         PHYSICAL_MINIMUM (0)        - reset physical
+    0x45, 0x00,        //         PHYSICAL_MAXIMUM (0)
+    0x75, 0x08,        //         REPORT_SIZE (8)
+    0x81, 0x06,        //         INPUT (Data,Var,Rel)
+    0xc0,              //       END_COLLECTION
+    0xa1, 0x02,        //       COLLECTION (Logical)
+                       // ------------------------------  Horizontal wheel res multiplier
+    0x09, 0x48,        //         USAGE (Resolution Multiplier)
+    0xb4,              //         POP
+    0xb1, 0x02,        //         FEATURE (Data,Var,Abs)
+                       // ------------------------------  Padding for Feature report
+    0x35, 0x00,        //         PHYSICAL_MINIMUM (0)        - reset physical
+    0x45, 0x00,        //         PHYSICAL_MAXIMUM (0)
+    0x75, 0x04,        //         REPORT_SIZE (4)
+    0xb1, 0x03,        //         FEATURE (Cnst,Var,Abs)
+                       // ------------------------------  Horizontal wheel
+    0x05, 0x0c,        //         USAGE_PAGE (Consumer Devices)
+    0x0a, 0x38, 0x02,  //         USAGE (AC Pan)
+    0x15, 0x81,        //         LOGICAL_MINIMUM (-127)
+    0x25, 0x7f,        //         LOGICAL_MAXIMUM (127)
+    0x75, 0x08,        //         REPORT_SIZE (8)
+    0x81, 0x06,        //         INPUT (Data,Var,Rel)
+    0xc0,              //       END_COLLECTION
+    0xc0,              //     END_COLLECTION
+    0xc0,              //   END_COLLECTION
+    0xc0               // END_COLLECTION
+*/
+};
+
+
+/* Descriptor for compite device: Keyboard + Mouse */
+#if USB_CFG_DESCR_PROPS_CONFIGURATION
+PROGMEM char usbDescriptorConfiguration[] = {    /* USB configuration descriptor */
+    9,          /* sizeof(usbDescriptorConfiguration): length of descriptor in bytes */
+    USBDESCR_CONFIG,    /* descriptor type */
+    9 + (9 + 9 + 7) + (9 + 9 + 7), 0,
+    //18 + 7 * USB_CFG_HAVE_INTRIN_ENDPOINT + 7 * USB_CFG_HAVE_INTRIN_ENDPOINT3 + 9, 0,
+                /* total length of data returned (including inlined descriptors) */
+    2,          /* number of interfaces in this configuration */
+    1,          /* index of this configuration */
+    0,          /* configuration name string index */
+#if USB_CFG_IS_SELF_POWERED
+    (1 << 7) | USBATTR_SELFPOWER,       /* attributes */
+#else
+    (1 << 7),                           /* attributes */
+#endif
+    USB_CFG_MAX_BUS_POWER/2,            /* max USB current in 2mA units */
+
+    /*
+     * Keyboard interface
+     */
+    /* Interface descriptor */
+    9,          /* sizeof(usbDescrInterface): length of descriptor in bytes */
+    USBDESCR_INTERFACE, /* descriptor type */
+    0,          /* index of this interface */
+    0,          /* alternate setting for this interface */
+    USB_CFG_HAVE_INTRIN_ENDPOINT, /* endpoints excl 0: number of endpoint descriptors to follow */
+    USB_CFG_INTERFACE_CLASS,
+    USB_CFG_INTERFACE_SUBCLASS,
+    USB_CFG_INTERFACE_PROTOCOL,
+    0,          /* string index for interface */
+    /* HID descriptor */
+    9,          /* sizeof(usbDescrHID): length of descriptor in bytes */
+    USBDESCR_HID,   /* descriptor type: HID */
+    0x01, 0x01, /* BCD representation of HID version */
+    0x00,       /* target country code */
+    0x01,       /* number of HID Report (or other HID class) Descriptor infos to follow */
+    0x22,       /* descriptor type: report */
+    sizeof(keyboard_hid_report), 0,  /* total length of report descriptor */
+    /* Endpoint descriptor */
+#if USB_CFG_HAVE_INTRIN_ENDPOINT    /* endpoint descriptor for endpoint 1 */
+    7,          /* sizeof(usbDescrEndpoint) */
+    USBDESCR_ENDPOINT,  /* descriptor type = endpoint */
+    (char)0x81, /* IN endpoint number 1 */
+    0x03,       /* attrib: Interrupt endpoint */
+    8, 0,       /* maximum packet size */
+    USB_CFG_INTR_POLL_INTERVAL, /* in ms */
+#endif
+
+    /*
+     * Mouse interface
+     */
+    /* Interface descriptor */
+    9,          /* sizeof(usbDescrInterface): length of descriptor in bytes */
+    USBDESCR_INTERFACE, /* descriptor type */
+    1,          /* index of this interface */
+    0,          /* alternate setting for this interface */
+    USB_CFG_HAVE_INTRIN_ENDPOINT3, /* endpoints excl 0: number of endpoint descriptors to follow */
+    0x03,       /* CLASS: HID */
+    0,          /* SUBCLASS: none */
+    0,          /* PROTOCOL: none */
+    0,          /* string index for interface */
+    /* HID descriptor */
+    9,          /* sizeof(usbDescrHID): length of descriptor in bytes */
+    USBDESCR_HID,   /* descriptor type: HID */
+    0x01, 0x01, /* BCD representation of HID version */
+    0x00,       /* target country code */
+    0x01,       /* number of HID Report (or other HID class) Descriptor infos to follow */
+    0x22,       /* descriptor type: report */
+    sizeof(mouse_hid_report), 0,  /* total length of report descriptor */
+#if USB_CFG_HAVE_INTRIN_ENDPOINT3   /* endpoint descriptor for endpoint 3 */
+    /* Endpoint descriptor */
+    7,          /* sizeof(usbDescrEndpoint) */
+    USBDESCR_ENDPOINT,  /* descriptor type = endpoint */
+    (char)(0x80 | USB_CFG_EP3_NUMBER), /* IN endpoint number 3 */
+    0x03,       /* attrib: Interrupt endpoint */
+    8, 0,       /* maximum packet size */
+    USB_CFG_INTR_POLL_INTERVAL, /* in ms */
+#endif
+};
+#endif
+
+USB_PUBLIC usbMsgLen_t usbFunctionDescriptor(struct usbRequest *rq)
+{
+    usbMsgLen_t len = 0;
+
+    print("usbFunctionDescriptor: ");
+    phex(rq->bmRequestType); print(" ");
+    phex(rq->bRequest); print(" ");
+    phex16(rq->wValue.word); print(" ");
+    phex16(rq->wIndex.word); print(" ");
+    phex16(rq->wLength.word); print("\n");
+
+    switch (rq->wValue.bytes[1]) {
+#if USB_CFG_DESCR_PROPS_CONFIGURATION
+        case USBDESCR_CONFIG:
+            usbMsgPtr = (unsigned char *)usbDescriptorConfiguration;
+            len = sizeof(usbDescriptorConfiguration);
+            break;
+#endif
+        case USBDESCR_HID:
+            usbMsgPtr = (unsigned char *)(usbDescriptorConfiguration + 18);
+            len = 9;
+            break;
+        case USBDESCR_HID_REPORT:
+            /* interface index */
+            switch (rq->wIndex.word) {
+                case 0:
+                    usbMsgPtr = keyboard_hid_report;
+                    len = sizeof(keyboard_hid_report);
+                    break;
+                case 1:
+                    usbMsgPtr = mouse_hid_report;
+                    len = sizeof(mouse_hid_report);
+                    break;
+            }
+            break;
+    }
+    print("desc len: "); phex(len); print("\n");
+    return len;
+}
diff --git a/ps2_vusb/host_vusb.h b/ps2_vusb/host_vusb.h
new file mode 100644 (file)
index 0000000..c9b1d77
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef HOST_VUSB_H
+#define HOST_VUSB_H
+
+void host_vusb_keyboard_send(void);
+
+#endif
+
diff --git a/ps2_vusb/keyboard.c b/ps2_vusb/keyboard.c
new file mode 100644 (file)
index 0000000..95f6588
--- /dev/null
@@ -0,0 +1,79 @@
+#include "usb_keycodes.h"
+#include "host.h"
+#include "keyboard.h"
+
+static report_keyboard_t report0;
+static report_keyboard_t report1;
+static report_keyboard_t *report = &report0;
+static report_keyboard_t *report_prev = &report1;
+
+void keyboard_send(void)
+{
+    host_keyboard_send(report);
+}
+
+bool keyboard_has_key(void)
+{
+    for (int i = 0; i < REPORT_KEYS; i++) {
+        if (report->keys[i])
+            return true;
+    }
+    return false;
+}
+
+void keyboard_add_mod(uint8_t mod)
+{
+    report->mods |= mod;
+}
+
+void keyboard_add_key(uint8_t code)
+{
+    int8_t i = 0;
+    int8_t empty = -1;
+    for (; i < REPORT_KEYS; i++) {
+        if (report_prev->keys[i] == code) {
+            report->keys[i] = code;
+            break;
+        }
+        if (empty == -1 && report_prev->keys[i] == KB_NO && report->keys[i] == KB_NO) {
+            empty = i;
+        }
+    }
+    if (i == REPORT_KEYS && empty != -1) {
+        report->keys[empty] = code;
+    }
+}
+
+void keyboard_add_code(uint8_t code)
+{
+    if (IS_MOD(code)) {
+        keyboard_add_mod(code);
+    } else {
+        keyboard_add_key(code);
+    }
+}
+
+void keyboard_swap_report(void)
+{
+    report_keyboard_t *tmp = report_prev;
+    report_prev = report;
+    report = tmp;
+}
+
+void keyboard_clear_report(void)
+{
+    report->mods = 0;
+    for (int8_t i = 0; i < REPORT_KEYS; i++) {
+        report->keys[i] = 0;
+    }
+}
+
+report_keyboard_t *keyboard_report(void)
+{
+    return report;
+}
+
+report_keyboard_t *keyboard_report_prev(void)
+{
+    return report_prev;
+}
index 87c61139b9cb705c5997c9051446d90644385d9c..bc6b21493709a7ec210e99e2eb640705f4963b96 100644 (file)
@@ -1,27 +1,21 @@
 #ifndef KEYBOARD_H
 #define KEYBOARD_H
 
-#include "stdbool.h"
+#include <stdint.h>
+#include <stdbool.h>
+#include "host.h"
 
 
-#define REPORT_KEYS 6
-typedef struct{
-    uint8_t mods;
-    uint8_t rserved;    // not used
-    uint8_t keys[REPORT_KEYS];
-}report_t;
+void keyboard_send(void);
+bool keyboard_has_key(void);
+void keyboard_add_mod(uint8_t mod);
+void keyboard_add_key(uint8_t key);
+void keyboard_add_code(uint8_t code);
+void keyboard_swap_report(void);
+void keyboard_clear_report(void);
+report_keyboard_t *keyboard_report(void);
+report_keyboard_t *keyboard_report_prev(void);
 
+#endif
 
-//extern report_t *report;
-//extern report_t *report_prev;
-
-report_t *report_get(void);
-bool report_has_key(void);
-void report_send(void);
-void report_add_mod(uint8_t mod);
-void report_add_key(uint8_t key);
-void report_add_code(uint8_t code);
-void report_swap(void);
-void report_clear(void);
 
-#endif
diff --git a/ps2_vusb/keyboard_vusb.c b/ps2_vusb/keyboard_vusb.c
deleted file mode 100644 (file)
index 6ea1957..0000000
+++ /dev/null
@@ -1,156 +0,0 @@
-#include "usbdrv.h"
-#include "usb_keycodes.h"
-#include "keyboard.h"
-#include "print.h"
-
-static report_t report0;
-static report_t report1;
-static report_t *report = &report0;
-static report_t *report_prev = &report1;
-
-void report_send(void)
-{
-    if (usbInterruptIsReady()){
-        usbSetInterrupt((void *)report, sizeof(*report));
-    }
-}
-
-report_t *report_get(void)
-{
-    return report;
-}
-
-uint8_t report_mods(void)
-{
-    return report->mods;
-}
-
-uint8_t *report_keys(void)
-{
-    return report->keys;
-}
-
-bool report_has_key(void)
-{
-    for (int i = 0; i < REPORT_KEYS; i++) {
-        if (report->keys[i])
-            return true;
-    }
-    return false;
-}
-
-void report_add_mod(uint8_t mod)
-{
-    report->mods |= mod;
-}
-
-void report_add_key(uint8_t code)
-{
-    int8_t i = 0;
-    int8_t empty = -1;
-    for (; i < REPORT_KEYS; i++) {
-        if (report_prev->keys[i] == code) {
-            report->keys[i] = code;
-            break;
-        }
-        if (empty == -1 && report_prev->keys[i] == KB_NO && report->keys[i] == KB_NO) {
-            empty = i;
-        }
-    }
-    if (i == REPORT_KEYS && empty != -1) {
-        report->keys[empty] = code;
-    }
-}
-
-void report_add_code(uint8_t code)
-{
-    if (IS_MOD(code)) {
-        report_add_mod(code);
-    } else {
-        report_add_key(code);
-    }
-}
-
-void report_swap(void)
-{
-    report_t *tmp = report_prev;
-    report_prev = report;
-    report = tmp;
-}
-
-void report_clear(void)
-{
-    report->mods = 0;
-    for (int8_t i = 0; i < REPORT_KEYS; i++) {
-        report->keys[i] = 0;
-    }
-}
-
-
-static uchar    idleRate;   /* repeat rate for keyboards, never used for mice */
-usbMsgLen_t usbFunctionSetup(uchar data[8])
-{
-usbRequest_t    *rq = (void *)data;
-
-    print("Setup: ");
-    if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){    /* class request type */
-        print("CLASS: ");
-        phex(rq->bRequest);
-        if(rq->bRequest == USBRQ_HID_GET_REPORT){
-            print("GET_REPORT");
-            /* we only have one report type, so don't look at wValue */
-            usbMsgPtr = (void *)report;
-            return sizeof(*report);
-        }else if(rq->bRequest == USBRQ_HID_GET_IDLE){
-            print("GET_IDLE: ");
-            phex(idleRate);
-            usbMsgPtr = &idleRate;
-            return 1;
-        }else if(rq->bRequest == USBRQ_HID_SET_IDLE){
-            idleRate = rq->wValue.bytes[1];
-            print("SET_IDLE: ");
-            phex(idleRate);
-        }
-        print("\n");
-    }else{
-        print("VENDOR\n");
-        /* no vendor specific requests implemented */
-    }
-    return 0;   /* default for not implemented requests: return no data back to host */
-}
-
-
-PROGMEM char usbHidReportDescriptor[USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH] = {
-    0x05, 0x01,          // Usage Page (Generic Desktop),
-    0x09, 0x06,          // Usage (Keyboard),
-    0xA1, 0x01,          // Collection (Application),
-    0x75, 0x01,          //   Report Size (1),
-    0x95, 0x08,          //   Report Count (8),
-    0x05, 0x07,          //   Usage Page (Key Codes),
-    0x19, 0xE0,          //   Usage Minimum (224),
-    0x29, 0xE7,          //   Usage Maximum (231),
-    0x15, 0x00,          //   Logical Minimum (0),
-    0x25, 0x01,          //   Logical Maximum (1),
-    0x81, 0x02,          //   Input (Data, Variable, Absolute), ;Modifier byte
-    0x95, 0x01,          //   Report Count (1),
-    0x75, 0x08,          //   Report Size (8),
-    0x81, 0x03,          //   Input (Constant),                 ;Reserved byte
-    0x95, 0x05,          //   Report Count (5),
-    0x75, 0x01,          //   Report Size (1),
-    0x05, 0x08,          //   Usage Page (LEDs),
-    0x19, 0x01,          //   Usage Minimum (1),
-    0x29, 0x05,          //   Usage Maximum (5),
-    0x91, 0x02,          //   Output (Data, Variable, Absolute), ;LED report
-    0x95, 0x01,          //   Report Count (1),
-    0x75, 0x03,          //   Report Size (3),
-    0x91, 0x03,          //   Output (Constant),                 ;LED report padding
-    0x95, 0x06,          //   Report Count (6),
-    0x75, 0x08,          //   Report Size (8),
-    0x15, 0x00,          //   Logical Minimum (0),
-    0x25, 0xFF,          //   Logical Maximum(255),
-    0x05, 0x07,          //   Usage Page (Key Codes),
-    0x19, 0x00,          //   Usage Minimum (0),
-    0x29, 0xFF,          //   Usage Maximum (255),
-    0x81, 0x00,          //   Input (Data, Array),
-    0xc0                 // End Collection
-};
index e4132badec491e61f7636dc3cf03733e3aa2ba62..b9ce8ca46a9e1b867d00c8663b73ac8944cdadc2 100644 (file)
@@ -98,23 +98,23 @@ void layer_switching(uint8_t fn_bits)
                     debug(" -> "); debug_hex(current_layer); debug("\n");
                 }
             } else {
-                if (report_has_key()) { // other keys is pressed
+                if (keyboard_has_key()) { // other keys is pressed
                     uint8_t _fn_to_send = BIT_SUBT(fn_bits, sent_fn);
                     if (_fn_to_send) {
                         debug("Fn case: 4(send Fn before other key pressed)\n");
                         // send only Fn key first
-                        report_swap();
-                        report_clear();
-                        report_add_code(keymap_fn_keycode(_fn_to_send));   // TODO: do all Fn keys
-                        report_add_mod(last_mods);
-                        report_send();
-                        report_swap();
+                        keyboard_swap_report();
+                        keyboard_clear_report();
+                        keyboard_add_code(keymap_fn_keycode(_fn_to_send));   // TODO: do all Fn keys
+                        keyboard_add_mod(last_mods);
+                        keyboard_send();
+                        keyboard_swap_report();
                         sent_fn |= _fn_to_send;
                     }
                 }
             }
             // add Fn keys to send
-            //report_add_code(keymap_fn_keycode(fn_bits&sent_fn));  // TODO: do all Fn keys
+            //keyboard_add_code(keymap_fn_keycode(fn_bits&sent_fn));  // TODO: do all Fn keys
         }
     } else { // Fn state is changed(edge)
         uint8_t fn_changed = 0;
@@ -128,7 +128,7 @@ void layer_switching(uint8_t fn_bits)
         // pressed Fn
         if ((fn_changed = BIT_SUBT(fn_bits, last_fn))) {
         debug("fn_changed: "); debug_bin(fn_changed); debug("\n");
-            if (report_has_key()) {
+            if (keyboard_has_key()) {
                 debug("Fn case: 5(pressed Fn with other key)\n");
                 sent_fn |= fn_changed;
             } else if (fn_changed & sent_fn) { // pressed same Fn in a row
@@ -149,12 +149,12 @@ void layer_switching(uint8_t fn_bits)
                 if (BIT_SUBT(fn_changed, sent_fn)) {  // layer not used && Fn not sent
                     debug("Fn case: 2(send Fn one shot: released Fn during LAYER_SEND_FN_TERM)\n");
                     // send only Fn key first
-                    report_swap();
-                    report_clear();
-                    report_add_code(keymap_fn_keycode(fn_changed));   // TODO: do all Fn keys
-                    report_add_mod(last_mods);
-                    report_send();
-                    report_swap();
+                    keyboard_swap_report();
+                    keyboard_clear_report();
+                    keyboard_add_code(keymap_fn_keycode(fn_changed));   // TODO: do all Fn keys
+                    keyboard_add_mod(last_mods);
+                    keyboard_send();
+                    keyboard_swap_report();
                     sent_fn |= fn_changed;
                 }
             }
@@ -165,13 +165,13 @@ void layer_switching(uint8_t fn_bits)
         }
 
         last_fn = fn_bits;
-        last_mods = report_get()->mods;
+        last_mods = keyboard_report()->mods;
         last_timer = timer_read();
     }
     // send Fn keys
     for (uint8_t i = 0; i < 8; i++) {
         if ((sent_fn & fn_bits) & (1<<i)) {
-            report_add_code(keymap_fn_keycode(1<<i));
+            keyboard_add_code(keymap_fn_keycode(1<<i));
         }
     }
 }
index 359e28254e4b04c78920d7a76ecc1f4f05f316ad..e692924e794a1f09019668de41690e228ff0e430 100644 (file)
@@ -7,68 +7,50 @@
  * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
  * This Revision: $Id: main.c 790 2010-05-30 21:00:26Z cs $
  */
-
-/*
-This example should run on most AVRs with only little changes. No special
-hardware resources except INT0 are used. You may have to change usbconfig.h for
-different I/O pins for USB. Please note that USB D+ must be the INT0 pin, or
-at least be connected to INT0 as well.
-
-We use VID/PID 0x046D/0xC00E which is taken from a Logitech mouse. Don't
-publish any hardware using these IDs! This is for demonstration only!
-*/
-
 #include <stdint.h>
 #include <avr/io.h>
 #include <avr/wdt.h>
 #include <avr/interrupt.h>  /* for sei() */
-#include <util/delay.h>     /* for _delay_ms() */
-
 #include <avr/pgmspace.h>   /* required by usbdrv.h */
+#include <util/delay.h>     /* for _delay_ms() */
 #include "usbdrv.h"
 #include "usart_print.h"        /* This is also an example for using debug macros */
-#include "ps2.h"
 #include "usb_keycodes.h"
 #include "matrix_skel.h"
 #include "keymap_skel.h"
+#include "mousekey.h"
+#include "keyboard.h"
 #include "layer.h"
 #include "print.h"
 #include "debug.h"
 #include "sendchar.h"
-#include "keyboard.h"
+#include "host.h"
+#include "host_vusb.h"
 #include "timer.h"
 
-/* ------------------------------------------------------------------------- */
-/* ----------------------------- USB interface ----------------------------- */
-/* ------------------------------------------------------------------------- */
-
-
-
-
-
 
 int main(void)
 {
-uchar   i;
-
-print_enable = true;
-debug_enable = true;
-timer_init();
-matrix_init();
-
     wdt_enable(WDTO_1S);
     /* Even if you don't use the watchdog, turn it off here. On newer devices,
      * the status of the watchdog (on/off, period) is PRESERVED OVER RESET!
      */
+
     /* RESET status: all port bits are inputs without pull-up.
      * That's the way we need D+ and D-. Therefore we don't need any
      * additional hardware initialization.
      */
     odDebugInit();
-    DBG1(0x00, 0, 0);       /* debug output: main starts */
     usbInit();
-    usbDeviceDisconnect();  /* enforce re-enumeration, do this while interrupts are disabled! */
-    i = 0;
+
+    print_enable = true;
+    //debug_enable = true;
+    timer_init();
+    matrix_init();
+
+    /* enforce re-enumeration, do this while interrupts are disabled! */
+    usbDeviceDisconnect();
+    uint8_t i = 0;
     while(--i){             /* fake USB disconnect for > 250 ms */
         wdt_reset();
         _delay_ms(1);
@@ -78,49 +60,44 @@ matrix_init();
 
     uint8_t fn_bits = 0;
     while (1) {                /* main event loop */
-        DBG1(0x02, 0, 0);   /* debug output: main loop iterates */
         wdt_reset();
         usbPoll();
+        host_vusb_keyboard_send();
 
-/*
-static uint8_t code = 0;
-code = ps2_host_recv();
-if (code) {
-    odDebug(0x05, &code, 1);
-}
-*/
         matrix_scan();
-        if (matrix_is_modified()) {
-            //matrix_print();   // too heavy on USART
-            fn_bits = 0;
-            report_swap();
-            report_clear();
-            for (int row = 0; row < matrix_rows(); row++) {
-                for (int col = 0; col < matrix_cols(); col++) {
-                    if (!matrix_is_on(row, col)) continue;
-
-                    uint8_t code = layer_get_keycode(row, col);
-                    if (code == KB_NO) {
-                        // do nothing
-                    }
-                    else if (IS_MOD(code)) {
-                        report_add_mod(MOD_BIT(code));
-                    }
-                    else if (IS_KEY(code)) {
-                        report_add_key(code);
-                    }
-                    else if (IS_FN(code)) {
-                        fn_bits |= FN_BIT(code);
-                    }
-                    else {
-                        debug("ignore keycode: "); debug_hex(code); debug("\n");
-                    }
+        fn_bits = 0;
+        keyboard_swap_report();
+        keyboard_clear_report();
+        mousekey_clear_report();
+        for (int row = 0; row < matrix_rows(); row++) {
+            for (int col = 0; col < matrix_cols(); col++) {
+                if (!matrix_is_on(row, col)) continue;
+
+                uint8_t code = layer_get_keycode(row, col);
+                if (code == KB_NO) {
+                    // do nothing
+                }
+                else if (IS_MOD(code)) {
+                    keyboard_add_mod(MOD_BIT(code));
+                }
+                else if (IS_KEY(code)) {
+                    keyboard_add_key(code);
+                }
+                else if (IS_FN(code)) {
+                    fn_bits |= FN_BIT(code);
+                }
+                else if (IS_MOUSEKEY(code)) {
+                    mousekey_decode(code);
+                }
+                else {
+                    debug("ignore keycode: "); debug_hex(code); debug("\n");
                 }
             }
         }
         layer_switching(fn_bits);
         if (matrix_is_modified()) {
-            report_send();
+            keyboard_send();
         }
+        mousekey_send();
     }
 }
index c46473392962edc292aecc9296e4a5f3216de683..bd9b92446cf86466d2cfd68b8d77277da111260a 100644 (file)
@@ -190,8 +190,10 @@ uint8_t matrix_scan(void)
     }
 
     uint8_t code;
-    while ((code = ps2_host_recv())) {
-//debug_hex(code); debug(" ");
+    code = ps2_host_recv();
+    if (code == 0x00) return 0;
+    //while ((code = ps2_host_recv())) {
+//phex(code); print(" ");
         switch (state) {
             case INIT:
                 switch (code) {
@@ -348,7 +350,8 @@ uint8_t matrix_scan(void)
             default:
                 state = INIT;
         }
-    }
+    //}
+//print("|");
 
     // handle LED indicators
 /*
@@ -463,6 +466,7 @@ static void matrix_make(uint8_t code)
     if (!matrix_is_on(ROW(code), COL(code))) {
         matrix[ROW(code)] |= 1<<COL(code);
         is_modified = true;
+        //print("matrix_make: "); phex(code); print("\n");
     }
 }
 
@@ -472,6 +476,7 @@ static void matrix_break(uint8_t code)
     if (matrix_is_on(ROW(code), COL(code))) {
         matrix[ROW(code)] &= ~(1<<COL(code));
         is_modified = true;
+        //print("matrix_break: "); phex(code); print("\n");
     }
 }
 
diff --git a/ps2_vusb/mousekey.c b/ps2_vusb/mousekey.c
new file mode 100644 (file)
index 0000000..a311eec
--- /dev/null
@@ -0,0 +1,102 @@
+#include <stdint.h>
+#include <util/delay.h>
+#include "usb_keycodes.h"
+#include "host.h"
+#include "timer.h"
+#include "print.h"
+#include "mousekey.h"
+
+
+static report_mouse_t report;
+static report_mouse_t report_prev;
+
+static uint8_t mousekey_repeat =  0;
+
+
+/*
+ * TODO: fix acceleration algorithm
+ * see wikipedia http://en.wikipedia.org/wiki/Mouse_keys
+ */
+#ifndef MOUSEKEY_DELAY_TIME
+#   define MOUSEKEY_DELAY_TIME 255
+#endif
+
+
+static inline uint8_t move_unit(void)
+{
+    uint8_t unit = (10 + (mousekey_repeat));
+    return unit > 127 ? 127 : unit;
+}
+
+void mousekey_decode(uint8_t code)
+{
+    if      (code == KB_MS_UP)      report.y -= move_unit();
+    else if (code == KB_MS_DOWN)    report.y += move_unit();
+    else if (code == KB_MS_LEFT)    report.x -= move_unit();
+    else if (code == KB_MS_RIGHT)   report.x += move_unit();
+    else if (code == KB_MS_BTN1)    report.buttons |= MOUSE_BTN1;
+    else if (code == KB_MS_BTN2)    report.buttons |= MOUSE_BTN2;
+    else if (code == KB_MS_BTN3)    report.buttons |= MOUSE_BTN3;
+/*
+    else if (code == KB_MS_BTN4)    report.buttons |= MOUSE_BTN4;
+    else if (code == KB_MS_BTN5)    report.buttons |= MOUSE_BTN5;
+    else if (code == KB_MS_WH_UP)   report.v += 1;
+    else if (code == KB_MS_WH_DOWN) report.v -= 1;
+    else if (code == KB_MS_WH_LEFT) report.h -= 1;
+    else if (code == KB_MS_WH_RIGHT)report.h += 1;
+*/
+}
+
+bool mousekey_changed(void)
+{
+    return (report.buttons != report_prev.buttons ||
+            report.x != report_prev.x ||
+            report.y != report_prev.y ||
+            report.x || report.y);
+    //return (report.buttons != report_prev.buttons || report.x || report.y);
+}
+
+void mousekey_send(void)
+{
+    static uint16_t last_timer = 0;
+
+    if (!mousekey_changed()) {
+        mousekey_repeat = 0;
+        return;
+    }
+
+    // send immediately when buttun state is changed
+    if (report.buttons == report_prev.buttons) {
+        // TODO: delay parameter setting
+        if ((timer_elapsed(last_timer) < (mousekey_repeat == 1 ? 20 : 5))) {
+            return;
+        }
+    }
+
+    if (report.x && report.y) {
+        report.x *= 0.7;
+        report.y *= 0.7;
+    }
+
+    /*
+    print("mousekey_repeat: "); phex(mousekey_repeat); print("\n");
+    print("timer: "); phex16(timer_read()); print("\n");
+    print("last_timer: "); phex16(last_timer); print("\n");
+    print("mousekey: "); phex(report.buttons); print(" "); phex(report.x); print(" "); phex(report.y); print("\n");
+    */
+
+    host_mouse_send(&report);
+    report_prev.buttons = report.buttons;
+    report_prev.x = report.x;
+    report_prev.y = report.y;
+    if (mousekey_repeat != 0xFF) mousekey_repeat++;
+    last_timer = timer_read();
+    mousekey_clear_report();
+}
+
+void mousekey_clear_report(void)
+{
+    report.buttons = 0;
+    report.x = 0;
+    report.y = 0;
+}
diff --git a/ps2_vusb/mousekey.h b/ps2_vusb/mousekey.h
new file mode 100644 (file)
index 0000000..ea9b4f2
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef MOUSEKEY_H
+#define  MOUSEKEY_H
+
+#include <stdbool.h>
+#include "host.h"
+
+void mousekey_decode(uint8_t code);
+bool mousekey_changed(void);
+void mousekey_send(void);
+void mousekey_clear_report(void);
+
+#endif
index 12bf1d5393152a51fa5b547c419e3beb87c86706..84fc6fd3fb3c93a595cc35ce85b631b5fbbfdd9c 100644 (file)
@@ -77,7 +77,7 @@ section at the end of this file).
  * default control endpoint 0 and an interrupt-in endpoint (any other endpoint
  * number).
  */
-#define USB_CFG_HAVE_INTRIN_ENDPOINT3   0
+#define USB_CFG_HAVE_INTRIN_ENDPOINT3   1
 /* Define this to 1 if you want to compile a version with three endpoints: The
  * default control endpoint 0, an interrupt-in endpoint 3 (or the number
  * configured below) and a catch-all default interrupt-in endpoint as above.
@@ -277,7 +277,7 @@ section at the end of this file).
  * HID class is 3, no subclass and protocol required (but may be useful!)
  * CDC class is 2, use subclass 2 and protocol 1 for ACM
  */
-#define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH    63
+#define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH    0
 /* Define this to the length of the HID report descriptor, if you implement
  * an HID device. Otherwise don't define it or define it to 0.
  * If you use this define, you must add a PROGMEM character array named
@@ -343,14 +343,17 @@ section at the end of this file).
  */
 
 #define USB_CFG_DESCR_PROPS_DEVICE                  0
-#define USB_CFG_DESCR_PROPS_CONFIGURATION           0
+#define USB_CFG_DESCR_PROPS_CONFIGURATION           USB_PROP_IS_DYNAMIC
+//#define USB_CFG_DESCR_PROPS_CONFIGURATION           0
 #define USB_CFG_DESCR_PROPS_STRINGS                 0
 #define USB_CFG_DESCR_PROPS_STRING_0                0
 #define USB_CFG_DESCR_PROPS_STRING_VENDOR           0
 #define USB_CFG_DESCR_PROPS_STRING_PRODUCT          0
 #define USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER    0
+//#define USB_CFG_DESCR_PROPS_HID                     USB_PROP_IS_DYNAMIC
 #define USB_CFG_DESCR_PROPS_HID                     0
-#define USB_CFG_DESCR_PROPS_HID_REPORT              0
+#define USB_CFG_DESCR_PROPS_HID_REPORT              USB_PROP_IS_DYNAMIC
+//#define USB_CFG_DESCR_PROPS_HID_REPORT              0
 #define USB_CFG_DESCR_PROPS_UNKNOWN                 0
 
 /* ----------------------- Optional MCU Description ------------------------ */