- 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
@@ -106,28 +106,41 @@ void nmi_default_isr() | |||
// NVIC - Hard Fault 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 | |||
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 | |||
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 | |||
void usage_fault_default_isr() | |||
{ | |||
print("Usage Fault!" NL ); | |||
print("Usage Fault! SCB_CFSR: "); | |||
printHex32( SCB_CFSR ); | |||
print( NL ); | |||
} | |||
@@ -1951,7 +1951,9 @@ typedef struct { | |||
#define SCB_CFSR *(volatile uint32_t *)0xE000ED28 // Configurable Fault Status Register | |||
#define SCB_HFSR *(volatile uint32_t *)0xE000ED2C // HardFault 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_COUNTFLAG (uint32_t)0x00010000 |
@@ -1,7 +1,7 @@ | |||
/* Teensyduino Core Library | |||
* http://www.pjrc.com/teensy/ | |||
* 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 | |||
* a copy of this software and associated documentation files (the | |||
@@ -34,6 +34,9 @@ | |||
// Local Includes | |||
#include "usb_desc.h" | |||
// Generated Includes | |||
#include <kll_defs.h> | |||
// ----- Macros ----- | |||
@@ -260,7 +263,10 @@ static uint8_t nkro_keyboard_report_desc[] = { | |||
0x95, 0x01, // Report Count (1), | |||
0x81, 0x03, // Input (Constant), | |||
0xc0, // End Collection - Keyboard | |||
}; | |||
// System Control and Consumer Control | |||
static uint8_t sys_ctrl_report_desc[] = { | |||
// System Control Collection | |||
// | |||
// NOTES: | |||
@@ -290,16 +296,15 @@ static uint8_t nkro_keyboard_report_desc[] = { | |||
0x85, 0x03, // Report ID (3), | |||
0x75, 0x10, // Report Size (16), | |||
0x95, 0x01, // Report Count (1), | |||
0x16, 0x20, 0x00, // Logical Minimum (32), | |||
0x16, 0x01, 0x00, // Logical Minimum (1), | |||
0x26, 0x9C, 0x02, // Logical Maximum (668), | |||
0x05, 0x0C, // Usage Page (Consumer), | |||
0x19, 0x20, // Usage Minimum (32), | |||
0x19, 0x01, // Usage Minimum (1), | |||
0x2A, 0x9C, 0x02, // Usage Maximum (668), | |||
0x81, 0x00, // Input (Data, Array), | |||
0xc0, // End Collection - Consumer Control | |||
}; | |||
/* MOUSE | |||
// Mouse Protocol 1, HID 1.11 spec, Appendix B, page 59-60, with wheel extension | |||
static uint8_t mouse_report_desc[] = { | |||
0x05, 0x01, // Usage Page (Generic Desktop) | |||
@@ -332,7 +337,52 @@ static uint8_t mouse_report_desc[] = { | |||
0x81, 0x06, // Input (Data, Variable, Relative) | |||
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 | |||
}; | |||
@@ -365,13 +415,13 @@ static uint8_t config_descriptor[CONFIG_DESC_SIZE] = { | |||
0x03, // bInterfaceClass (0x03 = HID) | |||
0x01, // bInterfaceSubClass (0x00 = Non-Boot, 0x01 = Boot) | |||
0x01, // bInterfaceProtocol (0x01 = Keyboard) | |||
0, // iInterface | |||
KEYBOARD_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 | |||
KeyboardLocale_define, // bCountryCode | |||
1, // bNumDescriptors | |||
0x22, // bDescriptorType | |||
LSB(sizeof(keyboard_report_desc)), // wDescriptorLength | |||
@@ -396,13 +446,13 @@ static uint8_t config_descriptor[CONFIG_DESC_SIZE] = { | |||
0x03, // bInterfaceClass (0x03 = HID) | |||
0x00, // bInterfaceSubClass (0x00 = Non-Boot, 0x01 = Boot) | |||
0x01, // bInterfaceProtocol (0x01 = Keyboard) | |||
0, // iInterface | |||
NKRO_KEYBOARD_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 | |||
KeyboardLocale_define, // bCountryCode | |||
1, // bNumDescriptors | |||
0x22, // bDescriptorType | |||
LSB(sizeof(nkro_keyboard_report_desc)), // wDescriptorLength | |||
@@ -426,7 +476,7 @@ static uint8_t config_descriptor[CONFIG_DESC_SIZE] = { | |||
0x02, // bFunctionClass | |||
0x02, // bFunctionSubClass | |||
0x01, // bFunctionProtocol | |||
0, // iFunction | |||
CDC_STATUS_INTERFACE + 4, // iFunction | |||
// --- Serial CDC --- CDC Data Interface | |||
// - 9 bytes - | |||
@@ -439,7 +489,7 @@ static uint8_t config_descriptor[CONFIG_DESC_SIZE] = { | |||
0x02, // bInterfaceClass | |||
0x02, // bInterfaceSubClass | |||
0x01, // bInterfaceProtocol | |||
0, // iInterface | |||
CDC_STATUS_INTERFACE + 4, // iInterface | |||
// - 5 bytes - | |||
// CDC Header Functional Descriptor, CDC Spec 5.2.3.1, Table 26 | |||
5, // bFunctionLength | |||
@@ -484,7 +534,7 @@ static uint8_t config_descriptor[CONFIG_DESC_SIZE] = { | |||
0x0A, // bInterfaceClass | |||
0x00, // bInterfaceSubClass | |||
0x00, // bInterfaceProtocol | |||
0, // iInterface | |||
CDC_DATA_INTERFACE + 4, // iInterface | |||
// - 7 bytes - | |||
// endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 | |||
7, // bLength | |||
@@ -502,8 +552,7 @@ static uint8_t config_descriptor[CONFIG_DESC_SIZE] = { | |||
CDC_TX_SIZE, 0, // wMaxPacketSize | |||
0, // bInterval | |||
/* | |||
// Mouse Interface | |||
// --- Mouse Interface --- | |||
// - 9 bytes - | |||
// interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 | |||
9, // bLength | |||
@@ -513,8 +562,8 @@ static uint8_t config_descriptor[CONFIG_DESC_SIZE] = { | |||
1, // bNumEndpoints | |||
0x03, // bInterfaceClass (0x03 = HID) | |||
0x00, // bInterfaceSubClass (0x01 = Boot) | |||
0x00, // bInterfaceProtocol (0x02 = Mouse) | |||
0, // iInterface | |||
0x02, // bInterfaceProtocol (0x02 = Mouse) | |||
MOUSE_INTERFACE + 4, // iInterface | |||
// - 9 bytes - | |||
// HID interface descriptor, HID 1.11 spec, section 6.2.1 | |||
9, // bLength | |||
@@ -533,8 +582,68 @@ static uint8_t config_descriptor[CONFIG_DESC_SIZE] = { | |||
0x03, // bmAttributes (0x03=intr) | |||
MOUSE_SIZE, 0, // wMaxPacketSize | |||
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 | |||
}; | |||
@@ -564,21 +673,23 @@ struct usb_string_descriptor_struct string0 = { | |||
{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 ); | |||
@@ -592,18 +703,36 @@ const usb_descriptor_list_t usb_descriptor_list[] = { | |||
{0x0200, 0x0000, config_descriptor, sizeof(config_descriptor)}, | |||
{0x0600, 0x0000, device_qualifier_descriptor, sizeof(device_qualifier_descriptor)}, | |||
{0x0A00, 0x0000, usb_debug_descriptor, sizeof(usb_debug_descriptor)}, | |||
{0x2200, KEYBOARD_INTERFACE, keyboard_report_desc, sizeof(keyboard_report_desc)}, | |||
{0x2100, KEYBOARD_INTERFACE, config_descriptor + KEYBOARD_DESC_OFFSET, 9}, | |||
{0x2200, NKRO_KEYBOARD_INTERFACE, nkro_keyboard_report_desc, sizeof(nkro_keyboard_report_desc)}, | |||
{0x2100, NKRO_KEYBOARD_INTERFACE, config_descriptor + NKRO_KEYBOARD_DESC_OFFSET, 9}, | |||
/* MOUSE | |||
{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}, | |||
{0x0301, 0x0409, (const uint8_t *)&usb_string_manufacturer_name, 0}, | |||
{0x0302, 0x0409, (const uint8_t *)&usb_string_product_name, 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} | |||
}; | |||
@@ -54,19 +54,21 @@ | |||
#define DEVICE_SUBCLASS 0x00 | |||
#define DEVICE_PROTOCOL 0x00 | |||
#define EP0_SIZE 64 | |||
#define NUM_ENDPOINTS 5 | |||
#define NUM_ENDPOINTS 8 | |||
#define NUM_USB_BUFFERS 30 | |||
#define NUM_INTERFACE 4 | |||
#define NUM_INTERFACE 7 | |||
#define KEYBOARD_INTERFACE 0 // Keyboard | |||
#define KEYBOARD_ENDPOINT 1 | |||
#define KEYBOARD_SIZE 8 | |||
#define KEYBOARD_INTERVAL 1 | |||
#define KEYBOARD_NAME L"Boot Keyboard" | |||
#define NKRO_KEYBOARD_INTERFACE 1 // NKRO Keyboard | |||
#define NKRO_KEYBOARD_ENDPOINT 2 | |||
#define NKRO_KEYBOARD_SIZE 64 | |||
#define NKRO_KEYBOARD_INTERVAL 1 | |||
#define NKRO_KEYBOARD_NAME L"NKRO Keyboard" | |||
#define CDC_IAD_DESCRIPTOR 1 | |||
#define CDC_STATUS_INTERFACE 2 | |||
@@ -77,25 +79,34 @@ | |||
#define CDC_ACM_SIZE 16 | |||
#define CDC_RX_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_ENDPOINT 6 | |||
#define MOUSE_SIZE 8 | |||
#define MOUSE_INTERVAL 2 | |||
#define MOUSE_NAME L"Mouse" | |||
#define JOYSTICK_INTERFACE 5 // Joystick | |||
#define JOYSTICK_ENDPOINT 7 | |||
#define JOYSTICK_SIZE 16 | |||
#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 NKRO_KEYBOARD_DESC_OFFSET (9 + 9+9+7 + 9) | |||
#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 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 ENDPOINT2_CONFIG ENDPOINT_TRANSIMIT_ONLY | |||
@@ -104,6 +115,7 @@ | |||
#define ENDPOINT5_CONFIG ENDPOINT_TRANSIMIT_ONLY | |||
#define ENDPOINT6_CONFIG ENDPOINT_TRANSIMIT_ONLY | |||
#define ENDPOINT7_CONFIG ENDPOINT_TRANSIMIT_ONLY | |||
#define ENDPOINT8_CONFIG ENDPOINT_TRANSIMIT_ONLY | |||
@@ -173,6 +173,9 @@ static uint8_t reply_buffer[8]; | |||
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; | |||
} | |||
@@ -198,7 +201,8 @@ static void usb_setup() | |||
switch ( setup.wRequestAndType ) | |||
{ | |||
case 0x0500: // SET_ADDRESS | |||
break; | |||
goto send; | |||
case 0x0900: // SET_CONFIGURATION | |||
#ifdef UART_DEBUG | |||
print("CONFIGURE - "); | |||
@@ -288,18 +292,21 @@ static void usb_setup() | |||
table[ index( i, TX, EVEN ) ].desc = 0; | |||
table[ index( i, TX, ODD ) ].desc = 0; | |||
} | |||
break; | |||
goto send; | |||
case 0x0880: // GET_CONFIGURATION | |||
reply_buffer[0] = usb_configuration; | |||
datalen = 1; | |||
data = reply_buffer; | |||
break; | |||
goto send; | |||
case 0x0080: // GET_STATUS (device) | |||
reply_buffer[0] = 0; | |||
reply_buffer[1] = 0; | |||
datalen = 2; | |||
data = reply_buffer; | |||
break; | |||
goto send; | |||
case 0x0082: // GET_STATUS (endpoint) | |||
if ( setup.wIndex > NUM_ENDPOINTS ) | |||
{ | |||
@@ -313,12 +320,15 @@ static void usb_setup() | |||
reply_buffer[0] = 1; | |||
data = reply_buffer; | |||
datalen = 2; | |||
break; | |||
goto send; | |||
case 0x0100: // CLEAR_FEATURE (device) | |||
case 0x0101: // CLEAR_FEATURE (interface) | |||
// TODO: Currently ignoring, perhaps useful? -HaaTa | |||
warn_print("CLEAR_FEATURE - Device/Interface"); | |||
endpoint0_stall(); | |||
return; | |||
case 0x0102: // CLEAR_FEATURE (interface) | |||
i = setup.wIndex & 0x7F; | |||
if ( i > NUM_ENDPOINTS || setup.wValue != 0 ) | |||
@@ -326,6 +336,7 @@ static void usb_setup() | |||
endpoint0_stall(); | |||
return; | |||
} | |||
warn_print("CLEAR_FEATURE - Interface"); | |||
//(*(uint8_t *)(&USB0_ENDPT0 + setup.wIndex * 4)) &= ~0x02; | |||
// TODO: do we need to clear the data toggle here? | |||
//break; | |||
@@ -334,11 +345,14 @@ static void usb_setup() | |||
// XXX: Ignoring seems to work, though this may not be the ideal behaviour -HaaTa | |||
endpoint0_stall(); | |||
return; | |||
case 0x0300: // SET_FEATURE (device) | |||
case 0x0301: // SET_FEATURE (interface) | |||
// TODO: Currently ignoring, perhaps useful? -HaaTa | |||
warn_print("SET_FEATURE"); | |||
endpoint0_stall(); | |||
return; | |||
case 0x0302: // SET_FEATURE (endpoint) | |||
i = setup.wIndex & 0x7F; | |||
if ( i > NUM_ENDPOINTS || setup.wValue != 0 ) | |||
@@ -349,7 +363,8 @@ static void usb_setup() | |||
} | |||
(*(uint8_t *)(&USB0_ENDPT0 + setup.wIndex * 4)) |= 0x02; | |||
// TODO: do we need to clear the data toggle here? | |||
break; | |||
goto send; | |||
case 0x0680: // GET_DESCRIPTOR | |||
case 0x0681: | |||
#ifdef UART_DEBUG | |||
@@ -401,8 +416,7 @@ static void usb_setup() | |||
case 0x2221: // CDC_SET_CONTROL_LINE_STATE | |||
usb_cdc_line_rtsdtr = setup.wValue; | |||
//serial_print("set control line state\n"); | |||
endpoint0_stall(); | |||
return; | |||
goto send; | |||
case 0x21A1: // CDC_GET_LINE_CODING | |||
data = (uint8_t*)usb_cdc_line_coding; | |||
@@ -412,30 +426,44 @@ static void usb_setup() | |||
case 0x2021: // CDC_SET_LINE_CODING | |||
// XXX Needed? | |||
//serial_print("set coding, waiting...\n"); | |||
endpoint0_stall(); | |||
return; // Cannot stall here (causes issues) | |||
return; | |||
case 0x0921: // HID SET_REPORT | |||
#ifdef UART_DEBUG | |||
print("SET_REPORT - "); | |||
warn_msg("SET_REPORT - "); | |||
printHex( setup.wValue ); | |||
print(" - "); | |||
printHex( setup.wValue & 0xFF ); | |||
print( NL ); | |||
#endif | |||
USBKeys_LEDs = setup.wValue & 0xFF; | |||
// Must be stall for some reason... -HaaTa | |||
endpoint0_stall(); | |||
return; | |||
case 0x01A1: // HID GET_REPORT | |||
#ifdef UART_DEBUG | |||
print("GET_REPORT - "); | |||
printHex( USBKeys_LEDs ); | |||
printHex( setup.wIndex ); | |||
print(NL); | |||
#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 | |||
#ifdef UART_DEBUG | |||
@@ -445,8 +473,7 @@ static void usb_setup() | |||
#endif | |||
USBKeys_Idle_Config = (setup.wValue >> 8); | |||
USBKeys_Idle_Count = 0; | |||
endpoint0_stall(); | |||
return; | |||
goto send; | |||
case 0x0B21: // HID SET_PROTOCOL | |||
#ifdef UART_DEBUG | |||
@@ -457,8 +484,7 @@ static void usb_setup() | |||
print(NL); | |||
#endif | |||
USBKeys_Protocol = setup.wValue & 0xFF; // 0 - Boot Mode, 1 - NKRO Mode | |||
endpoint0_stall(); | |||
return; | |||
goto send; | |||
// case 0xC940: | |||
default: | |||
@@ -472,10 +498,16 @@ static void usb_setup() | |||
send: | |||
#ifdef UART_DEBUG | |||
print("setup send "); | |||
printHex32((uint32_t)data); | |||
printHex32( (uint32_t)data ); | |||
print(","); | |||
printHex(datalen); | |||
print(NL); | |||
for ( uint8_t c = 0; c < datalen; c++ ) | |||
{ | |||
printHex( data[c] ); | |||
print(" "); | |||
} | |||
print(","); | |||
printHex( datalen ); | |||
print( NL ); | |||
#endif | |||
if ( datalen > setup.wLength ) | |||
@@ -592,6 +624,7 @@ static void usb_control( uint32_t stat ) | |||
// unfreeze the USB, now that we're ready | |||
USB0_CTL = USB_CTL_USBENSOFEN; // clear TXSUSPENDTOKENBUSY bit | |||
break; | |||
case 0x01: // OUT transaction received from host | |||
case 0x02: | |||
#ifdef UART_DEBUG | |||
@@ -663,6 +696,7 @@ static void usb_control( uint32_t stat ) | |||
} | |||
break; | |||
default: | |||
#ifdef UART_DEBUG | |||
print("PID=unknown:"); |
@@ -52,10 +52,16 @@ | |||
// When the PC isn't listening, how long do we wait before discarding data? | |||
#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) | |||
#elif F_CPU == 72000000 | |||
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 512) // XXX Correct? | |||
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 512) | |||
#elif F_CPU == 48000000 | |||
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 428) | |||
#elif F_CPU == 24000000 | |||
@@ -89,7 +95,7 @@ void usb_keyboard_send() | |||
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(); | |||
if ( tx_packet ) | |||
@@ -98,7 +104,18 @@ void usb_keyboard_send() | |||
} | |||
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(); | |||
if ( tx_packet ) | |||
@@ -118,6 +135,47 @@ void usb_keyboard_send() | |||
// Pointer to USB tx packet buffer | |||
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 ) | |||
{ | |||
// Send boot keyboard interrupt packet(s) | |||
@@ -157,45 +215,6 @@ void usb_keyboard_send() | |||
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 | |||
if ( USBKeys_Changed ) | |||
{ |
@@ -1,10 +1,10 @@ | |||
Name = pjrcUSBCapabilities; | |||
Version = 0.4; | |||
Version = 0.5; | |||
Author = "HaaTa (Jacob Alexander) 2014-2015"; | |||
KLL = 0.3b; | |||
# Modified Date | |||
Date = 2015-05-02; | |||
Date = 2015-07-12; | |||
# Output capabilities | |||
@@ -17,3 +17,7 @@ usbKeyOut => Output_usbCodeSend_capability( usbCode : 1 ); | |||
kbdProtocolBoot => Output_kbdProtocolBoot_capability(); | |||
kbdProtocolNKRO => Output_kbdProtocolNKRO_capability(); | |||
# Locale Settings | |||
keyboardLocale => KeyboardLocale_define; | |||
keyboardLocale = 0; | |||
@@ -26,8 +26,10 @@ elseif ( ${COMPILER_FAMILY} MATCHES "arm" ) | |||
output_com.c | |||
arm/usb_desc.c | |||
arm/usb_dev.c | |||
arm/usb_joystick.c | |||
arm/usb_keyboard.c | |||
arm/usb_mem.c | |||
arm/usb_mouse.c | |||
arm/usb_serial.c | |||
) | |||