Browse Source

FIxing Media Keys and general USB compatibilty

- 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 locale
capsense
Jacob Alexander 8 years ago
parent
commit
20b62afb9a

+ 17
- 4
Lib/mk20dx.c View File

// 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 );
} }





+ 3
- 1
Lib/mk20dx.h View File

#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

+ 165
- 36
Output/pjrcUSB/arm/usb_desc.c View File

/* 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}
}; };



+ 17
- 5
Output/pjrcUSB/arm/usb_desc.h View File

#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







+ 56
- 22
Output/pjrcUSB/arm/usb_dev.c View File



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:");

+ 62
- 43
Output/pjrcUSB/arm/usb_keyboard.c View File

// 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 )
{ {

+ 6
- 2
Output/pjrcUSB/capabilities.kll View File

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;


+ 2
- 0
Output/pjrcUSB/setup.cmake View File

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
) )