From 02d955e9fecda610e9cb7f5317262b907614bf31 Mon Sep 17 00:00:00 2001 From: tmk Date: Wed, 17 Nov 2010 16:06:20 +0900 Subject: [PATCH] add audio controls from consumer page(HID) --- Makefile.common | 1 + hhkb/keymap.c | 2 +- key_process.c | 13 +++++++++ usb.c | 71 ++++++++++++++++++++++++++++++++++++++++++++----- usb_extra.c | 33 +++++++++++++++++++++++ usb_extra.h | 20 ++++++++++++++ usb_keycodes.h | 4 +-- 7 files changed, 134 insertions(+), 10 deletions(-) create mode 100644 usb_extra.c create mode 100644 usb_extra.h diff --git a/Makefile.common b/Makefile.common index bec799c089..467f6e777b 100644 --- a/Makefile.common +++ b/Makefile.common @@ -55,6 +55,7 @@ SRC = tmk.c \ usb_keyboard.c \ usb_mouse.c \ usb_debug.c \ + usb_extra.c \ usb.c \ jump_bootloader.c \ print.c \ diff --git a/hhkb/keymap.c b/hhkb/keymap.c index 18e444e2c6..ea8e39a934 100644 --- a/hhkb/keymap.c +++ b/hhkb/keymap.c @@ -84,7 +84,7 @@ static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { */ 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_INS, 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_BSPC, \ - KB_LCTL,KB_VUP, KB_VDWN,KB_MUTE,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_LGUI,KB_LALT,KB_SPC, KB_RALT,FN_7), diff --git a/key_process.c b/key_process.c index f6e16b8edd..243f4aad8a 100644 --- a/key_process.c +++ b/key_process.c @@ -8,6 +8,7 @@ #include "jump_bootloader.h" #include "usb_keyboard.h" #include "usb_mouse.h" +#include "usb_extra.h" #include "usb_keycodes.h" #include "layer.h" #include "matrix_skel.h" @@ -88,6 +89,18 @@ void proc_matrix(void) { if (code == MS_WH_RIGHT) mouse_hwheel += 1; } else if (IS_FN(code)) { fn_bits |= FN_BIT(code); + } else if (code == KB_MUTE) { + usb_extra_send(AUDIO_MUTE); + usb_extra_send(0); + _delay_ms(500); + } else if (code == KB_VOLU) { + usb_extra_send(AUDIO_VOL_UP); + usb_extra_send(0); + _delay_ms(100); + } else if (code == KB_VOLD) { + usb_extra_send(AUDIO_VOL_DOWN); + usb_extra_send(0); + _delay_ms(100); } else { // normal keys if (key_index < 6) diff --git a/usb.c b/usb.c index 3011ecb2a9..7add57daa3 100644 --- a/usb.c +++ b/usb.c @@ -28,6 +28,7 @@ #include "usb_keyboard.h" #include "usb_mouse.h" #include "usb_debug.h" +#include "usb_extra.h" #include "print.h" #include "util.h" @@ -87,7 +88,7 @@ static const uint8_t PROGMEM endpoint_config_table[] = { 1, EP_TYPE_INTERRUPT_IN, EP_SIZE(KEYBOARD_SIZE) | KEYBOARD_BUFFER, // 1 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 - 0, // 4 + 1, EP_TYPE_INTERRUPT_IN, EP_SIZE(EXTRA_SIZE) | EXTRA_BUFFER, // 4 0, // 5 0, // 6 }; @@ -249,17 +250,43 @@ static uint8_t PROGMEM debug_hid_report_desc[] = { 0xC0 // end collection }; -#define CONFIG1_DESC_SIZE (9+(9+9+7)+(9+9+7)+(9+9+7)) -#define KEYBOARD_HID_DESC_OFFSET (9+9) -#define MOUSE_HID_DESC_OFFSET (9+(9+9+7)+9) -#define DEBUG_HID_DESC_OFFSET (9+(9+9+7)+(9+9+7)+9) +// audio controls(consumer page) +// http://www.microsoft.com/whdc/archive/w2kbd.mspx +static uint8_t PROGMEM extra_hid_report_desc[] = { + 0x05, 0x0c, // USAGE_PAGE (Consumer Devices) + 0x09, 0x01, // USAGE (Consumer Control) + 0xa1, 0x01, // COLLECTION (Application) + 0x85, 0x01, // REPORT_ID (1) + 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) + 0x75, 0x01, // REPORT_SIZE (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 +}; + +#define CONFIG1_DESC_SIZE (9+(9+9+7)*4) +#define KEYBOARD_HID_DESC_OFFSET (9+(9+9+7)*0+9) +#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) static uint8_t PROGMEM config1_descriptor[CONFIG1_DESC_SIZE] = { // configuration descriptor, USB spec 9.6.3, page 264-266, Table 9-10 9, // bLength; 2, // bDescriptorType; LSB(CONFIG1_DESC_SIZE), // wTotalLength MSB(CONFIG1_DESC_SIZE), - 3, // bNumInterfaces + 4, // bNumInterfaces 1, // bConfigurationValue 0, // iConfiguration 0xC0, // bmAttributes @@ -344,7 +371,34 @@ static uint8_t PROGMEM config1_descriptor[CONFIG1_DESC_SIZE] = { DEBUG_TX_ENDPOINT | 0x80, // bEndpointAddress 0x03, // bmAttributes (0x03=intr) DEBUG_TX_SIZE, 0, // wMaxPacketSize - 1 // bInterval + 1, // bInterval + + // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 + 9, // bLength + 4, // bDescriptorType + EXTRA_INTERFACE, // bInterfaceNumber + 0, // bAlternateSetting + 1, // bNumEndpoints + 0x03, // bInterfaceClass (0x03 = HID) + 0x00, // bInterfaceSubClass + 0x00, // bInterfaceProtocol + 0, // iInterface + // HID descriptor, HID 1.11 spec, section 6.2.1 + 9, // bLength + 0x21, // bDescriptorType + 0x11, 0x01, // bcdHID + 0, // bCountryCode + 1, // bNumDescriptors + 0x22, // bDescriptorType + sizeof(extra_hid_report_desc), // wDescriptorLength + 0, + // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 + 7, // bLength + 5, // bDescriptorType + EXTRA_ENDPOINT | 0x80, // bEndpointAddress + 0x03, // bmAttributes (0x03=intr) + EXTRA_SIZE, 0, // wMaxPacketSize + 10, // bInterval }; // If you're desperate for a little extra code memory, these strings @@ -392,6 +446,9 @@ static struct descriptor_list_struct { // HID REPORT {0x2200, DEBUG_INTERFACE, debug_hid_report_desc, sizeof(debug_hid_report_desc)}, {0x2100, DEBUG_INTERFACE, config1_descriptor+DEBUG_HID_DESC_OFFSET, 9}, + // HID REPORT + {0x2200, EXTRA_INTERFACE, extra_hid_report_desc, sizeof(extra_hid_report_desc)}, + {0x2100, EXTRA_INTERFACE, config1_descriptor+EXTRA_HID_DESC_OFFSET, 9}, // STRING descriptor {0x0300, 0x0000, (const uint8_t *)&string0, 4}, {0x0301, 0x0409, (const uint8_t *)&string1, sizeof(STR_MANUFACTURER)}, diff --git a/usb_extra.c b/usb_extra.c new file mode 100644 index 0000000000..94c317d981 --- /dev/null +++ b/usb_extra.c @@ -0,0 +1,33 @@ +#include +#include "usb_extra.h" + +int8_t usb_extra_send(uint8_t bits) +{ + uint8_t intr_state, timeout; + + if (!usb_configured()) return -1; + intr_state = SREG; + cli(); + UENUM = EXTRA_ENDPOINT; + timeout = UDFNUML + 50; + while (1) { + // are we ready to transmit? + if (UEINTX & (1< +#include "usb.h" + + +#define EXTRA_INTERFACE 3 +#define EXTRA_ENDPOINT 4 +#define EXTRA_SIZE 2 +#define EXTRA_BUFFER EP_DOUBLE_BUFFER + +#define AUDIO_VOL_UP (1<<0) +#define AUDIO_VOL_DOWN (1<<1) +#define AUDIO_MUTE (1<<2) + + +int8_t usb_extra_send(uint8_t bits); + +#endif diff --git a/usb_keycodes.h b/usb_keycodes.h index b49ecd5809..87aa31ca8f 100644 --- a/usb_keycodes.h +++ b/usb_keycodes.h @@ -77,8 +77,8 @@ #define KB_SCLN KB_SCOLON #define KB_QUOT KB_QUOTE #define KB_PWR KB_POWER -#define KB_VUP KB_VOLUP -#define KB_VDWN KB_VOLDOWN +#define KB_VOLU KB_VOLUP +#define KB_VOLD KB_VOLDOWN #define KP_SLSH KP_SLASH #define KP_ASTR KP_ASTERISK #define KP_MINS KP_MINUS