From 74f7e19863ced21bf5d27c1fb1207f79f2195e24 Mon Sep 17 00:00:00 2001 From: tmk Date: Sat, 21 May 2011 10:28:57 +0900 Subject: [PATCH] added USB_EXTRA feature to HHKB/V-USB --- command.c | 6 +- hhkb/Makefile.vusb | 2 +- host.h | 22 ++++++ keyboard.c | 20 +++--- pjrc/host.c | 19 +++++ pjrc/usb.c | 4 ++ vusb/host.c | 171 +++++++++++++++++++++++++++------------------ 7 files changed, 166 insertions(+), 78 deletions(-) diff --git a/command.c b/command.c index cd51b79cb..ca149dbd0 100755 --- a/command.c +++ b/command.c @@ -122,11 +122,15 @@ uint8_t command_proc(void) #endif #ifdef USB_EXTRA_ENABLE case KB_ESC: +#ifdef HOST_PJRC if (suspend && remote_wakeup) { usb_remote_wakeup(); } else { - usb_extra_system_send(SYSTEM_POWER_DOWN); + host_system_send(SYSTEM_POWER_DOWN); } +#else + host_system_send(SYSTEM_POWER_DOWN); +#endif break; #endif case KB_BSPC: diff --git a/hhkb/Makefile.vusb b/hhkb/Makefile.vusb index ea89a6f6a..7826ffd02 100644 --- a/hhkb/Makefile.vusb +++ b/hhkb/Makefile.vusb @@ -42,7 +42,7 @@ F_CPU = 20000000 # comment out to disable the options. # MOUSEKEY_ENABLE = yes # Mouse keys -#USB_EXTRA_ENABLE = yes # Enhanced feature for Windows(Audio control and System control) +USB_EXTRA_ENABLE = yes # Enhanced feature for Windows(Audio control and System control) #USB_NKRO_ENABLE = yes # USB Nkey Rollover diff --git a/host.h b/host.h index 045ccd8e6..7ba9dd43c 100644 --- a/host.h +++ b/host.h @@ -4,6 +4,11 @@ #include +/* report id */ +#define REPORT_ID_MOUSE 1 +#define REPORT_ID_SYSTEM 2 +#define REPORT_ID_AUDIO 3 + /* keyboard Modifiers in boot protocol report */ #define BIT_LCTRL (1<<0) #define BIT_LSHIFT (1<<1) @@ -25,6 +30,16 @@ #define MOUSE_BTN4 (1<<3) #define MOUSE_BTN5 (1<<4) +// Consumer Page(0x0C) Consumer Control(0x01) +#define AUDIO_VOL_UP (1<<0) +#define AUDIO_VOL_DOWN (1<<1) +#define AUDIO_MUTE (1<<2) + +// Generic Desktop Page(0x01) System Control(0x80) +#define SYSTEM_POWER_DOWN (1<<0) +#define SYSTEM_SLEEP (1<<1) +#define SYSTEM_WAKE_UP (1<<2) + #if defined(HOST_PJRC) # include "usb.h" @@ -44,6 +59,7 @@ typedef struct { } report_keyboard_t; typedef struct { + uint8_t report_id; uint8_t buttons; int8_t x; int8_t y; @@ -74,6 +90,12 @@ uint8_t host_get_first_key(void); void host_send_keyboard_report(void); +#if defined(MOUSEKEY_ENABLE) || defined(PS2_MOUSE_ENABLE) void host_mouse_send(report_mouse_t *report); +#endif +#ifdef USB_EXTRA_ENABLE +void host_system_send(uint8_t data); +void host_audio_send(uint8_t data); +#endif #endif diff --git a/keyboard.c b/keyboard.c index 03db3257a..fd6e23042 100644 --- a/keyboard.c +++ b/keyboard.c @@ -11,9 +11,7 @@ #ifdef MOUSEKEY_ENABLE #include "mousekey.h" #endif -/* TODO: shoud make new API */ #ifdef USB_EXTRA_ENABLE -#include "usb_extra.h" #include #endif @@ -68,23 +66,27 @@ void keyboard_proc(void) #ifdef USB_EXTRA_ENABLE // audio control & system control else if (code == KB_MUTE) { - usb_extra_audio_send(AUDIO_MUTE); - usb_extra_audio_send(0); + host_audio_send(AUDIO_MUTE); _delay_ms(500); + host_audio_send(0); } else if (code == KB_VOLU) { - usb_extra_audio_send(AUDIO_VOL_UP); - usb_extra_audio_send(0); + host_audio_send(AUDIO_VOL_UP); _delay_ms(200); + host_audio_send(0); } else if (code == KB_VOLD) { - usb_extra_audio_send(AUDIO_VOL_DOWN); - usb_extra_audio_send(0); + host_audio_send(AUDIO_VOL_DOWN); _delay_ms(200); + host_audio_send(0); } else if (code == KB_PWR) { +#ifdef HOST_PJRC if (suspend && remote_wakeup) { usb_remote_wakeup(); } else { - usb_extra_system_send(SYSTEM_POWER_DOWN); + host_system_send(SYSTEM_POWER_DOWN); } +#else + host_system_send(SYSTEM_POWER_DOWN); +#endif _delay_ms(1000); } #endif diff --git a/pjrc/host.c b/pjrc/host.c index b69c6cb20..2a81e4c5e 100644 --- a/pjrc/host.c +++ b/pjrc/host.c @@ -2,7 +2,12 @@ #include #include "usb_keycodes.h" #include "usb_keyboard.h" +#if defined(MOUSEKEY_ENABLE) || defined(PS2_MOUSE_ENABLE) #include "usb_mouse.h" +#endif +#ifdef USB_EXTRA_ENABLE +#include "usb_extra.h" +#endif #include "debug.h" #include "host.h" #include "util.h" @@ -104,10 +109,24 @@ void host_send_keyboard_report(void) usb_keyboard_send_report(keyboard_report); } +#if defined(MOUSEKEY_ENABLE) || defined(PS2_MOUSE_ENABLE) void host_mouse_send(report_mouse_t *report) { usb_mouse_send(report->x, report->y, report->v, report->h, report->buttons); } +#endif + +#ifdef USB_EXTRA_ENABLE +void host_system_send(uint8_t data) +{ + usb_extra_system_send(data); +} + +void host_audio_send(uint8_t data) +{ + usb_extra_audio_send(data); +} +#endif static inline void add_key_byte(uint8_t code) diff --git a/pjrc/usb.c b/pjrc/usb.c index b2c18d98d..711c0e68a 100755 --- a/pjrc/usb.c +++ b/pjrc/usb.c @@ -682,7 +682,11 @@ ISR(USB_GEN_vect) } } /* TODO: should keep IDLE rate on each keyboard interface */ +#ifdef USB_NKRO_ENABLE if (!keyboard_nkro && usb_keyboard_idle_config && (++div4 & 3) == 0) { +#else + if (usb_keyboard_idle_config && (++div4 & 3) == 0) { +#endif UENUM = KBD_ENDPOINT; if (UEINTX & (1<report_id = REPORT_ID_MOUSE; if (usbInterruptIsReady3()) { usbSetInterrupt3((void *)report, sizeof(*report)); } else { debug("Int3 not ready\n"); } } +#endif + +#ifdef USB_EXTRA_ENABLE +void host_system_send(uint8_t data) +{ + static uint8_t report[] = { REPORT_ID_SYSTEM, 0 }; + report[1] = data; + if (usbInterruptIsReady3()) { + usbSetInterrupt3((void *)&report, sizeof(report)); + } else { + debug("Int3 not ready\n"); + } +} + +void host_audio_send(uint8_t data) +{ + static uint8_t report[] = { REPORT_ID_AUDIO, 0 }; + report[1] = data; + if (usbInterruptIsReady3()) { + usbSetInterrupt3((void *)&report, sizeof(report)); + } else { + debug("Int3 not ready\n"); + } +} +#endif @@ -265,77 +292,87 @@ PROGMEM uchar keyboard_hid_report[] = { * http://www.microsoft.com/whdc/device/input/wheel.mspx */ PROGMEM uchar mouse_hid_report[] = { - /* from HID 1.11 spec example */ + /* mouse */ 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 + 0x85, 0x01, // REPORT_ID (1) + 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) + // ---------------------------- 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) + 0x95, 0x01, // REPORT_COUNT (1) + 0x81, 0x06, // INPUT (Data,Var,Rel) + // ---------------------------- 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) + 0x95, 0x01, // REPORT_COUNT (1) + 0x81, 0x06, // INPUT (Data,Var,Rel) 0xc0, // END_COLLECTION - 0xc0 // END_COLLECTION + 0xc0, // END_COLLECTION + /* system */ + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + 0x09, 0x80, // USAGE (System Control) + 0xa1, 0x01, // COLLECTION (Application) + 0x85, 0x02, // REPORT_ID (2) + 0x19, 0x81, // USAGE_MINIMUM (System Power Down) + 0x29, 0x83, // USAGE_MAXIMUM (System Wake Up) + 0x75, 0x01, // REPORT_SIZE (1) + 0x95, 0x03, // REPORT_COUNT (3) + 0x81, 0x06, // INPUT (Data,Var,Rel) + 0x95, 0x05, // REPORT_COUNT (5) + 0x81, 0x07, // INPUT (Cnst,Var,Rel) + 0xc0, // END_COLLECTION + /* audio */ + 0x05, 0x0c, // USAGE_PAGE (Consumer Devices) + 0x09, 0x01, // USAGE (Consumer Control) + 0xa1, 0x01, // COLLECTION (Application) + 0x85, 0x03, // REPORT_ID (3) + 0x09, 0xe9, // USAGE (Volume Up) + 0x09, 0xea, // USAGE (Volume Down) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x01, // LOGICAL_MAXIMUM (1) + 0x75, 0x01, // REPORT_SIZE (1) + 0x95, 0x02, // REPORT_COUNT (2) + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0x09, 0xe2, // USAGE (Mute) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x01, // LOGICAL_MAXIMUM (1) + 0x95, 0x01, // REPORT_COUNT (1) + 0x81, 0x06, // INPUT (Data,Var,Rel) + 0x95, 0x05, // REPORT_COUNT (5) + 0x81, 0x07, // INPUT (Cnst,Var,Abs) + 0xc0, // END_COLLECTION };