- Media keys tested working on Linux/Windows/Mac (use Consumer control) - Fixed enumeration delays - Fixed virtual serial port configuration issues - Fixed GET_REPORT and SET_REPORT - Added intial descriptors and endpoints for Mouse and Joystick devices - Split out the consumer and system control endpoint - Added more fault debugging messages - Added interface names to endpoints (visible in Windows Device Manager) - Added KLL define for keyboard localecapsense
// NVIC - Hard Fault ISR | // NVIC - Hard Fault ISR | ||||
void hard_fault_default_isr() | void hard_fault_default_isr() | ||||
{ | { | ||||
print("Hard Fault!" NL ); | |||||
print("Hard Fault! SCB_HFSR: "); | |||||
printHex32( SCB_HFSR ); | |||||
print( NL ); | |||||
SOFTWARE_RESET(); | |||||
} | } | ||||
// NVIC - Memory Manager Fault ISR | // NVIC - Memory Manager Fault ISR | ||||
void memmanage_fault_default_isr() | void memmanage_fault_default_isr() | ||||
{ | { | ||||
print("Memory Manager Fault!" NL ); | |||||
print("Memory Manager Fault! SCB_CFSR: "); | |||||
printHex32( SCB_CFSR ); | |||||
print(" SCB_MMAR: "); | |||||
printHex32( SCB_MMAR ); | |||||
print( NL ); | |||||
} | } | ||||
// NVIC - Bus Fault ISR | // NVIC - Bus Fault ISR | ||||
void bus_fault_default_isr() | void bus_fault_default_isr() | ||||
{ | { | ||||
print("Bus Fault!" NL ); | |||||
print("Bus Fault! SCB_CFSR: "); | |||||
printHex32( SCB_CFSR ); | |||||
print(" SCB_BFAR: "); | |||||
printHex32( SCB_BFAR ); | |||||
print( NL ); | |||||
} | } | ||||
// NVIC - Usage Fault ISR | // NVIC - Usage Fault ISR | ||||
void usage_fault_default_isr() | void usage_fault_default_isr() | ||||
{ | { | ||||
print("Usage Fault!" NL ); | |||||
print("Usage Fault! SCB_CFSR: "); | |||||
printHex32( SCB_CFSR ); | |||||
print( NL ); | |||||
} | } | ||||
#define SCB_CFSR *(volatile uint32_t *)0xE000ED28 // Configurable Fault Status Register | #define SCB_CFSR *(volatile uint32_t *)0xE000ED28 // Configurable Fault Status Register | ||||
#define SCB_HFSR *(volatile uint32_t *)0xE000ED2C // HardFault Status | #define SCB_HFSR *(volatile uint32_t *)0xE000ED2C // HardFault Status | ||||
#define SCB_DFSR *(volatile uint32_t *)0xE000ED30 // Debug Fault Status | #define SCB_DFSR *(volatile uint32_t *)0xE000ED30 // Debug Fault Status | ||||
#define SCB_MMFAR *(volatile uint32_t *)0xE000ED34 // MemManage Fault Address | |||||
#define SCB_MMAR *(volatile uint32_t *)0xE000ED34 // MemManage Fault Address | |||||
#define SCB_BFAR *(volatile uint32_t *)0xE000ED38 // BusFault Addreses Register | |||||
#define SCB_AFSR *(volatile uint32_t *)0xE000ED3C // Auxilary Fault Status Register | |||||
#define SYST_CSR *(volatile uint32_t *)0xE000E010 // SysTick Control and Status | #define SYST_CSR *(volatile uint32_t *)0xE000E010 // SysTick Control and Status | ||||
#define SYST_CSR_COUNTFLAG (uint32_t)0x00010000 | #define SYST_CSR_COUNTFLAG (uint32_t)0x00010000 |
/* Teensyduino Core Library | /* Teensyduino Core Library | ||||
* http://www.pjrc.com/teensy/ | * http://www.pjrc.com/teensy/ | ||||
* Copyright (c) 2013 PJRC.COM, LLC. | * Copyright (c) 2013 PJRC.COM, LLC. | ||||
* Modified by Jacob Alexander (2013-2014) | |||||
* Modified by Jacob Alexander (2013-2015) | |||||
* | * | ||||
* Permission is hereby granted, free of charge, to any person obtaining | * Permission is hereby granted, free of charge, to any person obtaining | ||||
* a copy of this software and associated documentation files (the | * a copy of this software and associated documentation files (the | ||||
// Local Includes | // Local Includes | ||||
#include "usb_desc.h" | #include "usb_desc.h" | ||||
// Generated Includes | |||||
#include <kll_defs.h> | |||||
// ----- Macros ----- | // ----- Macros ----- | ||||
0x95, 0x01, // Report Count (1), | 0x95, 0x01, // Report Count (1), | ||||
0x81, 0x03, // Input (Constant), | 0x81, 0x03, // Input (Constant), | ||||
0xc0, // End Collection - Keyboard | 0xc0, // End Collection - Keyboard | ||||
}; | |||||
// System Control and Consumer Control | |||||
static uint8_t sys_ctrl_report_desc[] = { | |||||
// System Control Collection | // System Control Collection | ||||
// | // | ||||
// NOTES: | // NOTES: | ||||
0x85, 0x03, // Report ID (3), | 0x85, 0x03, // Report ID (3), | ||||
0x75, 0x10, // Report Size (16), | 0x75, 0x10, // Report Size (16), | ||||
0x95, 0x01, // Report Count (1), | 0x95, 0x01, // Report Count (1), | ||||
0x16, 0x20, 0x00, // Logical Minimum (32), | |||||
0x16, 0x01, 0x00, // Logical Minimum (1), | |||||
0x26, 0x9C, 0x02, // Logical Maximum (668), | 0x26, 0x9C, 0x02, // Logical Maximum (668), | ||||
0x05, 0x0C, // Usage Page (Consumer), | 0x05, 0x0C, // Usage Page (Consumer), | ||||
0x19, 0x20, // Usage Minimum (32), | |||||
0x19, 0x01, // Usage Minimum (1), | |||||
0x2A, 0x9C, 0x02, // Usage Maximum (668), | 0x2A, 0x9C, 0x02, // Usage Maximum (668), | ||||
0x81, 0x00, // Input (Data, Array), | 0x81, 0x00, // Input (Data, Array), | ||||
0xc0, // End Collection - Consumer Control | 0xc0, // End Collection - Consumer Control | ||||
}; | }; | ||||
/* MOUSE | |||||
// Mouse Protocol 1, HID 1.11 spec, Appendix B, page 59-60, with wheel extension | // Mouse Protocol 1, HID 1.11 spec, Appendix B, page 59-60, with wheel extension | ||||
static uint8_t mouse_report_desc[] = { | static uint8_t mouse_report_desc[] = { | ||||
0x05, 0x01, // Usage Page (Generic Desktop) | 0x05, 0x01, // Usage Page (Generic Desktop) | ||||
0x81, 0x06, // Input (Data, Variable, Relative) | 0x81, 0x06, // Input (Data, Variable, Relative) | ||||
0xC0 // End Collection | 0xC0 // End Collection | ||||
}; | }; | ||||
*/ | |||||
// Joystick Protocol, HID 1.11 spec, Apendix D, page 64-65 | |||||
static uint8_t joystick_report_desc[] = { | |||||
0x05, 0x01, // Usage Page (Generic Desktop) | |||||
0x09, 0x04, // Usage (Joystick) | |||||
0xA1, 0x01, // Collection (Application) | |||||
0x15, 0x00, // Logical Minimum (0) | |||||
0x25, 0x01, // Logical Maximum (1) | |||||
0x75, 0x01, // Report Size (1) | |||||
0x95, 0x20, // Report Count (32) | |||||
0x05, 0x09, // Usage Page (Button) | |||||
0x19, 0x01, // Usage Minimum (Button #1) | |||||
0x29, 0x20, // Usage Maximum (Button #32) | |||||
0x81, 0x02, // Input (variable,absolute) | |||||
0x15, 0x00, // Logical Minimum (0) | |||||
0x25, 0x07, // Logical Maximum (7) | |||||
0x35, 0x00, // Physical Minimum (0) | |||||
0x46, 0x3B, 0x01, // Physical Maximum (315) | |||||
0x75, 0x04, // Report Size (4) | |||||
0x95, 0x01, // Report Count (1) | |||||
0x65, 0x14, // Unit (20) | |||||
0x05, 0x01, // Usage Page (Generic Desktop) | |||||
0x09, 0x39, // Usage (Hat switch) | |||||
0x81, 0x42, // Input (variable,absolute,null_state) | |||||
0x05, 0x01, // Usage Page (Generic Desktop) | |||||
0x09, 0x01, // Usage (Pointer) | |||||
0xA1, 0x00, // Collection () | |||||
0x15, 0x00, // Logical Minimum (0) | |||||
0x26, 0xFF, 0x03, // Logical Maximum (1023) | |||||
0x75, 0x0A, // Report Size (10) | |||||
0x95, 0x04, // Report Count (4) | |||||
0x09, 0x30, // Usage (X) | |||||
0x09, 0x31, // Usage (Y) | |||||
0x09, 0x32, // Usage (Z) | |||||
0x09, 0x35, // Usage (Rz) | |||||
0x81, 0x02, // Input (variable,absolute) | |||||
0xC0, // End Collection | |||||
0x15, 0x00, // Logical Minimum (0) | |||||
0x26, 0xFF, 0x03, // Logical Maximum (1023) | |||||
0x75, 0x0A, // Report Size (10) | |||||
0x95, 0x02, // Report Count (2) | |||||
0x09, 0x36, // Usage (Slider) | |||||
0x09, 0x36, // Usage (Slider) | |||||
0x81, 0x02, // Input (variable,absolute) | |||||
0xC0 // End Collection | |||||
}; | |||||
0x03, // bInterfaceClass (0x03 = HID) | 0x03, // bInterfaceClass (0x03 = HID) | ||||
0x01, // bInterfaceSubClass (0x00 = Non-Boot, 0x01 = Boot) | 0x01, // bInterfaceSubClass (0x00 = Non-Boot, 0x01 = Boot) | ||||
0x01, // bInterfaceProtocol (0x01 = Keyboard) | 0x01, // bInterfaceProtocol (0x01 = Keyboard) | ||||
0, // iInterface | |||||
KEYBOARD_INTERFACE + 4, // iInterface | |||||
// - 9 bytes - | // - 9 bytes - | ||||
// HID interface descriptor, HID 1.11 spec, section 6.2.1 | // HID interface descriptor, HID 1.11 spec, section 6.2.1 | ||||
9, // bLength | 9, // bLength | ||||
0x21, // bDescriptorType | 0x21, // bDescriptorType | ||||
0x11, 0x01, // bcdHID | 0x11, 0x01, // bcdHID | ||||
0, // bCountryCode | |||||
KeyboardLocale_define, // bCountryCode | |||||
1, // bNumDescriptors | 1, // bNumDescriptors | ||||
0x22, // bDescriptorType | 0x22, // bDescriptorType | ||||
LSB(sizeof(keyboard_report_desc)), // wDescriptorLength | LSB(sizeof(keyboard_report_desc)), // wDescriptorLength | ||||
0x03, // bInterfaceClass (0x03 = HID) | 0x03, // bInterfaceClass (0x03 = HID) | ||||
0x00, // bInterfaceSubClass (0x00 = Non-Boot, 0x01 = Boot) | 0x00, // bInterfaceSubClass (0x00 = Non-Boot, 0x01 = Boot) | ||||
0x01, // bInterfaceProtocol (0x01 = Keyboard) | 0x01, // bInterfaceProtocol (0x01 = Keyboard) | ||||
0, // iInterface | |||||
NKRO_KEYBOARD_INTERFACE + 4, // iInterface | |||||
// - 9 bytes - | // - 9 bytes - | ||||
// HID interface descriptor, HID 1.11 spec, section 6.2.1 | // HID interface descriptor, HID 1.11 spec, section 6.2.1 | ||||
9, // bLength | 9, // bLength | ||||
0x21, // bDescriptorType | 0x21, // bDescriptorType | ||||
0x11, 0x01, // bcdHID | 0x11, 0x01, // bcdHID | ||||
0, // bCountryCode | |||||
KeyboardLocale_define, // bCountryCode | |||||
1, // bNumDescriptors | 1, // bNumDescriptors | ||||
0x22, // bDescriptorType | 0x22, // bDescriptorType | ||||
LSB(sizeof(nkro_keyboard_report_desc)), // wDescriptorLength | LSB(sizeof(nkro_keyboard_report_desc)), // wDescriptorLength | ||||
0x02, // bFunctionClass | 0x02, // bFunctionClass | ||||
0x02, // bFunctionSubClass | 0x02, // bFunctionSubClass | ||||
0x01, // bFunctionProtocol | 0x01, // bFunctionProtocol | ||||
0, // iFunction | |||||
CDC_STATUS_INTERFACE + 4, // iFunction | |||||
// --- Serial CDC --- CDC Data Interface | // --- Serial CDC --- CDC Data Interface | ||||
// - 9 bytes - | // - 9 bytes - | ||||
0x02, // bInterfaceClass | 0x02, // bInterfaceClass | ||||
0x02, // bInterfaceSubClass | 0x02, // bInterfaceSubClass | ||||
0x01, // bInterfaceProtocol | 0x01, // bInterfaceProtocol | ||||
0, // iInterface | |||||
CDC_STATUS_INTERFACE + 4, // iInterface | |||||
// - 5 bytes - | // - 5 bytes - | ||||
// CDC Header Functional Descriptor, CDC Spec 5.2.3.1, Table 26 | // CDC Header Functional Descriptor, CDC Spec 5.2.3.1, Table 26 | ||||
5, // bFunctionLength | 5, // bFunctionLength | ||||
0x0A, // bInterfaceClass | 0x0A, // bInterfaceClass | ||||
0x00, // bInterfaceSubClass | 0x00, // bInterfaceSubClass | ||||
0x00, // bInterfaceProtocol | 0x00, // bInterfaceProtocol | ||||
0, // iInterface | |||||
CDC_DATA_INTERFACE + 4, // iInterface | |||||
// - 7 bytes - | // - 7 bytes - | ||||
// endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 | // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 | ||||
7, // bLength | 7, // bLength | ||||
CDC_TX_SIZE, 0, // wMaxPacketSize | CDC_TX_SIZE, 0, // wMaxPacketSize | ||||
0, // bInterval | 0, // bInterval | ||||
/* | |||||
// Mouse Interface | |||||
// --- Mouse Interface --- | |||||
// - 9 bytes - | // - 9 bytes - | ||||
// interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 | // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 | ||||
9, // bLength | 9, // bLength | ||||
1, // bNumEndpoints | 1, // bNumEndpoints | ||||
0x03, // bInterfaceClass (0x03 = HID) | 0x03, // bInterfaceClass (0x03 = HID) | ||||
0x00, // bInterfaceSubClass (0x01 = Boot) | 0x00, // bInterfaceSubClass (0x01 = Boot) | ||||
0x00, // bInterfaceProtocol (0x02 = Mouse) | |||||
0, // iInterface | |||||
0x02, // bInterfaceProtocol (0x02 = Mouse) | |||||
MOUSE_INTERFACE + 4, // iInterface | |||||
// - 9 bytes - | // - 9 bytes - | ||||
// HID interface descriptor, HID 1.11 spec, section 6.2.1 | // HID interface descriptor, HID 1.11 spec, section 6.2.1 | ||||
9, // bLength | 9, // bLength | ||||
0x03, // bmAttributes (0x03=intr) | 0x03, // bmAttributes (0x03=intr) | ||||
MOUSE_SIZE, 0, // wMaxPacketSize | MOUSE_SIZE, 0, // wMaxPacketSize | ||||
MOUSE_INTERVAL, // bInterval | MOUSE_INTERVAL, // bInterval | ||||
#endif // MOUSE_INTERFACE | |||||
*/ | |||||
// --- Joystick Interface --- | |||||
// - 9 bytes - | |||||
// interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 | |||||
9, // bLength | |||||
4, // bDescriptorType | |||||
JOYSTICK_INTERFACE, // bInterfaceNumber | |||||
0, // bAlternateSetting | |||||
1, // bNumEndpoints | |||||
0x03, // bInterfaceClass (0x03 = HID) | |||||
0x00, // bInterfaceSubClass | |||||
0x00, // bInterfaceProtocol | |||||
JOYSTICK_INTERFACE + 4, // iInterface | |||||
// - 9 bytes - | |||||
// HID interface descriptor, HID 1.11 spec, section 6.2.1 | |||||
9, // bLength | |||||
0x21, // bDescriptorType | |||||
0x11, 0x01, // bcdHID | |||||
0, // bCountryCode | |||||
1, // bNumDescriptors | |||||
0x22, // bDescriptorType | |||||
LSB(sizeof(joystick_report_desc)), // wDescriptorLength | |||||
MSB(sizeof(joystick_report_desc)), | |||||
// - 7 bytes - | |||||
// endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 | |||||
7, // bLength | |||||
5, // bDescriptorType | |||||
JOYSTICK_ENDPOINT | 0x80, // bEndpointAddress | |||||
0x03, // bmAttributes (0x03=intr) | |||||
JOYSTICK_SIZE, 0, // wMaxPacketSize | |||||
JOYSTICK_INTERVAL, // bInterval | |||||
// --- System/Consumer Control --- | |||||
// - 9 bytes - | |||||
// interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 | |||||
9, // bLength | |||||
4, // bDescriptorType | |||||
SYS_CTRL_INTERFACE, // bInterfaceNumber | |||||
0, // bAlternateSetting | |||||
1, // bNumEndpoints | |||||
0x03, // bInterfaceClass (0x03 = HID) | |||||
0x01, // bInterfaceSubClass (0x00 = Non-Boot, 0x01 = Boot) | |||||
0x00, // bInterfaceProtocol (0x00 = None) | |||||
SYS_CTRL_INTERFACE + 4, // iInterface | |||||
// - 9 bytes - | |||||
// HID interface descriptor, HID 1.11 spec, section 6.2.1 | |||||
9, // bLength | |||||
0x21, // bDescriptorType | |||||
0x11, 0x01, // bcdHID | |||||
KeyboardLocale_define, // bCountryCode | |||||
1, // bNumDescriptors | |||||
0x22, // bDescriptorType | |||||
LSB(sizeof(sys_ctrl_report_desc)), // wDescriptorLength | |||||
MSB(sizeof(sys_ctrl_report_desc)), | |||||
// - 7 bytes - | |||||
// endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 | |||||
7, // bLength | |||||
5, // bDescriptorType | |||||
SYS_CTRL_ENDPOINT | 0x80, // bEndpointAddress | |||||
0x03, // bmAttributes (0x03=intr) | |||||
SYS_CTRL_SIZE, 0, // wMaxPacketSize | |||||
SYS_CTRL_INTERVAL, // bInterval | |||||
}; | }; | ||||
{0x0409} | {0x0409} | ||||
}; | }; | ||||
struct usb_string_descriptor_struct usb_string_manufacturer_name_default = { | |||||
sizeof(STR_MANUFACTURER), | |||||
3, | |||||
{STR_MANUFACTURER} | |||||
}; | |||||
struct usb_string_descriptor_struct usb_string_product_name_default = { | |||||
sizeof(STR_PRODUCT), | |||||
3, | |||||
{STR_PRODUCT} | |||||
}; | |||||
struct usb_string_descriptor_struct usb_string_serial_number_default = { | |||||
sizeof(STR_SERIAL), | |||||
3, | |||||
{STR_SERIAL} | |||||
}; | |||||
#define usb_string_descriptor(name, str) \ | |||||
struct usb_string_descriptor_struct name = { \ | |||||
sizeof(str), \ | |||||
3, \ | |||||
{str} \ | |||||
} | |||||
usb_string_descriptor( usb_string_manufacturer_name_default, STR_MANUFACTURER ); | |||||
usb_string_descriptor( usb_string_product_name_default, STR_PRODUCT ); | |||||
usb_string_descriptor( usb_string_serial_number_default, STR_SERIAL ); | |||||
usb_string_descriptor( usb_string_keyboard_name, KEYBOARD_NAME ); | |||||
usb_string_descriptor( usb_string_nkro_keyboard_name, NKRO_KEYBOARD_NAME ); | |||||
usb_string_descriptor( usb_string_cdc_status_name, CDC_STATUS_NAME ); | |||||
usb_string_descriptor( usb_string_cdc_data_name, CDC_DATA_NAME ); | |||||
usb_string_descriptor( usb_string_mouse_name, MOUSE_NAME ); | |||||
usb_string_descriptor( usb_string_joystick_name, JOYSTICK_NAME ); | |||||
usb_string_descriptor( usb_string_sys_ctrl_name, SYS_CTRL_NAME ); | |||||
{0x0200, 0x0000, config_descriptor, sizeof(config_descriptor)}, | {0x0200, 0x0000, config_descriptor, sizeof(config_descriptor)}, | ||||
{0x0600, 0x0000, device_qualifier_descriptor, sizeof(device_qualifier_descriptor)}, | {0x0600, 0x0000, device_qualifier_descriptor, sizeof(device_qualifier_descriptor)}, | ||||
{0x0A00, 0x0000, usb_debug_descriptor, sizeof(usb_debug_descriptor)}, | {0x0A00, 0x0000, usb_debug_descriptor, sizeof(usb_debug_descriptor)}, | ||||
{0x2200, KEYBOARD_INTERFACE, keyboard_report_desc, sizeof(keyboard_report_desc)}, | {0x2200, KEYBOARD_INTERFACE, keyboard_report_desc, sizeof(keyboard_report_desc)}, | ||||
{0x2100, KEYBOARD_INTERFACE, config_descriptor + KEYBOARD_DESC_OFFSET, 9}, | {0x2100, KEYBOARD_INTERFACE, config_descriptor + KEYBOARD_DESC_OFFSET, 9}, | ||||
{0x2200, NKRO_KEYBOARD_INTERFACE, nkro_keyboard_report_desc, sizeof(nkro_keyboard_report_desc)}, | {0x2200, NKRO_KEYBOARD_INTERFACE, nkro_keyboard_report_desc, sizeof(nkro_keyboard_report_desc)}, | ||||
{0x2100, NKRO_KEYBOARD_INTERFACE, config_descriptor + NKRO_KEYBOARD_DESC_OFFSET, 9}, | {0x2100, NKRO_KEYBOARD_INTERFACE, config_descriptor + NKRO_KEYBOARD_DESC_OFFSET, 9}, | ||||
/* MOUSE | |||||
{0x2200, MOUSE_INTERFACE, mouse_report_desc, sizeof(mouse_report_desc)}, | {0x2200, MOUSE_INTERFACE, mouse_report_desc, sizeof(mouse_report_desc)}, | ||||
{0x2100, MOUSE_INTERFACE, config_descriptor+MOUSE_DESC_OFFSET, 9}, | |||||
*/ | |||||
{0x2100, MOUSE_INTERFACE, config_descriptor + MOUSE_DESC_OFFSET, 9}, | |||||
{0x2200, JOYSTICK_INTERFACE, joystick_report_desc, sizeof(joystick_report_desc)}, | |||||
{0x2100, JOYSTICK_INTERFACE, config_descriptor + JOYSTICK_DESC_OFFSET, 9}, | |||||
{0x2200, SYS_CTRL_INTERFACE, sys_ctrl_report_desc, sizeof(sys_ctrl_report_desc)}, | |||||
{0x2100, SYS_CTRL_INTERFACE, config_descriptor + SYS_CTRL_DESC_OFFSET, 9}, | |||||
#define iInterfaceString(num, var) \ | |||||
{0x0300 + 4 + num, 0x409, (const uint8_t *)&var, 0 } | |||||
{0x0300, 0x0000, (const uint8_t *)&string0, 0}, | {0x0300, 0x0000, (const uint8_t *)&string0, 0}, | ||||
{0x0301, 0x0409, (const uint8_t *)&usb_string_manufacturer_name, 0}, | {0x0301, 0x0409, (const uint8_t *)&usb_string_manufacturer_name, 0}, | ||||
{0x0302, 0x0409, (const uint8_t *)&usb_string_product_name, 0}, | {0x0302, 0x0409, (const uint8_t *)&usb_string_product_name, 0}, | ||||
{0x0303, 0x0409, (const uint8_t *)&usb_string_serial_number, 0}, | {0x0303, 0x0409, (const uint8_t *)&usb_string_serial_number, 0}, | ||||
iInterfaceString( KEYBOARD_INTERFACE, usb_string_keyboard_name ), | |||||
iInterfaceString( NKRO_KEYBOARD_INTERFACE, usb_string_nkro_keyboard_name ), | |||||
iInterfaceString( CDC_STATUS_INTERFACE, usb_string_cdc_status_name ), | |||||
iInterfaceString( CDC_DATA_INTERFACE, usb_string_cdc_data_name ), | |||||
iInterfaceString( MOUSE_INTERFACE, usb_string_mouse_name ), | |||||
iInterfaceString( JOYSTICK_INTERFACE, usb_string_joystick_name ), | |||||
iInterfaceString( SYS_CTRL_INTERFACE, usb_string_sys_ctrl_name ), | |||||
{0, 0, NULL, 0} | {0, 0, NULL, 0} | ||||
}; | }; | ||||
#define DEVICE_SUBCLASS 0x00 | #define DEVICE_SUBCLASS 0x00 | ||||
#define DEVICE_PROTOCOL 0x00 | #define DEVICE_PROTOCOL 0x00 | ||||
#define EP0_SIZE 64 | #define EP0_SIZE 64 | ||||
#define NUM_ENDPOINTS 5 | |||||
#define NUM_ENDPOINTS 8 | |||||
#define NUM_USB_BUFFERS 30 | #define NUM_USB_BUFFERS 30 | ||||
#define NUM_INTERFACE 4 | |||||
#define NUM_INTERFACE 7 | |||||
#define KEYBOARD_INTERFACE 0 // Keyboard | #define KEYBOARD_INTERFACE 0 // Keyboard | ||||
#define KEYBOARD_ENDPOINT 1 | #define KEYBOARD_ENDPOINT 1 | ||||
#define KEYBOARD_SIZE 8 | #define KEYBOARD_SIZE 8 | ||||
#define KEYBOARD_INTERVAL 1 | #define KEYBOARD_INTERVAL 1 | ||||
#define KEYBOARD_NAME L"Boot Keyboard" | |||||
#define NKRO_KEYBOARD_INTERFACE 1 // NKRO Keyboard | #define NKRO_KEYBOARD_INTERFACE 1 // NKRO Keyboard | ||||
#define NKRO_KEYBOARD_ENDPOINT 2 | #define NKRO_KEYBOARD_ENDPOINT 2 | ||||
#define NKRO_KEYBOARD_SIZE 64 | #define NKRO_KEYBOARD_SIZE 64 | ||||
#define NKRO_KEYBOARD_INTERVAL 1 | #define NKRO_KEYBOARD_INTERVAL 1 | ||||
#define NKRO_KEYBOARD_NAME L"NKRO Keyboard" | |||||
#define CDC_IAD_DESCRIPTOR 1 | #define CDC_IAD_DESCRIPTOR 1 | ||||
#define CDC_STATUS_INTERFACE 2 | #define CDC_STATUS_INTERFACE 2 | ||||
#define CDC_ACM_SIZE 16 | #define CDC_ACM_SIZE 16 | ||||
#define CDC_RX_SIZE 64 | #define CDC_RX_SIZE 64 | ||||
#define CDC_TX_SIZE 64 | #define CDC_TX_SIZE 64 | ||||
#define CDC_STATUS_NAME L"Virtual Serial Port - Status" | |||||
#define CDC_DATA_NAME L"Virtual Serial Port - Data" | |||||
#define MOUSE_INTERFACE 4 // Mouse | #define MOUSE_INTERFACE 4 // Mouse | ||||
#define MOUSE_ENDPOINT 6 | #define MOUSE_ENDPOINT 6 | ||||
#define MOUSE_SIZE 8 | #define MOUSE_SIZE 8 | ||||
#define MOUSE_INTERVAL 2 | #define MOUSE_INTERVAL 2 | ||||
#define MOUSE_NAME L"Mouse" | |||||
#define JOYSTICK_INTERFACE 5 // Joystick | #define JOYSTICK_INTERFACE 5 // Joystick | ||||
#define JOYSTICK_ENDPOINT 7 | #define JOYSTICK_ENDPOINT 7 | ||||
#define JOYSTICK_SIZE 16 | #define JOYSTICK_SIZE 16 | ||||
#define JOYSTICK_INTERVAL 1 | #define JOYSTICK_INTERVAL 1 | ||||
#define JOYSTICK_NAME L"Joystick" | |||||
#define SYS_CTRL_INTERFACE 6 // Media Keys | |||||
#define SYS_CTRL_ENDPOINT 8 | |||||
#define SYS_CTRL_SIZE 8 | |||||
#define SYS_CTRL_INTERVAL 1 | |||||
#define SYS_CTRL_NAME L"Media Keys" | |||||
#define KEYBOARD_DESC_OFFSET (9 + 9) | #define KEYBOARD_DESC_OFFSET (9 + 9) | ||||
#define NKRO_KEYBOARD_DESC_OFFSET (9 + 9+9+7 + 9) | #define NKRO_KEYBOARD_DESC_OFFSET (9 + 9+9+7 + 9) | ||||
#define SERIAL_CDC_DESC_OFFSET (9 + 9+9+7 + 9+9+7 + 8) | #define SERIAL_CDC_DESC_OFFSET (9 + 9+9+7 + 9+9+7 + 8) | ||||
#define CONFIG_DESC_SIZE (9 + 9+9+7 + 9+9+7 + 8+9+5+5+4+5+7+9+7+7) | |||||
// XXX Unused | |||||
#define MOUSE_DESC_OFFSET (9 + 9+9+7 + 9+9+7 + 8+9+5+5+4+5+7+9+7+7 + 9) | #define MOUSE_DESC_OFFSET (9 + 9+9+7 + 9+9+7 + 8+9+5+5+4+5+7+9+7+7 + 9) | ||||
#define JOYSTICK_DESC_OFFSET (9 + 9+9+7 + 9+9+7 + 8+9+5+5+4+5+7+9+7+7 + 9+9+7 + 9) | #define JOYSTICK_DESC_OFFSET (9 + 9+9+7 + 9+9+7 + 8+9+5+5+4+5+7+9+7+7 + 9+9+7 + 9) | ||||
#define SYS_CTRL_DESC_OFFSET (9 + 9+9+7 + 9+9+7 + 8+9+5+5+4+5+7+9+7+7 + 9+9+7 + 9+9+7 + 9) | |||||
#define CONFIG_DESC_SIZE (9 + 9+9+7 + 9+9+7 + 8+9+5+5+4+5+7+9+7+7 + 9+9+7 + 9+9+7 + 9+9+7) | |||||
#define ENDPOINT1_CONFIG ENDPOINT_TRANSIMIT_ONLY | #define ENDPOINT1_CONFIG ENDPOINT_TRANSIMIT_ONLY | ||||
#define ENDPOINT2_CONFIG ENDPOINT_TRANSIMIT_ONLY | #define ENDPOINT2_CONFIG ENDPOINT_TRANSIMIT_ONLY | ||||
#define ENDPOINT5_CONFIG ENDPOINT_TRANSIMIT_ONLY | #define ENDPOINT5_CONFIG ENDPOINT_TRANSIMIT_ONLY | ||||
#define ENDPOINT6_CONFIG ENDPOINT_TRANSIMIT_ONLY | #define ENDPOINT6_CONFIG ENDPOINT_TRANSIMIT_ONLY | ||||
#define ENDPOINT7_CONFIG ENDPOINT_TRANSIMIT_ONLY | #define ENDPOINT7_CONFIG ENDPOINT_TRANSIMIT_ONLY | ||||
#define ENDPOINT8_CONFIG ENDPOINT_TRANSIMIT_ONLY | |||||
static void endpoint0_stall() | static void endpoint0_stall() | ||||
{ | { | ||||
#ifdef UART_DEBUG_UNKNOWN | |||||
print("STALL" NL ); | |||||
#endif | |||||
USB0_ENDPT0 = USB_ENDPT_EPSTALL | USB_ENDPT_EPRXEN | USB_ENDPT_EPTXEN | USB_ENDPT_EPHSHK; | USB0_ENDPT0 = USB_ENDPT_EPSTALL | USB_ENDPT_EPRXEN | USB_ENDPT_EPTXEN | USB_ENDPT_EPHSHK; | ||||
} | } | ||||
switch ( setup.wRequestAndType ) | switch ( setup.wRequestAndType ) | ||||
{ | { | ||||
case 0x0500: // SET_ADDRESS | case 0x0500: // SET_ADDRESS | ||||
break; | |||||
goto send; | |||||
case 0x0900: // SET_CONFIGURATION | case 0x0900: // SET_CONFIGURATION | ||||
#ifdef UART_DEBUG | #ifdef UART_DEBUG | ||||
print("CONFIGURE - "); | print("CONFIGURE - "); | ||||
table[ index( i, TX, EVEN ) ].desc = 0; | table[ index( i, TX, EVEN ) ].desc = 0; | ||||
table[ index( i, TX, ODD ) ].desc = 0; | table[ index( i, TX, ODD ) ].desc = 0; | ||||
} | } | ||||
break; | |||||
goto send; | |||||
case 0x0880: // GET_CONFIGURATION | case 0x0880: // GET_CONFIGURATION | ||||
reply_buffer[0] = usb_configuration; | reply_buffer[0] = usb_configuration; | ||||
datalen = 1; | datalen = 1; | ||||
data = reply_buffer; | data = reply_buffer; | ||||
break; | |||||
goto send; | |||||
case 0x0080: // GET_STATUS (device) | case 0x0080: // GET_STATUS (device) | ||||
reply_buffer[0] = 0; | reply_buffer[0] = 0; | ||||
reply_buffer[1] = 0; | reply_buffer[1] = 0; | ||||
datalen = 2; | datalen = 2; | ||||
data = reply_buffer; | data = reply_buffer; | ||||
break; | |||||
goto send; | |||||
case 0x0082: // GET_STATUS (endpoint) | case 0x0082: // GET_STATUS (endpoint) | ||||
if ( setup.wIndex > NUM_ENDPOINTS ) | if ( setup.wIndex > NUM_ENDPOINTS ) | ||||
{ | { | ||||
reply_buffer[0] = 1; | reply_buffer[0] = 1; | ||||
data = reply_buffer; | data = reply_buffer; | ||||
datalen = 2; | datalen = 2; | ||||
break; | |||||
goto send; | |||||
case 0x0100: // CLEAR_FEATURE (device) | case 0x0100: // CLEAR_FEATURE (device) | ||||
case 0x0101: // CLEAR_FEATURE (interface) | case 0x0101: // CLEAR_FEATURE (interface) | ||||
// TODO: Currently ignoring, perhaps useful? -HaaTa | // TODO: Currently ignoring, perhaps useful? -HaaTa | ||||
warn_print("CLEAR_FEATURE - Device/Interface"); | |||||
endpoint0_stall(); | endpoint0_stall(); | ||||
return; | return; | ||||
case 0x0102: // CLEAR_FEATURE (interface) | case 0x0102: // CLEAR_FEATURE (interface) | ||||
i = setup.wIndex & 0x7F; | i = setup.wIndex & 0x7F; | ||||
if ( i > NUM_ENDPOINTS || setup.wValue != 0 ) | if ( i > NUM_ENDPOINTS || setup.wValue != 0 ) | ||||
endpoint0_stall(); | endpoint0_stall(); | ||||
return; | return; | ||||
} | } | ||||
warn_print("CLEAR_FEATURE - Interface"); | |||||
//(*(uint8_t *)(&USB0_ENDPT0 + setup.wIndex * 4)) &= ~0x02; | //(*(uint8_t *)(&USB0_ENDPT0 + setup.wIndex * 4)) &= ~0x02; | ||||
// TODO: do we need to clear the data toggle here? | // TODO: do we need to clear the data toggle here? | ||||
//break; | //break; | ||||
// XXX: Ignoring seems to work, though this may not be the ideal behaviour -HaaTa | // XXX: Ignoring seems to work, though this may not be the ideal behaviour -HaaTa | ||||
endpoint0_stall(); | endpoint0_stall(); | ||||
return; | return; | ||||
case 0x0300: // SET_FEATURE (device) | case 0x0300: // SET_FEATURE (device) | ||||
case 0x0301: // SET_FEATURE (interface) | case 0x0301: // SET_FEATURE (interface) | ||||
// TODO: Currently ignoring, perhaps useful? -HaaTa | // TODO: Currently ignoring, perhaps useful? -HaaTa | ||||
warn_print("SET_FEATURE"); | |||||
endpoint0_stall(); | endpoint0_stall(); | ||||
return; | return; | ||||
case 0x0302: // SET_FEATURE (endpoint) | case 0x0302: // SET_FEATURE (endpoint) | ||||
i = setup.wIndex & 0x7F; | i = setup.wIndex & 0x7F; | ||||
if ( i > NUM_ENDPOINTS || setup.wValue != 0 ) | if ( i > NUM_ENDPOINTS || setup.wValue != 0 ) | ||||
} | } | ||||
(*(uint8_t *)(&USB0_ENDPT0 + setup.wIndex * 4)) |= 0x02; | (*(uint8_t *)(&USB0_ENDPT0 + setup.wIndex * 4)) |= 0x02; | ||||
// TODO: do we need to clear the data toggle here? | // TODO: do we need to clear the data toggle here? | ||||
break; | |||||
goto send; | |||||
case 0x0680: // GET_DESCRIPTOR | case 0x0680: // GET_DESCRIPTOR | ||||
case 0x0681: | case 0x0681: | ||||
#ifdef UART_DEBUG | #ifdef UART_DEBUG | ||||
case 0x2221: // CDC_SET_CONTROL_LINE_STATE | case 0x2221: // CDC_SET_CONTROL_LINE_STATE | ||||
usb_cdc_line_rtsdtr = setup.wValue; | usb_cdc_line_rtsdtr = setup.wValue; | ||||
//serial_print("set control line state\n"); | //serial_print("set control line state\n"); | ||||
endpoint0_stall(); | |||||
return; | |||||
goto send; | |||||
case 0x21A1: // CDC_GET_LINE_CODING | case 0x21A1: // CDC_GET_LINE_CODING | ||||
data = (uint8_t*)usb_cdc_line_coding; | data = (uint8_t*)usb_cdc_line_coding; | ||||
case 0x2021: // CDC_SET_LINE_CODING | case 0x2021: // CDC_SET_LINE_CODING | ||||
// XXX Needed? | // XXX Needed? | ||||
//serial_print("set coding, waiting...\n"); | //serial_print("set coding, waiting...\n"); | ||||
endpoint0_stall(); | |||||
return; // Cannot stall here (causes issues) | |||||
return; | |||||
case 0x0921: // HID SET_REPORT | case 0x0921: // HID SET_REPORT | ||||
#ifdef UART_DEBUG | #ifdef UART_DEBUG | ||||
print("SET_REPORT - "); | |||||
warn_msg("SET_REPORT - "); | |||||
printHex( setup.wValue ); | printHex( setup.wValue ); | ||||
print(" - "); | print(" - "); | ||||
printHex( setup.wValue & 0xFF ); | printHex( setup.wValue & 0xFF ); | ||||
print( NL ); | print( NL ); | ||||
#endif | #endif | ||||
USBKeys_LEDs = setup.wValue & 0xFF; | USBKeys_LEDs = setup.wValue & 0xFF; | ||||
// Must be stall for some reason... -HaaTa | |||||
endpoint0_stall(); | endpoint0_stall(); | ||||
return; | return; | ||||
case 0x01A1: // HID GET_REPORT | case 0x01A1: // HID GET_REPORT | ||||
#ifdef UART_DEBUG | #ifdef UART_DEBUG | ||||
print("GET_REPORT - "); | print("GET_REPORT - "); | ||||
printHex( USBKeys_LEDs ); | |||||
printHex( setup.wIndex ); | |||||
print(NL); | print(NL); | ||||
#endif | #endif | ||||
data = (uint8_t*)&USBKeys_LEDs; | |||||
datalen = 1; | |||||
goto send; | |||||
// Search through descriptors returning necessary info | |||||
for ( list = usb_descriptor_list; 1; list++ ) | |||||
{ | |||||
if ( list->addr == NULL ) | |||||
break; | |||||
if ( list->wValue != 0x2200 ) | |||||
continue; | |||||
if ( setup.wIndex == list->wIndex ) | |||||
{ | |||||
data = list->addr; | |||||
datalen = list->length; | |||||
goto send; | |||||
} | |||||
} | |||||
endpoint0_stall(); | |||||
return; | |||||
case 0x0A21: // HID SET_IDLE | case 0x0A21: // HID SET_IDLE | ||||
#ifdef UART_DEBUG | #ifdef UART_DEBUG | ||||
#endif | #endif | ||||
USBKeys_Idle_Config = (setup.wValue >> 8); | USBKeys_Idle_Config = (setup.wValue >> 8); | ||||
USBKeys_Idle_Count = 0; | USBKeys_Idle_Count = 0; | ||||
endpoint0_stall(); | |||||
return; | |||||
goto send; | |||||
case 0x0B21: // HID SET_PROTOCOL | case 0x0B21: // HID SET_PROTOCOL | ||||
#ifdef UART_DEBUG | #ifdef UART_DEBUG | ||||
print(NL); | print(NL); | ||||
#endif | #endif | ||||
USBKeys_Protocol = setup.wValue & 0xFF; // 0 - Boot Mode, 1 - NKRO Mode | USBKeys_Protocol = setup.wValue & 0xFF; // 0 - Boot Mode, 1 - NKRO Mode | ||||
endpoint0_stall(); | |||||
return; | |||||
goto send; | |||||
// case 0xC940: | // case 0xC940: | ||||
default: | default: | ||||
send: | send: | ||||
#ifdef UART_DEBUG | #ifdef UART_DEBUG | ||||
print("setup send "); | print("setup send "); | ||||
printHex32((uint32_t)data); | |||||
printHex32( (uint32_t)data ); | |||||
print(","); | print(","); | ||||
printHex(datalen); | |||||
print(NL); | |||||
for ( uint8_t c = 0; c < datalen; c++ ) | |||||
{ | |||||
printHex( data[c] ); | |||||
print(" "); | |||||
} | |||||
print(","); | |||||
printHex( datalen ); | |||||
print( NL ); | |||||
#endif | #endif | ||||
if ( datalen > setup.wLength ) | if ( datalen > setup.wLength ) | ||||
// unfreeze the USB, now that we're ready | // unfreeze the USB, now that we're ready | ||||
USB0_CTL = USB_CTL_USBENSOFEN; // clear TXSUSPENDTOKENBUSY bit | USB0_CTL = USB_CTL_USBENSOFEN; // clear TXSUSPENDTOKENBUSY bit | ||||
break; | break; | ||||
case 0x01: // OUT transaction received from host | case 0x01: // OUT transaction received from host | ||||
case 0x02: | case 0x02: | ||||
#ifdef UART_DEBUG | #ifdef UART_DEBUG | ||||
} | } | ||||
break; | break; | ||||
default: | default: | ||||
#ifdef UART_DEBUG | #ifdef UART_DEBUG | ||||
print("PID=unknown:"); | print("PID=unknown:"); |
// When the PC isn't listening, how long do we wait before discarding data? | // When the PC isn't listening, how long do we wait before discarding data? | ||||
#define TX_TIMEOUT_MSEC 50 | #define TX_TIMEOUT_MSEC 50 | ||||
#if F_CPU == 96000000 | |||||
#if F_CPU == 168000000 | |||||
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 1100) | |||||
#elif F_CPU == 144000000 | |||||
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 932) | |||||
#elif F_CPU == 120000000 | |||||
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 764) | |||||
#elif F_CPU == 96000000 | |||||
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 596) | #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 596) | ||||
#elif F_CPU == 72000000 | #elif F_CPU == 72000000 | ||||
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 512) // XXX Correct? | |||||
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 512) | |||||
#elif F_CPU == 48000000 | #elif F_CPU == 48000000 | ||||
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 428) | #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 428) | ||||
#elif F_CPU == 24000000 | #elif F_CPU == 24000000 | ||||
if ( USBKeys_Protocol == 0 ) // Boot Mode | if ( USBKeys_Protocol == 0 ) // Boot Mode | ||||
{ | { | ||||
if ( usb_tx_packet_count( NKRO_KEYBOARD_ENDPOINT ) < TX_PACKET_LIMIT ) | |||||
if ( usb_tx_packet_count( KEYBOARD_ENDPOINT ) < TX_PACKET_LIMIT ) | |||||
{ | { | ||||
tx_packet = usb_malloc(); | tx_packet = usb_malloc(); | ||||
if ( tx_packet ) | if ( tx_packet ) | ||||
} | } | ||||
else if ( USBKeys_Protocol == 1 ) // NKRO Mode | else if ( USBKeys_Protocol == 1 ) // NKRO Mode | ||||
{ | { | ||||
if ( usb_tx_packet_count( KEYBOARD_ENDPOINT ) < TX_PACKET_LIMIT ) | |||||
if ( usb_tx_packet_count( NKRO_KEYBOARD_ENDPOINT ) < TX_PACKET_LIMIT ) | |||||
{ | |||||
tx_packet = usb_malloc(); | |||||
if ( tx_packet ) | |||||
break; | |||||
} | |||||
} | |||||
else if ( USBKeys_Changed & | |||||
( USBKeyChangeState_System | USBKeyChangeState_Consumer ) | |||||
) | |||||
{ | |||||
if ( usb_tx_packet_count( SYS_CTRL_ENDPOINT ) < TX_PACKET_LIMIT ) | |||||
{ | { | ||||
tx_packet = usb_malloc(); | tx_packet = usb_malloc(); | ||||
if ( tx_packet ) | if ( tx_packet ) | ||||
// Pointer to USB tx packet buffer | // Pointer to USB tx packet buffer | ||||
uint8_t *tx_buf = tx_packet->buf; | uint8_t *tx_buf = tx_packet->buf; | ||||
// Check system control keys | |||||
if ( USBKeys_Changed & USBKeyChangeState_System ) | |||||
{ | |||||
if ( Output_DebugMode ) | |||||
{ | |||||
print("SysCtrl["); | |||||
printHex_op( USBKeys_SysCtrl, 2 ); | |||||
print( "] " NL ); | |||||
} | |||||
*tx_buf++ = 0x02; // ID | |||||
*tx_buf = USBKeys_SysCtrl; | |||||
tx_packet->len = 2; | |||||
// Send USB Packet | |||||
usb_tx( SYS_CTRL_ENDPOINT, tx_packet ); | |||||
USBKeys_Changed &= ~USBKeyChangeState_System; // Mark sent | |||||
return; | |||||
} | |||||
// Check consumer control keys | |||||
if ( USBKeys_Changed & USBKeyChangeState_Consumer ) | |||||
{ | |||||
if ( Output_DebugMode ) | |||||
{ | |||||
print("ConsCtrl["); | |||||
printHex_op( USBKeys_ConsCtrl, 2 ); | |||||
print( "] " NL ); | |||||
} | |||||
*tx_buf++ = 0x03; // ID | |||||
*tx_buf++ = (uint8_t)(USBKeys_ConsCtrl & 0x00FF); | |||||
*tx_buf = (uint8_t)(USBKeys_ConsCtrl >> 8); | |||||
tx_packet->len = 3; | |||||
// Send USB Packet | |||||
usb_tx( SYS_CTRL_ENDPOINT, tx_packet ); | |||||
USBKeys_Changed &= ~USBKeyChangeState_Consumer; // Mark sent | |||||
return; | |||||
} | |||||
switch ( USBKeys_Protocol ) | switch ( USBKeys_Protocol ) | ||||
{ | { | ||||
// Send boot keyboard interrupt packet(s) | // Send boot keyboard interrupt packet(s) | ||||
dbug_msg("NKRO USB: "); | dbug_msg("NKRO USB: "); | ||||
} | } | ||||
// Check system control keys | |||||
if ( USBKeys_Changed & USBKeyChangeState_System ) | |||||
{ | |||||
if ( Output_DebugMode ) | |||||
{ | |||||
print("SysCtrl["); | |||||
printHex_op( USBKeys_SysCtrl, 2 ); | |||||
print( "] " NL ); | |||||
} | |||||
*tx_buf++ = 0x02; // ID | |||||
*tx_buf = USBKeys_SysCtrl; | |||||
tx_packet->len = 2; | |||||
// Send USB Packet | |||||
usb_tx( NKRO_KEYBOARD_ENDPOINT, tx_packet ); | |||||
USBKeys_Changed &= ~USBKeyChangeState_System; // Mark sent | |||||
} | |||||
// Check consumer control keys | |||||
if ( USBKeys_Changed & USBKeyChangeState_Consumer ) | |||||
{ | |||||
if ( Output_DebugMode ) | |||||
{ | |||||
print("ConsCtrl["); | |||||
printHex_op( USBKeys_ConsCtrl, 2 ); | |||||
print( "] " NL ); | |||||
} | |||||
*tx_buf++ = 0x03; // ID | |||||
*tx_buf++ = (uint8_t)(USBKeys_ConsCtrl & 0x00FF); | |||||
*tx_buf = (uint8_t)(USBKeys_ConsCtrl >> 8); | |||||
tx_packet->len = 3; | |||||
// Send USB Packet | |||||
usb_tx( NKRO_KEYBOARD_ENDPOINT, tx_packet ); | |||||
USBKeys_Changed &= ~USBKeyChangeState_Consumer; // Mark sent | |||||
} | |||||
// Standard HID Keyboard | // Standard HID Keyboard | ||||
if ( USBKeys_Changed ) | if ( USBKeys_Changed ) | ||||
{ | { |
Name = pjrcUSBCapabilities; | Name = pjrcUSBCapabilities; | ||||
Version = 0.4; | |||||
Version = 0.5; | |||||
Author = "HaaTa (Jacob Alexander) 2014-2015"; | Author = "HaaTa (Jacob Alexander) 2014-2015"; | ||||
KLL = 0.3b; | KLL = 0.3b; | ||||
# Modified Date | # Modified Date | ||||
Date = 2015-05-02; | |||||
Date = 2015-07-12; | |||||
# Output capabilities | # Output capabilities | ||||
kbdProtocolBoot => Output_kbdProtocolBoot_capability(); | kbdProtocolBoot => Output_kbdProtocolBoot_capability(); | ||||
kbdProtocolNKRO => Output_kbdProtocolNKRO_capability(); | kbdProtocolNKRO => Output_kbdProtocolNKRO_capability(); | ||||
# Locale Settings | |||||
keyboardLocale => KeyboardLocale_define; | |||||
keyboardLocale = 0; | |||||
output_com.c | output_com.c | ||||
arm/usb_desc.c | arm/usb_desc.c | ||||
arm/usb_dev.c | arm/usb_dev.c | ||||
arm/usb_joystick.c | |||||
arm/usb_keyboard.c | arm/usb_keyboard.c | ||||
arm/usb_mem.c | arm/usb_mem.c | ||||
arm/usb_mouse.c | |||||
arm/usb_serial.c | arm/usb_serial.c | ||||
) | ) | ||||