Major USB update, fixes most (if not all) known issues
USB - General - Refactored descriptors - Enabled/Disable USB endpoints - Added debug flags for special features - Code cleanup - Interface count calculation based off of enabled endpoints - Delayed wTotalLength calculation to simplify descriptor offsets - Re-ordered endpoints and interfaces - Added more debug output - Added usbInitTime to show how long keyboard initialization took (Useful when debugging bad init sequences) - Added function for usb_resume() which takes care of the resume sequence * Resume is now only called if packets are starting to timeout USB - Special Options - Added enableDeviceRestartOnUSBTimeout * A last resort hammer for bad USB Chipsets/OSs, don't use if you can help it * Disabled - Added enableUSBResume * Enables host resume wake-up signalling, required to wake a computer from sleep * Enabled - Added enableUSBLowPowerNegotiation * Enables power negotiation hack * Required to use firmware with an IPad and other hard-limit low-power USB hosts * Hasn't been tested with the recent changes * Disabled - Added enableUSBSuspend * Enables power down events on host USB bus suspend * Enabled USB - Keyboard - Attempted to cleanup HID SET_REPORT * Works much better * Still has an issue under Linux which generates *a lot* of NAKs (initializes quickly regardless) + Not present on other keyboards + SETUP -> OUT -> IN : This sequence is the problem + Specifically during the OUT phase - Enabled USB - CDC Virtual Serial Port - Code cleanup - Added convenience struct USBCDCLineCoding for easier debugging - Attempted to cleanup CDC_SET_LING_CODING * Works much better * Still has an issue under Linux which generates *a lot* of NAKs (initializes quickly regardless) + SETUP -> OUT -> IN : This sequence is the problem + Specifically during the OUT phase + Likely the same issues as HID SET_REPORT - Enabled USB - Mouse - Enabled USB - Joystick - Disabled USB - RawIO - Initial code, API not used yet - Disabled DFU - Updated load script, now faster
This commit is contained in:
parent
8a96e70b4b
commit
358d480ea9
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (C) 2011-2014 by Jacob Alexander
|
/* Copyright (C) 2011-2016 by Jacob Alexander
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@ -127,7 +127,7 @@ void printHex32_op( uint32_t in, uint8_t op )
|
|||||||
// With an op of 1, the max number of characters is 6 + 1 for null
|
// With an op of 1, the max number of characters is 6 + 1 for null
|
||||||
// e.g. "0xFFFF\0"
|
// e.g. "0xFFFF\0"
|
||||||
// op 2 and 4 require fewer characters (2+1 and 4+1 respectively)
|
// op 2 and 4 require fewer characters (2+1 and 4+1 respectively)
|
||||||
char tmpStr[7];
|
char tmpStr[11];
|
||||||
|
|
||||||
// Convert number
|
// Convert number
|
||||||
hex32ToStr_op( in, tmpStr, op );
|
hex32ToStr_op( in, tmpStr, op );
|
||||||
@ -259,6 +259,7 @@ void hex32ToStr_op( uint32_t in, char* out, uint8_t op )
|
|||||||
break;
|
break;
|
||||||
case 2: // 8-bit padding
|
case 2: // 8-bit padding
|
||||||
case 4: // 16-bit padding
|
case 4: // 16-bit padding
|
||||||
|
case 8: // 32-bit padding
|
||||||
while ( pos < op )
|
while ( pos < op )
|
||||||
out[pos++] = '0';
|
out[pos++] = '0';
|
||||||
break;
|
break;
|
||||||
|
@ -2,8 +2,9 @@
|
|||||||
# Convenience script for loading firmware onto a dfu type device
|
# Convenience script for loading firmware onto a dfu type device
|
||||||
# By default, initiates dfu-util
|
# By default, initiates dfu-util
|
||||||
|
|
||||||
SERIAL_PORT=""
|
SERIAL_PORT="/dev/kiibohd"
|
||||||
AUTO_SCREEN_SESSION=""
|
AUTO_SCREEN_SESSION="/dev/kiibohd"
|
||||||
|
NOSCREEN=0
|
||||||
PROG_NAME=$(basename $0)
|
PROG_NAME=$(basename $0)
|
||||||
|
|
||||||
# Parse all the command line arguments
|
# Parse all the command line arguments
|
||||||
@ -19,6 +20,10 @@ while (( "$#" >= "1" )); do
|
|||||||
SERIAL_PORT="$2"
|
SERIAL_PORT="$2"
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
|
-n|--noscreen)
|
||||||
|
NOSCREEN=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
-h|--help)
|
-h|--help)
|
||||||
echo "Usage: $PROG_NAME [options...]"
|
echo "Usage: $PROG_NAME [options...]"
|
||||||
echo ""
|
echo ""
|
||||||
@ -49,12 +54,19 @@ done
|
|||||||
if [[ "$SERIAL_PORT" != "" ]] && [[ -e "$SERIAL_PORT" ]]; then
|
if [[ "$SERIAL_PORT" != "" ]] && [[ -e "$SERIAL_PORT" ]]; then
|
||||||
echo "NOTE: This may fail if the uC is in a bad state or does not support remote flashing"
|
echo "NOTE: This may fail if the uC is in a bad state or does not support remote flashing"
|
||||||
printf "reload\r" > $SERIAL_PORT
|
printf "reload\r" > $SERIAL_PORT
|
||||||
sleep 2
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Load via dfu-util
|
# Load via dfu-util
|
||||||
# Used for McHCK based uCs
|
# Used for McHCK based uCs
|
||||||
if type dfu-util &>/dev/null; then
|
if type dfu-util &>/dev/null; then
|
||||||
|
# Wait for device to appear
|
||||||
|
while true; do
|
||||||
|
dfu-util -l | grep -q "Kiibohd DFU"
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
sleep 0.1
|
||||||
|
done
|
||||||
dfu-util -D @TARGET_BIN@
|
dfu-util -D @TARGET_BIN@
|
||||||
EXIT_STATUS=$?
|
EXIT_STATUS=$?
|
||||||
else
|
else
|
||||||
@ -63,9 +75,12 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Load Screen Session if specified
|
# Load Screen Session if specified
|
||||||
if (( "$EXIT_STATUS" == "0" )) && [[ "$AUTO_SCREEN_SESSION" != "" ]]; then
|
if (( "$EXIT_STATUS" == "0" )) && [[ "$AUTO_SCREEN_SESSION" != "" ]] && [[ $NOSCREEN -ne 1 ]]; then
|
||||||
if type screen &>/dev/null; then
|
if type screen &>/dev/null; then
|
||||||
|
# Wait for interface
|
||||||
|
while [ ! -e $AUTO_SCREEN_SESSION ]; do
|
||||||
sleep 0.1
|
sleep 0.1
|
||||||
|
done
|
||||||
screen $AUTO_SCREEN_SESSION
|
screen $AUTO_SCREEN_SESSION
|
||||||
else
|
else
|
||||||
echo "screen is not installed"
|
echo "screen is not installed"
|
||||||
|
@ -103,6 +103,7 @@ static uint8_t usb_debug_descriptor[] = {
|
|||||||
// the meaning and format of the data.
|
// the meaning and format of the data.
|
||||||
|
|
||||||
// Keyboard Protocol 1, HID 1.11 spec, Appendix B, page 59-60
|
// Keyboard Protocol 1, HID 1.11 spec, Appendix B, page 59-60
|
||||||
|
#if enableKeyboard_define == 1
|
||||||
static uint8_t keyboard_report_desc[] = {
|
static uint8_t keyboard_report_desc[] = {
|
||||||
// Keyboard Collection
|
// Keyboard Collection
|
||||||
0x05, 0x01, // Usage Page (Generic Desktop),
|
0x05, 0x01, // Usage Page (Generic Desktop),
|
||||||
@ -304,8 +305,11 @@ static uint8_t sys_ctrl_report_desc[] = {
|
|||||||
0x81, 0x00, // Input (Data, Array),
|
0x81, 0x00, // Input (Data, Array),
|
||||||
0xc0, // End Collection - Consumer Control
|
0xc0, // End Collection - Consumer Control
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// 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
|
||||||
|
#if enableMouse_define == 1
|
||||||
static uint8_t mouse_report_desc[] = {
|
static uint8_t mouse_report_desc[] = {
|
||||||
0x05, 0x01, // Usage Page (Generic Desktop)
|
0x05, 0x01, // Usage Page (Generic Desktop)
|
||||||
0x09, 0x02, // Usage (Mouse)
|
0x09, 0x02, // Usage (Mouse)
|
||||||
@ -383,8 +387,11 @@ static uint8_t mouse_report_desc[] = {
|
|||||||
0xc0, // End Collection - Mouse Logical
|
0xc0, // End Collection - Mouse Logical
|
||||||
0xc0 // End Collection - Mouse Application
|
0xc0 // End Collection - Mouse Application
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// Joystick Protocol, HID 1.11 spec, Apendix D, page 64-65
|
// Joystick Protocol, HID 1.11 spec, Apendix D, page 64-65
|
||||||
|
#if enableJoystick_define == 1
|
||||||
static uint8_t joystick_report_desc[] = {
|
static uint8_t joystick_report_desc[] = {
|
||||||
0x05, 0x01, // Usage Page (Generic Desktop)
|
0x05, 0x01, // Usage Page (Generic Desktop)
|
||||||
0x09, 0x04, // Usage (Joystick)
|
0x09, 0x04, // Usage (Joystick)
|
||||||
@ -429,27 +436,68 @@ static uint8_t joystick_report_desc[] = {
|
|||||||
0x81, 0x02, // Input (variable,absolute)
|
0x81, 0x02, // Input (variable,absolute)
|
||||||
0xC0 // End Collection
|
0xC0 // End Collection
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ----- USB Configuration -----
|
// ----- USB Configuration -----
|
||||||
|
|
||||||
|
// Check for non-selected USB descriptors to update the total interface count
|
||||||
|
// XXX This must be correct or some OSs/Init sequences will not initialize the keyboard/device
|
||||||
|
#if enableKeyboard_define != 1
|
||||||
|
#undef KEYBOARD_INTERFACES
|
||||||
|
#define KEYBOARD_INTERFACES 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if enableMouse_define != 1
|
||||||
|
#undef MOUSE_INTERFACES
|
||||||
|
#define MOUSE_INTERFACES 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if enableJoystick_define != 1
|
||||||
|
#undef JOYSTICK_INTERFACES
|
||||||
|
#define JOYSTICK_INTERFACES 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if enableVirtualSerialPort_define != 1
|
||||||
|
#undef CDC_INTERFACES
|
||||||
|
#define CDC_INTERFACES 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if enableRawIO_define != 1
|
||||||
|
#undef RAWIO_INTERFACES
|
||||||
|
#define RAWIO_INTERFACES 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Determine number of interfaces
|
||||||
|
#define NUM_INTERFACE (KEYBOARD_INTERFACES + CDC_INTERFACES + MOUSE_INTERFACES + JOYSTICK_INTERFACES + RAWIO_INTERFACES)
|
||||||
|
|
||||||
|
|
||||||
// USB Configuration Descriptor. This huge descriptor tells all
|
// USB Configuration Descriptor. This huge descriptor tells all
|
||||||
// of the devices capbilities.
|
// of the devices capbilities.
|
||||||
static uint8_t config_descriptor[CONFIG_DESC_SIZE] = {
|
static uint8_t config_descriptor[] = {
|
||||||
// --- Configuration ---
|
// --- Configuration ---
|
||||||
// - 9 bytes -
|
// - 9 bytes -
|
||||||
// configuration descriptor, USB spec 9.6.3, page 264-266, Table 9-10
|
// configuration descriptor, USB spec 9.6.3, page 264-266, Table 9-10
|
||||||
9, // bLength;
|
9, // bLength;
|
||||||
2, // bDescriptorType;
|
2, // bDescriptorType;
|
||||||
LSB(CONFIG_DESC_SIZE), // wTotalLength
|
0xFF, // wTotalLength - XXX Set in usb_init (simplifies defines)
|
||||||
MSB(CONFIG_DESC_SIZE),
|
0xFF,
|
||||||
NUM_INTERFACE, // bNumInterfaces
|
NUM_INTERFACE, // bNumInterfaces
|
||||||
1, // bConfigurationValue
|
1, // bConfigurationValue
|
||||||
0, // iConfiguration
|
0, // iConfiguration
|
||||||
0xA0, // bmAttributes
|
0xA0, // bmAttributes
|
||||||
250, // bMaxPower - Entry Index 8
|
250, // bMaxPower - Entry Index 8
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// --- Keyboard Endpoint Descriptors ---
|
||||||
|
//
|
||||||
|
#if enableKeyboard_define == 1
|
||||||
|
#define KEYBOARD_DESC_TOTAL_OFFSET (KEYBOARD_DESC_SIZE + NKRO_KEYBOARD_DESC_SIZE + SYS_CTRL_DESC_SIZE)
|
||||||
|
#define NKRO_KEYBOARD_DESC_BASE_OFFSET (KEYBOARD_DESC_BASE_OFFSET + KEYBOARD_DESC_SIZE)
|
||||||
|
#define SYS_CTRL_DESC_BASE_OFFSET (KEYBOARD_DESC_BASE_OFFSET + KEYBOARD_DESC_SIZE + NKRO_KEYBOARD_DESC_SIZE)
|
||||||
|
|
||||||
// --- Keyboard HID --- Boot Mode Keyboard Interface
|
// --- Keyboard HID --- Boot Mode Keyboard 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
|
||||||
@ -512,6 +560,47 @@ static uint8_t config_descriptor[CONFIG_DESC_SIZE] = {
|
|||||||
NKRO_KEYBOARD_SIZE, 0, // wMaxPacketSize
|
NKRO_KEYBOARD_SIZE, 0, // wMaxPacketSize
|
||||||
NKRO_KEYBOARD_INTERVAL, // bInterval
|
NKRO_KEYBOARD_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
|
||||||
|
#else
|
||||||
|
#define KEYBOARD_DESC_TOTAL_OFFSET (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// --- CDC / Serial Port Endpoint Descriptors ---
|
||||||
|
//
|
||||||
|
#if enableVirtualSerialPort_define == 1
|
||||||
|
#define SERIAL_CDC_DESC_TOTAL_OFFSET (SERIAL_CDC_DESC_SIZE)
|
||||||
|
|
||||||
// --- Serial CDC --- CDC IAD Descriptor
|
// --- Serial CDC --- CDC IAD Descriptor
|
||||||
// - 8 bytes -
|
// - 8 bytes -
|
||||||
// interface association descriptor, USB ECN, Table 9-Z
|
// interface association descriptor, USB ECN, Table 9-Z
|
||||||
@ -522,7 +611,7 @@ static uint8_t config_descriptor[CONFIG_DESC_SIZE] = {
|
|||||||
0x02, // bFunctionClass
|
0x02, // bFunctionClass
|
||||||
0x02, // bFunctionSubClass
|
0x02, // bFunctionSubClass
|
||||||
0x01, // bFunctionProtocol
|
0x01, // bFunctionProtocol
|
||||||
CDC_STATUS_INTERFACE + 4, // iFunction
|
0, // iFunction (XXX No interface index, don't give string -HaaTa)
|
||||||
|
|
||||||
// --- Serial CDC --- CDC Data Interface
|
// --- Serial CDC --- CDC Data Interface
|
||||||
// - 9 bytes -
|
// - 9 bytes -
|
||||||
@ -597,6 +686,57 @@ static uint8_t config_descriptor[CONFIG_DESC_SIZE] = {
|
|||||||
0x02, // bmAttributes (0x02=bulk)
|
0x02, // bmAttributes (0x02=bulk)
|
||||||
CDC_TX_SIZE, 0, // wMaxPacketSize
|
CDC_TX_SIZE, 0, // wMaxPacketSize
|
||||||
0, // bInterval
|
0, // bInterval
|
||||||
|
#else
|
||||||
|
#define SERIAL_CDC_DESC_TOTAL_OFFSET (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// --- Raw IO Endpoint Descriptors ---
|
||||||
|
//
|
||||||
|
#if enableRawIO_define == 1
|
||||||
|
#define RAWIO_DESC_TOTAL_OFFSET (RAWIO_DESC_SIZE)
|
||||||
|
|
||||||
|
// --- Vendor Specific / RAW I/O ---
|
||||||
|
// - 9 bytes -
|
||||||
|
// interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
|
||||||
|
9, // bLength
|
||||||
|
4, // bDescriptorType
|
||||||
|
RAWIO_INTERFACE, // bInterfaceNumber
|
||||||
|
0, // bAlternateSetting
|
||||||
|
2, // bNumEndpoints
|
||||||
|
0xFF, // bInterfaceClass (0xFF)
|
||||||
|
0xFF, // bInterfaceSubClass
|
||||||
|
0xFF, // bInterfaceProtocol
|
||||||
|
RAWIO_INTERFACE + 4, // iInterface
|
||||||
|
|
||||||
|
// - 7 bytes -
|
||||||
|
// endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
|
||||||
|
7, // bLength
|
||||||
|
5, // bDescriptorType
|
||||||
|
RAWIO_TX_ENDPOINT | 0x80, // bEndpointAddress
|
||||||
|
0x02, // bmAttributes (0x02=bulk)
|
||||||
|
RAWIO_TX_SIZE, 0, // wMaxPacketSize
|
||||||
|
RAWIO_TX_INTERVAL, // bInterval
|
||||||
|
|
||||||
|
// - 7 bytes -
|
||||||
|
// endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
|
||||||
|
7, // bLength
|
||||||
|
5, // bDescriptorType
|
||||||
|
RAWIO_RX_ENDPOINT, // bEndpointAddress
|
||||||
|
0x02, // bmAttributes (0x02=bulk)
|
||||||
|
RAWIO_RX_SIZE, 0, // wMaxPacketSize
|
||||||
|
RAWIO_RX_INTERVAL, // bInterval
|
||||||
|
#else
|
||||||
|
#define RAWIO_DESC_TOTAL_OFFSET (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// --- Mouse Endpoint Descriptors ---
|
||||||
|
//
|
||||||
|
#if enableMouse_define == 1
|
||||||
|
#define MOUSE_DESC_TOTAL_OFFSET (MOUSE_DESC_SIZE)
|
||||||
|
|
||||||
// --- Mouse Interface ---
|
// --- Mouse Interface ---
|
||||||
// - 9 bytes -
|
// - 9 bytes -
|
||||||
@ -628,6 +768,16 @@ static uint8_t config_descriptor[CONFIG_DESC_SIZE] = {
|
|||||||
0x03, // bmAttributes (0x03=intr)
|
0x03, // bmAttributes (0x03=intr)
|
||||||
MOUSE_SIZE, 0, // wMaxPacketSize
|
MOUSE_SIZE, 0, // wMaxPacketSize
|
||||||
MOUSE_INTERVAL, // bInterval
|
MOUSE_INTERVAL, // bInterval
|
||||||
|
#else
|
||||||
|
#define MOUSE_DESC_TOTAL_OFFSET (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// --- Joystick Endpoint Descriptors ---
|
||||||
|
//
|
||||||
|
#if enableJoystick_define == 1
|
||||||
|
#define JOYSTICK_DESC_TOTAL_OFFSET (JOYSTICK_DESC_SIZE)
|
||||||
|
|
||||||
// --- Joystick Interface ---
|
// --- Joystick Interface ---
|
||||||
// - 9 bytes -
|
// - 9 bytes -
|
||||||
@ -659,37 +809,10 @@ static uint8_t config_descriptor[CONFIG_DESC_SIZE] = {
|
|||||||
0x03, // bmAttributes (0x03=intr)
|
0x03, // bmAttributes (0x03=intr)
|
||||||
JOYSTICK_SIZE, 0, // wMaxPacketSize
|
JOYSTICK_SIZE, 0, // wMaxPacketSize
|
||||||
JOYSTICK_INTERVAL, // bInterval
|
JOYSTICK_INTERVAL, // bInterval
|
||||||
|
#else
|
||||||
|
#define JOYSTICK_DESC_TOTAL_OFFSET (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
// --- 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
|
|
||||||
};
|
};
|
||||||
|
|
||||||
uint8_t *usb_bMaxPower = &config_descriptor[8];
|
uint8_t *usb_bMaxPower = &config_descriptor[8];
|
||||||
@ -731,18 +854,37 @@ struct usb_string_descriptor_struct string0 = {
|
|||||||
usb_string_descriptor( usb_string_manufacturer_name_default, STR_MANUFACTURER );
|
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_product_name_default, STR_PRODUCT );
|
||||||
usb_string_descriptor( usb_string_serial_number_default, STR_SERIAL );
|
usb_string_descriptor( usb_string_serial_number_default, STR_SERIAL );
|
||||||
|
|
||||||
|
#if enableKeyboard_define == 1
|
||||||
usb_string_descriptor( usb_string_keyboard_name, KEYBOARD_NAME );
|
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_nkro_keyboard_name, NKRO_KEYBOARD_NAME );
|
||||||
|
usb_string_descriptor( usb_string_sys_ctrl_name, SYS_CTRL_NAME );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if enableVirtualSerialPort_define == 1
|
||||||
usb_string_descriptor( usb_string_cdc_status_name, CDC_STATUS_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_cdc_data_name, CDC_DATA_NAME );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if enableRawIO_define == 1
|
||||||
|
usb_string_descriptor( usb_string_rawio_name, RAWIO_NAME );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if enableMouse_define == 1
|
||||||
usb_string_descriptor( usb_string_mouse_name, MOUSE_NAME );
|
usb_string_descriptor( usb_string_mouse_name, MOUSE_NAME );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if enableJoystick_define == 1
|
||||||
usb_string_descriptor( usb_string_joystick_name, JOYSTICK_NAME );
|
usb_string_descriptor( usb_string_joystick_name, JOYSTICK_NAME );
|
||||||
usb_string_descriptor( usb_string_sys_ctrl_name, SYS_CTRL_NAME );
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ----- Descriptors List -----
|
// ----- Descriptors List -----
|
||||||
|
|
||||||
|
#define iInterfaceString(num, var) \
|
||||||
|
{0x0300 + 4 + num, 0x0409, (const uint8_t *)&var, 0 }
|
||||||
|
|
||||||
// This table provides access to all the descriptor data above.
|
// This table provides access to all the descriptor data above.
|
||||||
|
|
||||||
const usb_descriptor_list_t usb_descriptor_list[] = {
|
const usb_descriptor_list_t usb_descriptor_list[] = {
|
||||||
@ -752,38 +894,57 @@ const usb_descriptor_list_t usb_descriptor_list[] = {
|
|||||||
{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)},
|
|
||||||
{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},
|
|
||||||
|
|
||||||
{0x2200, MOUSE_INTERFACE, mouse_report_desc, sizeof(mouse_report_desc)},
|
|
||||||
{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},
|
||||||
|
|
||||||
|
#if enableKeyboard_define == 1
|
||||||
|
{0x2200, KEYBOARD_INTERFACE, keyboard_report_desc, sizeof(keyboard_report_desc)},
|
||||||
|
{0x2100, KEYBOARD_INTERFACE, config_descriptor + KEYBOARD_DESC_BASE_OFFSET, 9},
|
||||||
|
|
||||||
|
{0x2200, NKRO_KEYBOARD_INTERFACE, nkro_keyboard_report_desc, sizeof(nkro_keyboard_report_desc)},
|
||||||
|
{0x2100, NKRO_KEYBOARD_INTERFACE, config_descriptor + NKRO_KEYBOARD_DESC_BASE_OFFSET, 9},
|
||||||
|
|
||||||
|
{0x2200, SYS_CTRL_INTERFACE, sys_ctrl_report_desc, sizeof(sys_ctrl_report_desc)},
|
||||||
|
{0x2100, SYS_CTRL_INTERFACE, config_descriptor + SYS_CTRL_DESC_BASE_OFFSET, 9},
|
||||||
|
|
||||||
iInterfaceString( KEYBOARD_INTERFACE, usb_string_keyboard_name ),
|
iInterfaceString( KEYBOARD_INTERFACE, usb_string_keyboard_name ),
|
||||||
iInterfaceString( NKRO_KEYBOARD_INTERFACE, usb_string_nkro_keyboard_name ),
|
iInterfaceString( NKRO_KEYBOARD_INTERFACE, usb_string_nkro_keyboard_name ),
|
||||||
|
iInterfaceString( SYS_CTRL_INTERFACE, usb_string_sys_ctrl_name ),
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if enableVirtualSerialPort_define == 1
|
||||||
iInterfaceString( CDC_STATUS_INTERFACE, usb_string_cdc_status_name ),
|
iInterfaceString( CDC_STATUS_INTERFACE, usb_string_cdc_status_name ),
|
||||||
iInterfaceString( CDC_DATA_INTERFACE, usb_string_cdc_data_name ),
|
iInterfaceString( CDC_DATA_INTERFACE, usb_string_cdc_data_name ),
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if enableRawIO_define == 1
|
||||||
|
iInterfaceString( RAWIO_INTERFACE, usb_string_rawio_name ),
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if enableMouse_define == 1
|
||||||
|
{0x2200, MOUSE_INTERFACE, mouse_report_desc, sizeof(mouse_report_desc)},
|
||||||
|
{0x2100, MOUSE_INTERFACE, config_descriptor + MOUSE_DESC_BASE_OFFSET, 9},
|
||||||
iInterfaceString( MOUSE_INTERFACE, usb_string_mouse_name ),
|
iInterfaceString( MOUSE_INTERFACE, usb_string_mouse_name ),
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if enableJoystick_define == 1
|
||||||
|
{0x2200, JOYSTICK_INTERFACE, joystick_report_desc, sizeof(joystick_report_desc)},
|
||||||
|
{0x2100, JOYSTICK_INTERFACE, config_descriptor + JOYSTICK_DESC_BASE_OFFSET, 9},
|
||||||
iInterfaceString( JOYSTICK_INTERFACE, usb_string_joystick_name ),
|
iInterfaceString( JOYSTICK_INTERFACE, usb_string_joystick_name ),
|
||||||
iInterfaceString( SYS_CTRL_INTERFACE, usb_string_sys_ctrl_name ),
|
#endif
|
||||||
|
|
||||||
{0, 0, NULL, 0}
|
{0, 0, NULL, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Simplifies defines for USB descriptors
|
||||||
|
void usb_set_config_descriptor_size()
|
||||||
|
{
|
||||||
|
config_descriptor[2] = LSB( sizeof( config_descriptor ) );
|
||||||
|
config_descriptor[3] = MSB( sizeof( config_descriptor ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ----- Endpoint Configuration -----
|
// ----- Endpoint Configuration -----
|
||||||
|
@ -54,9 +54,18 @@
|
|||||||
#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 8
|
#define NUM_ENDPOINTS 10 // XXX Can save some space if this can be calculated using KLL
|
||||||
#define NUM_USB_BUFFERS 30
|
#define NUM_USB_BUFFERS 30
|
||||||
#define NUM_INTERFACE 7
|
|
||||||
|
// XXX Remember to update total interface count, if it isn't correct some OSs will not initialize USB
|
||||||
|
// Linux warns in dmesg
|
||||||
|
// Mac OSX login screen will not initialize
|
||||||
|
#define KEYBOARD_INTERFACES 3 // Boot, NKRO, SysCtrl
|
||||||
|
#define CDC_INTERFACES 2
|
||||||
|
#define MOUSE_INTERFACES 1
|
||||||
|
#define JOYSTICK_INTERFACES 1
|
||||||
|
#define RAWIO_INTERFACES 1
|
||||||
|
|
||||||
|
|
||||||
#define KEYBOARD_INTERFACE 0 // Keyboard
|
#define KEYBOARD_INTERFACE 0 // Keyboard
|
||||||
#define KEYBOARD_ENDPOINT 1
|
#define KEYBOARD_ENDPOINT 1
|
||||||
@ -70,52 +79,97 @@
|
|||||||
#define NKRO_KEYBOARD_INTERVAL 1
|
#define NKRO_KEYBOARD_INTERVAL 1
|
||||||
#define NKRO_KEYBOARD_NAME L"NKRO Keyboard"
|
#define NKRO_KEYBOARD_NAME L"NKRO Keyboard"
|
||||||
|
|
||||||
|
#define SYS_CTRL_INTERFACE 2 // Media Keys
|
||||||
|
#define SYS_CTRL_ENDPOINT 3
|
||||||
|
#define SYS_CTRL_SIZE 8
|
||||||
|
#define SYS_CTRL_INTERVAL 1
|
||||||
|
#define SYS_CTRL_NAME L"Media Keys"
|
||||||
|
|
||||||
#define CDC_IAD_DESCRIPTOR 1
|
#define CDC_IAD_DESCRIPTOR 1
|
||||||
#define CDC_STATUS_INTERFACE 2
|
#define CDC_STATUS_INTERFACE 3
|
||||||
#define CDC_DATA_INTERFACE 3 // Serial
|
#define CDC_DATA_INTERFACE 4 // Serial
|
||||||
#define CDC_ACM_ENDPOINT 3
|
#define CDC_ACM_ENDPOINT 4
|
||||||
#define CDC_RX_ENDPOINT 4
|
#define CDC_RX_ENDPOINT 5
|
||||||
#define CDC_TX_ENDPOINT 5
|
#define CDC_TX_ENDPOINT 6
|
||||||
#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_STATUS_NAME L"Virtual Serial Port - Status"
|
||||||
#define CDC_DATA_NAME L"Virtual Serial Port - Data"
|
#define CDC_DATA_NAME L"Virtual Serial Port - Data"
|
||||||
|
|
||||||
#define MOUSE_INTERFACE 4 // Mouse
|
#define RAWIO_INTERFACE 5 // RawIO
|
||||||
#define MOUSE_ENDPOINT 6
|
#define RAWIO_TX_ENDPOINT 7
|
||||||
|
#define RAWIO_TX_SIZE 64
|
||||||
|
#define RAWIO_TX_INTERVAL 1
|
||||||
|
#define RAWIO_RX_ENDPOINT 8
|
||||||
|
#define RAWIO_RX_SIZE 64
|
||||||
|
#define RAWIO_RX_INTERVAL 1
|
||||||
|
#define RAWIO_NAME L"API Interface"
|
||||||
|
|
||||||
|
#define MOUSE_INTERFACE 6 // Mouse
|
||||||
|
#define MOUSE_ENDPOINT 9
|
||||||
#define MOUSE_SIZE 8
|
#define MOUSE_SIZE 8
|
||||||
#define MOUSE_INTERVAL 1
|
#define MOUSE_INTERVAL 1
|
||||||
#define MOUSE_NAME L"Mouse"
|
#define MOUSE_NAME L"Mouse"
|
||||||
|
|
||||||
#define JOYSTICK_INTERFACE 5 // Joystick
|
#define JOYSTICK_INTERFACE 7 // Joystick
|
||||||
#define JOYSTICK_ENDPOINT 7
|
#define JOYSTICK_ENDPOINT 10
|
||||||
#define JOYSTICK_SIZE 16
|
#define JOYSTICK_SIZE 16
|
||||||
#define JOYSTICK_INTERVAL 1
|
#define JOYSTICK_INTERVAL 1
|
||||||
#define JOYSTICK_NAME L"Joystick"
|
#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)
|
// Descriptor sizes
|
||||||
#define NKRO_KEYBOARD_DESC_OFFSET (9 + 9+9+7 + 9)
|
#define BASE_DESC_SIZE (9)
|
||||||
#define SERIAL_CDC_DESC_OFFSET (9 + 9+9+7 + 9+9+7 + 8)
|
#define KEYBOARD_DESC_SIZE (9+9+7)
|
||||||
#define MOUSE_DESC_OFFSET (9 + 9+9+7 + 9+9+7 + 8+9+5+5+4+5+7+9+7+7 + 9)
|
#define NKRO_KEYBOARD_DESC_SIZE (9+9+7)
|
||||||
#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_SIZE (9+9+7)
|
||||||
#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 SERIAL_CDC_DESC_SIZE (8+9+5+5+4+5+7+9+7+7)
|
||||||
#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 RAWIO_DESC_SIZE (9+7+7)
|
||||||
|
#define MOUSE_DESC_SIZE (9+9+7)
|
||||||
|
#define JOYSTICK_DESC_SIZE (9+9+7)
|
||||||
|
|
||||||
|
// Descriptor offsets
|
||||||
|
#define KEYBOARD_DESC_BASE_OFFSET ( \
|
||||||
|
BASE_DESC_SIZE + \
|
||||||
|
9 \
|
||||||
|
)
|
||||||
|
#define SERIAL_CDC_DESC_BASE_OFFSET ( \
|
||||||
|
BASE_DESC_SIZE + \
|
||||||
|
KEYBOARD_DESC_TOTAL_OFFSET + \
|
||||||
|
8 \
|
||||||
|
)
|
||||||
|
#define RAWIO_DESC_BASE_OFFSET ( \
|
||||||
|
BASE_DESC_SIZE + \
|
||||||
|
KEYBOARD_DESC_TOTAL_OFFSET + \
|
||||||
|
SERIAL_CDC_DESC_TOTAL_OFFSET + \
|
||||||
|
9 \
|
||||||
|
)
|
||||||
|
#define MOUSE_DESC_BASE_OFFSET ( \
|
||||||
|
BASE_DESC_SIZE + \
|
||||||
|
KEYBOARD_DESC_TOTAL_OFFSET + \
|
||||||
|
SERIAL_CDC_DESC_TOTAL_OFFSET + \
|
||||||
|
9 \
|
||||||
|
)
|
||||||
|
#define JOYSTICK_DESC_BASE_OFFSET ( \
|
||||||
|
BASE_DESC_SIZE + \
|
||||||
|
KEYBOARD_DESC_TOTAL_OFFSET + \
|
||||||
|
SERIAL_CDC_DESC_TOTAL_OFFSET + \
|
||||||
|
MOUSE_DESC_TOTAL_OFFSET + \
|
||||||
|
9 \
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
#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 ENDPOINT3_CONFIG ENDPOINT_TRANSIMIT_ONLY
|
#define ENDPOINT3_CONFIG ENDPOINT_TRANSIMIT_ONLY
|
||||||
#define ENDPOINT4_CONFIG ENDPOINT_RECEIVE_ONLY
|
#define ENDPOINT4_CONFIG ENDPOINT_TRANSIMIT_ONLY
|
||||||
#define ENDPOINT5_CONFIG ENDPOINT_TRANSIMIT_ONLY
|
#define ENDPOINT5_CONFIG ENDPOINT_RECEIVE_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
|
#define ENDPOINT8_CONFIG ENDPOINT_RECEIVE_ONLY
|
||||||
|
#define ENDPOINT9_CONFIG ENDPOINT_TRANSIMIT_ONLY
|
||||||
|
#define ENDPOINT10_CONFIG ENDPOINT_TRANSIMIT_ONLY
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -139,3 +193,8 @@ extern const usb_descriptor_list_t usb_descriptor_list[];
|
|||||||
|
|
||||||
extern uint8_t *usb_bMaxPower;
|
extern uint8_t *usb_bMaxPower;
|
||||||
|
|
||||||
|
|
||||||
|
// ----- Functions -----
|
||||||
|
|
||||||
|
void usb_set_config_descriptor_size();
|
||||||
|
|
||||||
|
@ -40,6 +40,10 @@
|
|||||||
#include "usb_dev.h"
|
#include "usb_dev.h"
|
||||||
#include "usb_mem.h"
|
#include "usb_mem.h"
|
||||||
|
|
||||||
|
#if enableVirtualSerialPort_define == 1
|
||||||
|
#include "usb_serial.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ----- Defines -----
|
// ----- Defines -----
|
||||||
@ -180,7 +184,10 @@ static uint8_t usb_dev_sleep = 0;
|
|||||||
static void endpoint0_stall()
|
static void endpoint0_stall()
|
||||||
{
|
{
|
||||||
#ifdef UART_DEBUG_UNKNOWN
|
#ifdef UART_DEBUG_UNKNOWN
|
||||||
print("STALL" NL );
|
print("STALL : ");
|
||||||
|
printInt32( systick_millis_count - USBInit_TimeStart );
|
||||||
|
print(" ms");
|
||||||
|
print(NL);
|
||||||
#endif
|
#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;
|
||||||
}
|
}
|
||||||
@ -195,7 +202,6 @@ static void endpoint0_transmit( const void *data, uint32_t len )
|
|||||||
|
|
||||||
void usb_reinit()
|
void usb_reinit()
|
||||||
{
|
{
|
||||||
power_neg_delay = 0;
|
|
||||||
usb_configuration = 0; // Clear USB configuration if we have one
|
usb_configuration = 0; // Clear USB configuration if we have one
|
||||||
USB0_CONTROL = 0; // Disable D+ Pullup to simulate disconnect
|
USB0_CONTROL = 0; // Disable D+ Pullup to simulate disconnect
|
||||||
delay(10); // Delay is necessary to simulate disconnect
|
delay(10); // Delay is necessary to simulate disconnect
|
||||||
@ -213,6 +219,18 @@ void usb_device_check()
|
|||||||
// Check if 100 ms has elapsed
|
// Check if 100 ms has elapsed
|
||||||
if ( systick_millis_count - power_neg_time > 100 )
|
if ( systick_millis_count - power_neg_time > 100 )
|
||||||
{
|
{
|
||||||
|
power_neg_delay = 0;
|
||||||
|
|
||||||
|
// USB Low Power Negotiation
|
||||||
|
#if enableUSBLowPowerNegotiation_define == 1
|
||||||
|
// Check to see if bMaxPower has already be lowered
|
||||||
|
// This generally points to a USB bug (host or device?)
|
||||||
|
if ( *usb_bMaxPower == 50 )
|
||||||
|
{
|
||||||
|
warn_msg("Power negotiation delay detected again, likely a system/device USB bug");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Update bMaxPower
|
// Update bMaxPower
|
||||||
// The value set is in increments of 2 mA
|
// The value set is in increments of 2 mA
|
||||||
// So 50 * 2 mA = 100 mA
|
// So 50 * 2 mA = 100 mA
|
||||||
@ -222,6 +240,9 @@ void usb_device_check()
|
|||||||
|
|
||||||
// Re-initialize USB
|
// Re-initialize USB
|
||||||
usb_reinit();
|
usb_reinit();
|
||||||
|
#else
|
||||||
|
warn_msg("USB Low Power Negotation Disabled, condition detected.");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -237,6 +258,10 @@ static void usb_setup()
|
|||||||
const uint8_t *cfg;
|
const uint8_t *cfg;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
// Reset USB Init timer
|
||||||
|
USBInit_TimeEnd = systick_millis_count;
|
||||||
|
USBInit_Ticks++;
|
||||||
|
|
||||||
// If another request is made, disable the power negotiation check
|
// If another request is made, disable the power negotiation check
|
||||||
// See GET_DESCRIPTOR - Configuration
|
// See GET_DESCRIPTOR - Configuration
|
||||||
if ( power_neg_delay )
|
if ( power_neg_delay )
|
||||||
@ -517,22 +542,40 @@ static void usb_setup()
|
|||||||
endpoint0_stall();
|
endpoint0_stall();
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
#if enableVirtualSerialPort_define == 1
|
||||||
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");
|
//info_print("set control line state");
|
||||||
goto send;
|
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;
|
||||||
datalen = sizeof( usb_cdc_line_coding );
|
datalen = sizeof( usb_cdc_line_coding );
|
||||||
goto send;
|
goto send;
|
||||||
|
|
||||||
case 0x2021: // CDC_SET_LINE_CODING
|
case 0x2021: // CDC_SET_LINE_CODING
|
||||||
// XXX Needed?
|
// ZLP Reply
|
||||||
//serial_print("set coding, waiting...\n");
|
// Settings are applied in PID=OUT
|
||||||
return;
|
goto send;
|
||||||
|
#endif
|
||||||
|
|
||||||
case 0x0921: // HID SET_REPORT
|
case 0x0921: // HID SET_REPORT
|
||||||
|
// ZLP Reply
|
||||||
|
// Settings are applied in PID=OUT
|
||||||
|
|
||||||
|
#ifdef UART_DEBUG
|
||||||
|
print("report_type(");
|
||||||
|
printHex( setup.wValue >> 8 );
|
||||||
|
print(")report_id(");
|
||||||
|
printHex( setup.wValue & 0xFF );
|
||||||
|
print(")interface(");
|
||||||
|
printHex( setup.wIndex );
|
||||||
|
print(")len(");
|
||||||
|
printHex( setup.wLength );
|
||||||
|
print(")");
|
||||||
|
print( NL );
|
||||||
|
#endif
|
||||||
|
|
||||||
// Interface
|
// Interface
|
||||||
switch ( setup.wIndex & 0xFF )
|
switch ( setup.wIndex & 0xFF )
|
||||||
{
|
{
|
||||||
@ -547,7 +590,7 @@ static void usb_setup()
|
|||||||
printHex( setup.wIndex );
|
printHex( setup.wIndex );
|
||||||
print( NL );
|
print( NL );
|
||||||
endpoint0_stall();
|
endpoint0_stall();
|
||||||
break;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
goto send;
|
goto send;
|
||||||
@ -596,6 +639,7 @@ static void usb_setup()
|
|||||||
print(NL);
|
print(NL);
|
||||||
#endif
|
#endif
|
||||||
reply_buffer[0] = USBKeys_Idle_Config;
|
reply_buffer[0] = USBKeys_Idle_Config;
|
||||||
|
data = reply_buffer;
|
||||||
datalen = 1;
|
datalen = 1;
|
||||||
goto send;
|
goto send;
|
||||||
|
|
||||||
@ -620,13 +664,16 @@ static void usb_setup()
|
|||||||
print(NL);
|
print(NL);
|
||||||
#endif
|
#endif
|
||||||
reply_buffer[0] = USBKeys_Protocol;
|
reply_buffer[0] = USBKeys_Protocol;
|
||||||
|
data = reply_buffer;
|
||||||
datalen = 1;
|
datalen = 1;
|
||||||
goto send;
|
goto send;
|
||||||
|
|
||||||
// case 0xC940:
|
// case 0xC940:
|
||||||
default:
|
default:
|
||||||
#ifdef UART_DEBUG_UNKNOWN
|
#ifdef UART_DEBUG_UNKNOWN
|
||||||
print("UNKNOWN");
|
print("UNKNOWN: ");
|
||||||
|
printInt32( systick_millis_count - USBInit_TimeStart );
|
||||||
|
print(" ms");
|
||||||
print(NL);
|
print(NL);
|
||||||
#endif
|
#endif
|
||||||
endpoint0_stall();
|
endpoint0_stall();
|
||||||
@ -717,8 +764,6 @@ static void usb_control( uint32_t stat )
|
|||||||
switch ( pid )
|
switch ( pid )
|
||||||
{
|
{
|
||||||
case 0x0D: // Setup received from host
|
case 0x0D: // Setup received from host
|
||||||
//serial_print("PID=Setup\n");
|
|
||||||
//if (count != 8) ; // panic?
|
|
||||||
// grab the 8 byte setup info
|
// grab the 8 byte setup info
|
||||||
setup.word1 = *(uint32_t *)(buf);
|
setup.word1 = *(uint32_t *)(buf);
|
||||||
setup.word2 = *(uint32_t *)(buf + 4);
|
setup.word2 = *(uint32_t *)(buf + 4);
|
||||||
@ -741,14 +786,14 @@ static void usb_control( uint32_t stat )
|
|||||||
//}
|
//}
|
||||||
table[index(0, TX, EVEN)].desc = 0;
|
table[index(0, TX, EVEN)].desc = 0;
|
||||||
table[index(0, TX, ODD)].desc = 0;
|
table[index(0, TX, ODD)].desc = 0;
|
||||||
|
|
||||||
// first IN after Setup is always DATA1
|
// first IN after Setup is always DATA1
|
||||||
ep0_tx_data_toggle = 1;
|
ep0_tx_data_toggle = 1;
|
||||||
|
|
||||||
#ifdef UART_DEBUG_UNKNOWN
|
#ifdef UART_DEBUG_UNKNOWN
|
||||||
print("bmRequestType:");
|
printHex( stat );
|
||||||
printHex(setup.bmRequestType);
|
print(" PID=SETUP wRequestAndType:");
|
||||||
print(", bRequest:");
|
printHex(setup.wRequestAndType);
|
||||||
printHex(setup.bRequest);
|
|
||||||
print(", wValue:");
|
print(", wValue:");
|
||||||
printHex(setup.wValue);
|
printHex(setup.wValue);
|
||||||
print(", wIndex:");
|
print(", wIndex:");
|
||||||
@ -759,8 +804,12 @@ static void usb_control( uint32_t stat )
|
|||||||
printHex32(setup.word1);
|
printHex32(setup.word1);
|
||||||
print(" ");
|
print(" ");
|
||||||
printHex32(setup.word2);
|
printHex32(setup.word2);
|
||||||
|
print(": ");
|
||||||
|
printInt32( systick_millis_count - USBInit_TimeStart );
|
||||||
|
print(" ms");
|
||||||
print(NL);
|
print(NL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// actually "do" the setup request
|
// actually "do" the setup request
|
||||||
usb_setup();
|
usb_setup();
|
||||||
// unfreeze the USB, now that we're ready
|
// unfreeze the USB, now that we're ready
|
||||||
@ -770,6 +819,7 @@ static void usb_control( uint32_t stat )
|
|||||||
case 0x01: // OUT transaction received from host
|
case 0x01: // OUT transaction received from host
|
||||||
case 0x02:
|
case 0x02:
|
||||||
#ifdef UART_DEBUG_UNKNOWN
|
#ifdef UART_DEBUG_UNKNOWN
|
||||||
|
printHex( stat );
|
||||||
print(" PID=OUT wRequestAndType:");
|
print(" PID=OUT wRequestAndType:");
|
||||||
printHex(setup.wRequestAndType);
|
printHex(setup.wRequestAndType);
|
||||||
print(", wValue:");
|
print(", wValue:");
|
||||||
@ -782,43 +832,77 @@ static void usb_control( uint32_t stat )
|
|||||||
printHex32(setup.word1);
|
printHex32(setup.word1);
|
||||||
print(" ");
|
print(" ");
|
||||||
printHex32(setup.word2);
|
printHex32(setup.word2);
|
||||||
|
print(": ");
|
||||||
|
printInt32( systick_millis_count - USBInit_TimeStart );
|
||||||
|
print(" ms");
|
||||||
print(NL);
|
print(NL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// CDC Interface
|
// CDC Interface
|
||||||
if ( setup.wRequestAndType == 0x2021 /*CDC_SET_LINE_CODING*/ )
|
#if enableVirtualSerialPort_define == 1
|
||||||
|
// CDC_SET_LINE_CODING - PID=OUT
|
||||||
|
// XXX - Getting lots of NAKs in Linux
|
||||||
|
if ( setup.wRequestAndType == 0x2021 )
|
||||||
{
|
{
|
||||||
int i;
|
// Copy over new line coding
|
||||||
uint8_t *dst = (uint8_t *)usb_cdc_line_coding;
|
memcpy( (void*)&usb_cdc_line_coding, buf, 7 );
|
||||||
//serial_print("set line coding ");
|
|
||||||
for ( i = 0; i < 7; i++ )
|
|
||||||
{
|
|
||||||
//serial_phex(*buf);
|
|
||||||
*dst++ = *buf++;
|
|
||||||
}
|
|
||||||
//serial_phex32(usb_cdc_line_coding[0]);
|
|
||||||
//serial_print("\n");
|
|
||||||
if ( usb_cdc_line_coding[0] == 134 )
|
|
||||||
usb_reboot_timer = 15;
|
|
||||||
endpoint0_transmit( NULL, 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keyboard SET_REPORT
|
#ifdef UART_DEBUG
|
||||||
if ( setup.wRequestAndType == 0x921 && setup.wValue & 0x200 )
|
// - Unused, but for the readers info -
|
||||||
|
print("dwDTERate(");
|
||||||
|
printInt32( usb_cdc_line_coding.dwDTERate );
|
||||||
|
print(")bCharFormat(");
|
||||||
|
printHex( usb_cdc_line_coding.bCharFormat );
|
||||||
|
print(")bParityType(");
|
||||||
|
printHex( usb_cdc_line_coding.bParityType );
|
||||||
|
print(")bDataBits(");
|
||||||
|
printHex( usb_cdc_line_coding.bDataBits );
|
||||||
|
print(")");
|
||||||
|
print( NL );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// XXX ZLP causes timeout/delay, why? -HaaTa
|
||||||
|
//endpoint0_transmit( NULL, 0 );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Keyboard HID SET_REPORT - PID=OUT
|
||||||
|
#if enableKeyboard_define == 1
|
||||||
|
// XXX - Getting lots of NAKs in Linux
|
||||||
|
if ( setup.wRequestAndType == 0x0921 && setup.wValue & 0x200 )
|
||||||
{
|
{
|
||||||
|
#ifdef UART_DEBUG
|
||||||
|
print("report_type(");
|
||||||
|
printHex( setup.wValue >> 8 );
|
||||||
|
print(")report_id(");
|
||||||
|
printHex( setup.wValue & 0xFF );
|
||||||
|
print(")interface(");
|
||||||
|
printHex( setup.wIndex );
|
||||||
|
print(")len(");
|
||||||
|
printHex( setup.wLength );
|
||||||
|
print(")[");
|
||||||
|
|
||||||
|
for ( size_t len = 0; len < setup.wLength; len++ )
|
||||||
|
{
|
||||||
|
printHex( buf[ len ] );
|
||||||
|
print(" ");
|
||||||
|
}
|
||||||
|
print("]");
|
||||||
|
print( NL );
|
||||||
|
#endif
|
||||||
|
|
||||||
// Interface
|
// Interface
|
||||||
switch ( setup.wIndex & 0xFF )
|
switch ( setup.wIndex & 0xFF )
|
||||||
{
|
{
|
||||||
// Keyboard Interface
|
// Keyboard Interface
|
||||||
case KEYBOARD_INTERFACE:
|
case KEYBOARD_INTERFACE:
|
||||||
USBKeys_LEDs = buf[0];
|
USBKeys_LEDs = buf[0];
|
||||||
endpoint0_transmit( NULL, 0 );
|
|
||||||
break;
|
break;
|
||||||
// NKRO Keyboard Interface
|
// NKRO Keyboard Interface
|
||||||
case NKRO_KEYBOARD_INTERFACE:
|
case NKRO_KEYBOARD_INTERFACE:
|
||||||
|
// Already set with the control sequence
|
||||||
// Only use 2nd byte, first byte is the report id
|
// Only use 2nd byte, first byte is the report id
|
||||||
USBKeys_LEDs = buf[1];
|
USBKeys_LEDs = buf[1];
|
||||||
endpoint0_transmit( NULL, 0 );
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
warn_msg("Unknown interface - ");
|
warn_msg("Unknown interface - ");
|
||||||
@ -827,33 +911,47 @@ static void usb_control( uint32_t stat )
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef UART_DEBUG
|
// XXX ZLP causes timeout/delay, why? -HaaTa
|
||||||
for ( size_t len = 0; len < setup.wLength; len++ )
|
//endpoint0_transmit( NULL, 0 );
|
||||||
{
|
|
||||||
printHex( buf[ len ] );
|
|
||||||
print(" ");
|
|
||||||
}
|
}
|
||||||
print( NL );
|
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
// give the buffer back
|
// give the buffer back
|
||||||
b->desc = BDT_DESC( EP0_SIZE, DATA1 );
|
b->desc = BDT_DESC( EP0_SIZE, DATA1 );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x09: // IN transaction completed to host
|
case 0x09: // IN transaction completed to host
|
||||||
#ifdef UART_DEBUG
|
data = ep0_tx_ptr;
|
||||||
print("PID=IN:");
|
|
||||||
|
#ifdef UART_DEBUG_UNKNOWN
|
||||||
printHex( stat );
|
printHex( stat );
|
||||||
|
print(" PID=IN wRequestAndType:");
|
||||||
|
printHex(setup.wRequestAndType);
|
||||||
|
print(", wValue:");
|
||||||
|
printHex(setup.wValue);
|
||||||
|
print(", wIndex:");
|
||||||
|
printHex(setup.wIndex);
|
||||||
|
print(", len:");
|
||||||
|
printHex(setup.wLength);
|
||||||
|
print(" -- ");
|
||||||
|
printHex32(setup.word1);
|
||||||
|
print(" ");
|
||||||
|
printHex32(setup.word2);
|
||||||
|
print(": ");
|
||||||
|
printInt32( systick_millis_count - USBInit_TimeStart );
|
||||||
|
print(" ms");
|
||||||
|
if ( data ) print(" DATA ");
|
||||||
print(NL);
|
print(NL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// send remaining data, if any...
|
// send remaining data, if any...
|
||||||
data = ep0_tx_ptr;
|
|
||||||
if ( data )
|
if ( data )
|
||||||
{
|
{
|
||||||
size = ep0_tx_len;
|
size = ep0_tx_len;
|
||||||
if (size > EP0_SIZE) size = EP0_SIZE;
|
if (size > EP0_SIZE)
|
||||||
|
{
|
||||||
|
size = EP0_SIZE;
|
||||||
|
}
|
||||||
endpoint0_transmit( data, size );
|
endpoint0_transmit( data, size );
|
||||||
data += size;
|
data += size;
|
||||||
ep0_tx_len -= size;
|
ep0_tx_len -= size;
|
||||||
@ -871,12 +969,34 @@ static void usb_control( uint32_t stat )
|
|||||||
USB0_ADDR = setup.wValue;
|
USB0_ADDR = setup.wValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CDC_SET_LINE_CODING - PID=IN
|
||||||
|
#if enableVirtualSerialPort_define == 1
|
||||||
|
if ( setup.wRequestAndType == 0x2021 )
|
||||||
|
{
|
||||||
|
// XXX ZLP causes timeout/delay, why? -HaaTa
|
||||||
|
//endpoint0_transmit( NULL, 0 );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Keyboard HID SET_REPORT - PID=IN
|
||||||
|
#if enableKeyboard_define == 1
|
||||||
|
// XXX - Getting lots of NAKs in Linux
|
||||||
|
if ( setup.wRequestAndType == 0x0921 && setup.wValue & 0x200 )
|
||||||
|
{
|
||||||
|
// XXX ZLP causes timeout/delay, why? -HaaTa
|
||||||
|
//endpoint0_transmit( NULL, 0 );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
#ifdef UART_DEBUG
|
#ifdef UART_DEBUG_UNKNOWN
|
||||||
print("PID=unknown: ");
|
print("PID=unknown: ");
|
||||||
printHex(pid);
|
printHex(pid);
|
||||||
|
print(": ");
|
||||||
|
printInt32( systick_millis_count - USBInit_TimeStart );
|
||||||
|
print(" ms");
|
||||||
print(NL);
|
print(NL);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
@ -889,14 +1009,25 @@ usb_packet_t *usb_rx( uint32_t endpoint )
|
|||||||
//print("USB RX");
|
//print("USB RX");
|
||||||
usb_packet_t *ret;
|
usb_packet_t *ret;
|
||||||
endpoint--;
|
endpoint--;
|
||||||
|
|
||||||
|
// Make sure this is a valid endpoint
|
||||||
if ( endpoint >= NUM_ENDPOINTS )
|
if ( endpoint >= NUM_ENDPOINTS )
|
||||||
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
__disable_irq();
|
__disable_irq();
|
||||||
|
|
||||||
|
// Receive packet, check pointer
|
||||||
ret = rx_first[endpoint];
|
ret = rx_first[endpoint];
|
||||||
if ( ret )
|
if ( ret )
|
||||||
|
{
|
||||||
rx_first[ endpoint ] = ret->next;
|
rx_first[ endpoint ] = ret->next;
|
||||||
usb_rx_byte_count_data[ endpoint ] -= ret->len;
|
usb_rx_byte_count_data[ endpoint ] -= ret->len;
|
||||||
|
}
|
||||||
|
|
||||||
__enable_irq();
|
__enable_irq();
|
||||||
|
|
||||||
//serial_print("rx, epidx=");
|
//serial_print("rx, epidx=");
|
||||||
//serial_phex(endpoint);
|
//serial_phex(endpoint);
|
||||||
//serial_print(", packet=");
|
//serial_print(", packet=");
|
||||||
@ -994,17 +1125,16 @@ void usb_rx_memory( usb_packet_t *packet )
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//#define index(endpoint, tx, odd) (((endpoint) << 2) | ((tx) << 1) | (odd))
|
// Call whenever there's an action that may wake the host device
|
||||||
//#define stat2bufferdescriptor(stat) (table + ((stat) >> 2))
|
void usb_resume()
|
||||||
|
|
||||||
void usb_tx( uint32_t endpoint, usb_packet_t *packet )
|
|
||||||
{
|
{
|
||||||
// Update expiry counter
|
|
||||||
USBKeys_Idle_Expiry = systick_millis_count;
|
|
||||||
|
|
||||||
// If we have been sleeping, try to wake up host
|
// If we have been sleeping, try to wake up host
|
||||||
if ( usb_dev_sleep )
|
if ( usb_dev_sleep && usb_configured() )
|
||||||
{
|
{
|
||||||
|
#if enableUSBResume_define == 1
|
||||||
|
#if enableVirtualSerialPort_define != 1
|
||||||
|
info_print("Attempting to resume the host");
|
||||||
|
#endif
|
||||||
// Force wake-up for 10 ms
|
// Force wake-up for 10 ms
|
||||||
// According to the USB Spec a device must hold resume for at least 1 ms but no more than 15 ms
|
// According to the USB Spec a device must hold resume for at least 1 ms but no more than 15 ms
|
||||||
USB0_CTL |= USB_CTL_RESUME;
|
USB0_CTL |= USB_CTL_RESUME;
|
||||||
@ -1012,8 +1142,18 @@ void usb_tx( uint32_t endpoint, usb_packet_t *packet )
|
|||||||
USB0_CTL &= ~(USB_CTL_RESUME);
|
USB0_CTL &= ~(USB_CTL_RESUME);
|
||||||
delay(50); // Wait for at least 50 ms to make sure the bus is clear
|
delay(50); // Wait for at least 50 ms to make sure the bus is clear
|
||||||
usb_dev_sleep = 0; // Make sure we don't call this again, may crash system
|
usb_dev_sleep = 0; // Make sure we don't call this again, may crash system
|
||||||
|
#else
|
||||||
|
warn_print("Host Resume Disabled");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void usb_tx( uint32_t endpoint, usb_packet_t *packet )
|
||||||
|
{
|
||||||
|
// Update expiry counter
|
||||||
|
USBKeys_Idle_Expiry = systick_millis_count;
|
||||||
|
|
||||||
// Since we are transmitting data, USB will be brought out of sleep/suspend
|
// Since we are transmitting data, USB will be brought out of sleep/suspend
|
||||||
// if it's in that state
|
// if it's in that state
|
||||||
// Use the currently set descriptor value
|
// Use the currently set descriptor value
|
||||||
@ -1087,16 +1227,12 @@ void usb_isr()
|
|||||||
{
|
{
|
||||||
uint8_t status, stat, t;
|
uint8_t status, stat, t;
|
||||||
|
|
||||||
//serial_print("isr");
|
|
||||||
//status = USB0_ISTAT;
|
|
||||||
//serial_phex(status);
|
|
||||||
//serial_print("\n");
|
|
||||||
restart:
|
restart:
|
||||||
status = USB0_ISTAT;
|
status = USB0_ISTAT;
|
||||||
/*
|
/*
|
||||||
print("USB ISR STATUS: ");
|
print(" ISR(");
|
||||||
printHex( status );
|
printHex( status );
|
||||||
print( NL );
|
print(") ");
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ( (status & USB_INTEN_SOFTOKEN /* 04 */ ) )
|
if ( (status & USB_INTEN_SOFTOKEN /* 04 */ ) )
|
||||||
@ -1112,6 +1248,7 @@ restart:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CDC Interface
|
// CDC Interface
|
||||||
|
#if enableVirtualSerialPort_define == 1
|
||||||
t = usb_cdc_transmit_flush_timer;
|
t = usb_cdc_transmit_flush_timer;
|
||||||
if ( t )
|
if ( t )
|
||||||
{
|
{
|
||||||
@ -1119,6 +1256,7 @@ restart:
|
|||||||
if ( t == 0 )
|
if ( t == 0 )
|
||||||
usb_serial_flush_callback();
|
usb_serial_flush_callback();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
USB0_ISTAT = USB_INTEN_SOFTOKEN;
|
USB0_ISTAT = USB_INTEN_SOFTOKEN;
|
||||||
@ -1323,16 +1461,26 @@ restart:
|
|||||||
// The USB Module triggers this interrupt when it detects the bus has been idle for 3 ms
|
// The USB Module triggers this interrupt when it detects the bus has been idle for 3 ms
|
||||||
if ( (status & USB_ISTAT_SLEEP /* 10 */ ) )
|
if ( (status & USB_ISTAT_SLEEP /* 10 */ ) )
|
||||||
{
|
{
|
||||||
//info_print("Host has requested USB sleep/suspend state");
|
#if enableUSBSuspend_define == 1
|
||||||
|
// Can cause issues with the virtual serial port
|
||||||
|
#if enableVirtualSerialPort_define != 1
|
||||||
|
info_print("Host has requested USB sleep/suspend state");
|
||||||
|
#endif
|
||||||
Output_update_usb_current( 100 ); // Set to 100 mA
|
Output_update_usb_current( 100 ); // Set to 100 mA
|
||||||
usb_dev_sleep = 1;
|
usb_dev_sleep = 1;
|
||||||
|
#else
|
||||||
|
info_print("USB Suspend Detected - Firmware USB Suspend Disabled");
|
||||||
|
#endif
|
||||||
USB0_ISTAT |= USB_ISTAT_SLEEP;
|
USB0_ISTAT |= USB_ISTAT_SLEEP;
|
||||||
}
|
}
|
||||||
|
|
||||||
// On USB Resume, unset the usb_dev_sleep so we don't keep sending resume signals
|
// On USB Resume, unset the usb_dev_sleep so we don't keep sending resume signals
|
||||||
if ( (status & USB_ISTAT_RESUME /* 20 */ ) )
|
if ( (status & USB_ISTAT_RESUME /* 20 */ ) )
|
||||||
{
|
{
|
||||||
//info_print("Host has woken-up/resumed from sleep/suspend state");
|
// Can cause issues with the virtual serial port
|
||||||
|
#if enableVirtualSerialPort_define != 1
|
||||||
|
info_print("Host has woken-up/resumed from sleep/suspend state");
|
||||||
|
#endif
|
||||||
Output_update_usb_current( *usb_bMaxPower * 2 );
|
Output_update_usb_current( *usb_bMaxPower * 2 );
|
||||||
usb_dev_sleep = 0;
|
usb_dev_sleep = 0;
|
||||||
USB0_ISTAT |= USB_ISTAT_RESUME;
|
USB0_ISTAT |= USB_ISTAT_RESUME;
|
||||||
@ -1347,6 +1495,13 @@ uint8_t usb_init()
|
|||||||
print("USB INIT"NL);
|
print("USB INIT"NL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
USBInit_TimeStart = systick_millis_count;
|
||||||
|
USBInit_Ticks = 0;
|
||||||
|
|
||||||
|
// XXX Set wTotalLength here instead of using defines
|
||||||
|
// Simplifies defines considerably
|
||||||
|
usb_set_config_descriptor_size();
|
||||||
|
|
||||||
// Clear out endpoints table
|
// Clear out endpoints table
|
||||||
for ( int i = 0; i <= NUM_ENDPOINTS * 4; i++ )
|
for ( int i = 0; i <= NUM_ENDPOINTS * 4; i++ )
|
||||||
{
|
{
|
||||||
|
@ -51,10 +51,6 @@ extern volatile uint8_t usb_configuration;
|
|||||||
|
|
||||||
extern uint16_t usb_rx_byte_count_data[NUM_ENDPOINTS];
|
extern uint16_t usb_rx_byte_count_data[NUM_ENDPOINTS];
|
||||||
|
|
||||||
extern volatile uint8_t usb_cdc_line_coding[7];
|
|
||||||
extern volatile uint8_t usb_cdc_line_rtsdtr;
|
|
||||||
extern volatile uint8_t usb_cdc_transmit_flush_timer;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ----- Functions -----
|
// ----- Functions -----
|
||||||
@ -67,6 +63,8 @@ void usb_isr();
|
|||||||
void usb_tx( uint32_t endpoint, usb_packet_t *packet );
|
void usb_tx( uint32_t endpoint, usb_packet_t *packet );
|
||||||
void usb_tx_isr( uint32_t endpoint, usb_packet_t *packet );
|
void usb_tx_isr( uint32_t endpoint, usb_packet_t *packet );
|
||||||
|
|
||||||
|
void usb_resume();
|
||||||
|
|
||||||
uint32_t usb_tx_byte_count( uint32_t endpoint );
|
uint32_t usb_tx_byte_count( uint32_t endpoint );
|
||||||
uint32_t usb_tx_packet_count( uint32_t endpoint );
|
uint32_t usb_tx_packet_count( uint32_t endpoint );
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* 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 (2015)
|
* Modified by Jacob Alexander (2015-2016)
|
||||||
*
|
*
|
||||||
* 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
|
||||||
@ -29,6 +29,8 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#if enableJoystick_define == 1
|
||||||
|
|
||||||
// ----- Includes -----
|
// ----- Includes -----
|
||||||
|
|
||||||
// Compiler Includes
|
// Compiler Includes
|
||||||
@ -112,3 +114,5 @@ int usb_joystick_send()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* 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.
|
||||||
* Modifications by Jacob Alexander 2013-2015
|
* Modifications by Jacob Alexander 2013-2016
|
||||||
*
|
*
|
||||||
* 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
|
||||||
@ -29,6 +29,9 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <kll_defs.h>
|
||||||
|
#if enableKeyboard_define == 1
|
||||||
|
|
||||||
// ----- Includes -----
|
// ----- Includes -----
|
||||||
|
|
||||||
// Compiler Includes
|
// Compiler Includes
|
||||||
@ -123,14 +126,25 @@ void usb_keyboard_send()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// USB Timeout, drop the packet, and potentially try something more drastic to re-enable the bus
|
||||||
if ( ++wait_count > TX_TIMEOUT || transmit_previous_timeout )
|
if ( ++wait_count > TX_TIMEOUT || transmit_previous_timeout )
|
||||||
{
|
{
|
||||||
transmit_previous_timeout = 1;
|
transmit_previous_timeout = 1;
|
||||||
warn_print("USB Transmit Timeout...restarting device");
|
|
||||||
USBKeys_Changed = USBKeyChangeState_None; // Indicate packet lost
|
USBKeys_Changed = USBKeyChangeState_None; // Indicate packet lost
|
||||||
|
#if enableDeviceRestartOnUSBTimeout == 1
|
||||||
|
warn_print("USB Transmit Timeout...restarting device");
|
||||||
usb_device_software_reset();
|
usb_device_software_reset();
|
||||||
|
#else
|
||||||
|
warn_print("USB Transmit Timeout...auto-restart disabled");
|
||||||
|
#endif
|
||||||
|
// Try to wakeup
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Try to wake up the device if we can't allocate a packet for some reason
|
||||||
|
// XXX This is a bit aggressive, but seems to work well. Unfortunately, not as quick as I'd like it -HaaTa
|
||||||
|
usb_resume();
|
||||||
|
|
||||||
yield();
|
yield();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -277,3 +291,5 @@ void usb_keyboard_send()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@ -29,6 +29,9 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <kll_defs.h>
|
||||||
|
#if enableMouse_define == 1
|
||||||
|
|
||||||
// ----- Includes -----
|
// ----- Includes -----
|
||||||
|
|
||||||
// Compiler Includes
|
// Compiler Includes
|
||||||
@ -300,3 +303,5 @@ void usb_mouse_screen_size(uint16_t width, uint16_t height, uint8_t mac)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
141
Output/pjrcUSB/arm/usb_rawio.c
Normal file
141
Output/pjrcUSB/arm/usb_rawio.c
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
/* Copyright (C) 2016 by Jacob Alexander
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <kll_defs.h>
|
||||||
|
#if enableRawIO_define == 1
|
||||||
|
|
||||||
|
// ----- Includes -----
|
||||||
|
|
||||||
|
// Compiler Includes
|
||||||
|
#include <string.h> // For memcpy
|
||||||
|
|
||||||
|
// Project Includes
|
||||||
|
#include <Lib/OutputLib.h>
|
||||||
|
#include <print.h>
|
||||||
|
|
||||||
|
// Local Includes
|
||||||
|
#include "usb_dev.h"
|
||||||
|
#include "usb_rawio.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ----- Defines -----
|
||||||
|
|
||||||
|
// Maximum number of transmit packets to queue so we don't starve other endpoints for memory
|
||||||
|
#define TX_PACKET_LIMIT 5
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ----- Functions -----
|
||||||
|
|
||||||
|
// Check for packets available from host
|
||||||
|
uint32_t usb_rawio_available()
|
||||||
|
{
|
||||||
|
// Error if USB isn't configured
|
||||||
|
if ( !usb_configuration )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Query number of bytes available from the endpoint
|
||||||
|
return usb_rx_byte_count( RAWIO_RX_ENDPOINT );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve packets from host
|
||||||
|
// Always returns RAWIO_RX_SIZE
|
||||||
|
int32_t usb_rawio_rx( void *buf, uint32_t timeout )
|
||||||
|
{
|
||||||
|
usb_packet_t *rx_packet;
|
||||||
|
uint32_t begin = millis();
|
||||||
|
|
||||||
|
// Read
|
||||||
|
while ( 1 )
|
||||||
|
{
|
||||||
|
// Error if USB isn't configured
|
||||||
|
if ( !usb_configuration )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
// Retrieve packet
|
||||||
|
rx_packet = usb_rx( RAWIO_RX_ENDPOINT );
|
||||||
|
if ( rx_packet )
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Check for timeout
|
||||||
|
if ( millis() - begin > timeout || !timeout )
|
||||||
|
{
|
||||||
|
warn_msg("RAWIO Rx - Timeout, dropping packet.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
yield();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transfer packet from USB buffer to given buffer
|
||||||
|
memcpy( buf, rx_packet->buf, RAWIO_RX_SIZE );
|
||||||
|
usb_free( rx_packet );
|
||||||
|
|
||||||
|
// Data sent in full packet chunks
|
||||||
|
return RAWIO_RX_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send packet to host
|
||||||
|
// XXX Only transfers RAWIO_TX_SIZE on each call (likely 64 bytes)
|
||||||
|
// Always returns RAWIO_TX_SIZE
|
||||||
|
int32_t usb_rawio_tx( const void *buf, uint32_t timeout )
|
||||||
|
{
|
||||||
|
usb_packet_t *tx_packet;
|
||||||
|
uint32_t begin = millis();
|
||||||
|
|
||||||
|
while ( 1 )
|
||||||
|
{
|
||||||
|
// Error if USB isn't configured
|
||||||
|
if ( !usb_configuration )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
// Make sure we haven't exceeded the outgoing packet limit
|
||||||
|
if ( usb_tx_packet_count( RAWIO_TX_ENDPOINT ) < TX_PACKET_LIMIT )
|
||||||
|
{
|
||||||
|
// Allocate a packet buffer
|
||||||
|
tx_packet = usb_malloc();
|
||||||
|
if ( tx_packet )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for timeout
|
||||||
|
if ( millis() - begin > timeout )
|
||||||
|
{
|
||||||
|
warn_msg("RAWIO Tx - Timeout, dropping packet.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
yield();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy input buffer to usb packet buffer and assign length
|
||||||
|
memcpy( tx_packet->buf, buf, RAWIO_TX_SIZE );
|
||||||
|
tx_packet->len = RAWIO_TX_SIZE;
|
||||||
|
|
||||||
|
// Send USB packet
|
||||||
|
usb_tx( RAWIO_TX_ENDPOINT, tx_packet );
|
||||||
|
|
||||||
|
return RAWIO_TX_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
35
Output/pjrcUSB/arm/usb_rawio.h
Normal file
35
Output/pjrcUSB/arm/usb_rawio.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/* Copyright (C) 2016 by Jacob Alexander
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// ----- Includes -----
|
||||||
|
|
||||||
|
#include "usb_desc.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ----- Functions -----
|
||||||
|
|
||||||
|
uint32_t usb_rawio_available();
|
||||||
|
int32_t usb_rawio_rx( void *buf, uint32_t timeout );
|
||||||
|
int32_t usb_rawio_tx( const void *buf, uint32_t timeout );
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
/* 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-2015
|
* Modified by Jacob Alexander 2013-2016
|
||||||
*
|
*
|
||||||
* 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
|
||||||
@ -29,6 +29,9 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <kll_defs.h>
|
||||||
|
#if enableVirtualSerialPort_define == 1
|
||||||
|
|
||||||
// ----- Includes -----
|
// ----- Includes -----
|
||||||
|
|
||||||
// Compiler Includes
|
// Compiler Includes
|
||||||
@ -69,9 +72,15 @@
|
|||||||
|
|
||||||
// ----- Variables -----
|
// ----- Variables -----
|
||||||
|
|
||||||
// serial port settings (baud rate, control signals, etc) set
|
// Serial port settings (baud rate, control signals, etc) set by the host
|
||||||
// by the PC. These are ignored, but kept in RAM.
|
// These are *ignored*, except to return back to the host if requested
|
||||||
volatile uint8_t usb_cdc_line_coding[7] = { 0x00, 0xE1, 0x00, 0x00, 0x00, 0x00, 0x08 };
|
volatile USBCDCLineCoding usb_cdc_line_coding = {
|
||||||
|
115200,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
8,
|
||||||
|
};
|
||||||
|
|
||||||
volatile uint8_t usb_cdc_line_rtsdtr = 0;
|
volatile uint8_t usb_cdc_line_rtsdtr = 0;
|
||||||
volatile uint8_t usb_cdc_transmit_flush_timer = 0;
|
volatile uint8_t usb_cdc_transmit_flush_timer = 0;
|
||||||
|
|
||||||
@ -315,3 +324,5 @@ void usb_serial_flush_callback()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* 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.
|
||||||
* Modifications by Jacob Alexander (2013-2015)
|
* Modifications by Jacob Alexander (2013-2016)
|
||||||
*
|
*
|
||||||
* 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
|
||||||
@ -50,9 +50,36 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ----- Structs -----
|
||||||
|
|
||||||
|
// See: Universal Serial Bus Class Definitions for Communication Devices 1.11 Table 50
|
||||||
|
// dwDTERate - Baud Rate : 4 bytes
|
||||||
|
// bCharFormat - Stop Bits : 1 byte
|
||||||
|
// 0: 1 stop bit
|
||||||
|
// 1: 1.5 stop bits
|
||||||
|
// 2: 2 stop bits
|
||||||
|
// bParityType - Parity : 1 byte
|
||||||
|
// 0: None
|
||||||
|
// 1: Odd
|
||||||
|
// 2: Even
|
||||||
|
// 3: Mark
|
||||||
|
// 4: Space
|
||||||
|
// bDataBits - Data Bits : 1 byte
|
||||||
|
// (5,6,7,8 or 16)
|
||||||
|
//
|
||||||
|
// Struct is 7 bytes wide
|
||||||
|
typedef struct USBCDCLineCoding {
|
||||||
|
uint32_t dwDTERate; // Baud Rate
|
||||||
|
uint8_t bCharFormat; // Stop Bits
|
||||||
|
uint8_t bParityType; // Parity
|
||||||
|
uint8_t bDataBits; // Data Bits
|
||||||
|
} USBCDCLineCoding;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ----- Variables -----
|
// ----- Variables -----
|
||||||
|
|
||||||
extern volatile uint8_t usb_cdc_line_coding[7];
|
extern volatile USBCDCLineCoding usb_cdc_line_coding;
|
||||||
|
|
||||||
extern volatile uint8_t usb_cdc_line_rtsdtr;
|
extern volatile uint8_t usb_cdc_line_rtsdtr;
|
||||||
extern volatile uint8_t usb_cdc_transmit_flush_timer;
|
extern volatile uint8_t usb_cdc_transmit_flush_timer;
|
||||||
|
@ -4,7 +4,7 @@ Author = "HaaTa (Jacob Alexander) 2014-2016";
|
|||||||
KLL = 0.3d;
|
KLL = 0.3d;
|
||||||
|
|
||||||
# Modified Date
|
# Modified Date
|
||||||
Date = 2016-03-21;
|
Date = 2016-05-31;
|
||||||
|
|
||||||
|
|
||||||
# Output capabilities
|
# Output capabilities
|
||||||
@ -38,3 +38,64 @@ flashModeEnabled = 0;
|
|||||||
|
|
||||||
flashMode => Output_flashMode_capability();
|
flashMode => Output_flashMode_capability();
|
||||||
|
|
||||||
|
|
||||||
|
## USB Compatibility Flags ##
|
||||||
|
# Some OSs and USB Chipsets have issues with USB features
|
||||||
|
# These flags are available to provide ways to debug them
|
||||||
|
|
||||||
|
# Enable USB Suspend/Low Power mode
|
||||||
|
# After a period of inactivity, the USB host may request that the device go into low power mode
|
||||||
|
# This is different than system sleep, though it may occur around the same time
|
||||||
|
enableUSBSuspend => enableUSBSuspend_define;
|
||||||
|
enableUSBSuspend = 1;
|
||||||
|
|
||||||
|
# Enable Low-power Negotiation
|
||||||
|
# In order to support low-powered USB hosts, such as an Apple IPad, a low power auto-negotiation scheme has been implemented
|
||||||
|
# Unfortunately, badly behaved USB Chipsets and OSs may not work correctly with this support enabled
|
||||||
|
# Typical symptoms:
|
||||||
|
# * USB constantly re-initializing when first plugging in
|
||||||
|
enableUSBLowPowerNegotiation => enableUSBLowPowerNegotiation_define;
|
||||||
|
enableUSBLowPowerNegotiation = 0;
|
||||||
|
|
||||||
|
# Enable Device Restart on USB Timeout
|
||||||
|
# *USE AS LAST RETORT*
|
||||||
|
# To work around some USB OS, Chipset and Firwmare bugs, an auto-restart mechanism has been implemented
|
||||||
|
# Depending on the situation, this can be rather aggressive.
|
||||||
|
# This behaves differently than the Low-power negotiation restart and have very different triggering schemes.
|
||||||
|
enableDeviceRestartOnUSBTimeout => enableDeviceRestartOnUSBTimeout_define;
|
||||||
|
enableDeviceRestartOnUSBTimeout = 0;
|
||||||
|
|
||||||
|
# Enable Host-Resume (wake-from-sleep)
|
||||||
|
# On specific actions (such as USB key actions), will trigger the host device to wake if USB is suspended
|
||||||
|
enableUSBResume => enableUSBResume_define;
|
||||||
|
enableUSBResume = 1;
|
||||||
|
|
||||||
|
## USB Endpoint Configuration ##
|
||||||
|
# 1 - Enable endpoint
|
||||||
|
# 0 - Disable endpoint
|
||||||
|
# Any/all endpoints can be disabled
|
||||||
|
# But you'll lose functionality for that feature
|
||||||
|
# Disabling endpoints will save RAM and Flash on the target MCU
|
||||||
|
|
||||||
|
# Joystick Endpoint
|
||||||
|
# *Currently Unused*
|
||||||
|
enableJoystick => enableJoystick_define;
|
||||||
|
enableJoystick = 0;
|
||||||
|
|
||||||
|
# Mouse Endpoint
|
||||||
|
enableMouse => enableMouse_define;
|
||||||
|
enableMouse = 1;
|
||||||
|
|
||||||
|
# Keyboard Endpoint
|
||||||
|
enableKeyboard => enableKeyboard_define;
|
||||||
|
enableKeyboard = 1;
|
||||||
|
|
||||||
|
# CDC / Serial Port Endpoint
|
||||||
|
enableVirtualSerialPort => enableVirtualSerialPort_define;
|
||||||
|
enableVirtualSerialPort = 1;
|
||||||
|
|
||||||
|
# Raw I/O Endpoint
|
||||||
|
# *Currently Unused*
|
||||||
|
enableRawIO => enableRawIO_define;
|
||||||
|
enableRawIO = 0;
|
||||||
|
|
||||||
|
@ -71,6 +71,7 @@ void cliFunc_readLEDs ( char* args );
|
|||||||
void cliFunc_sendKeys ( char* args );
|
void cliFunc_sendKeys ( char* args );
|
||||||
void cliFunc_setKeys ( char* args );
|
void cliFunc_setKeys ( char* args );
|
||||||
void cliFunc_setMod ( char* args );
|
void cliFunc_setMod ( char* args );
|
||||||
|
void cliFunc_usbInitTime( char* args );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -83,6 +84,7 @@ CLIDict_Entry( readLEDs, "Read LED byte:" NL "\t\t1 NumLck, 2 CapsLck, 4 Scrl
|
|||||||
CLIDict_Entry( sendKeys, "Send the prepared list of USB codes and modifier byte." );
|
CLIDict_Entry( sendKeys, "Send the prepared list of USB codes and modifier byte." );
|
||||||
CLIDict_Entry( setKeys, "Prepare a space separated list of USB codes (decimal). Waits until \033[35msendKeys\033[0m." );
|
CLIDict_Entry( setKeys, "Prepare a space separated list of USB codes (decimal). Waits until \033[35msendKeys\033[0m." );
|
||||||
CLIDict_Entry( setMod, "Set the modfier byte:" NL "\t\t1 LCtrl, 2 LShft, 4 LAlt, 8 LGUI, 16 RCtrl, 32 RShft, 64 RAlt, 128 RGUI" );
|
CLIDict_Entry( setMod, "Set the modfier byte:" NL "\t\t1 LCtrl, 2 LShft, 4 LAlt, 8 LGUI, 16 RCtrl, 32 RShft, 64 RAlt, 128 RGUI" );
|
||||||
|
CLIDict_Entry( usbInitTime, "Displays the time in ms from usb_init() till the last setup call." );
|
||||||
|
|
||||||
CLIDict_Def( outputCLIDict, "USB Module Commands" ) = {
|
CLIDict_Def( outputCLIDict, "USB Module Commands" ) = {
|
||||||
CLIDict_Item( kbdProtocol ),
|
CLIDict_Item( kbdProtocol ),
|
||||||
@ -91,6 +93,7 @@ CLIDict_Def( outputCLIDict, "USB Module Commands" ) = {
|
|||||||
CLIDict_Item( sendKeys ),
|
CLIDict_Item( sendKeys ),
|
||||||
CLIDict_Item( setKeys ),
|
CLIDict_Item( setKeys ),
|
||||||
CLIDict_Item( setMod ),
|
CLIDict_Item( setMod ),
|
||||||
|
CLIDict_Item( usbInitTime ),
|
||||||
{ 0, 0, 0 } // Null entry for dictionary end
|
{ 0, 0, 0 } // Null entry for dictionary end
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -162,6 +165,11 @@ uint16_t Output_ExtCurrent_Available = 0;
|
|||||||
// Initially 100 mA, but may be negotiated higher (e.g. 500 mA)
|
// Initially 100 mA, but may be negotiated higher (e.g. 500 mA)
|
||||||
uint16_t Output_USBCurrent_Available = 0;
|
uint16_t Output_USBCurrent_Available = 0;
|
||||||
|
|
||||||
|
// USB Init Time (ms) - usb_init()
|
||||||
|
volatile uint32_t USBInit_TimeStart;
|
||||||
|
volatile uint32_t USBInit_TimeEnd;
|
||||||
|
volatile uint16_t USBInit_Ticks;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ----- Capabilities -----
|
// ----- Capabilities -----
|
||||||
@ -169,6 +177,7 @@ uint16_t Output_USBCurrent_Available = 0;
|
|||||||
// Set Boot Keyboard Protocol
|
// Set Boot Keyboard Protocol
|
||||||
void Output_kbdProtocolBoot_capability( uint8_t state, uint8_t stateType, uint8_t *args )
|
void Output_kbdProtocolBoot_capability( uint8_t state, uint8_t stateType, uint8_t *args )
|
||||||
{
|
{
|
||||||
|
#if enableKeyboard_define == 1
|
||||||
// Display capability name
|
// Display capability name
|
||||||
if ( stateType == 0xFF && state == 0xFF )
|
if ( stateType == 0xFF && state == 0xFF )
|
||||||
{
|
{
|
||||||
@ -190,12 +199,14 @@ void Output_kbdProtocolBoot_capability( uint8_t state, uint8_t stateType, uint8_
|
|||||||
|
|
||||||
// Set the keyboard protocol to Boot Mode
|
// Set the keyboard protocol to Boot Mode
|
||||||
USBKeys_Protocol = 0;
|
USBKeys_Protocol = 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Set NKRO Keyboard Protocol
|
// Set NKRO Keyboard Protocol
|
||||||
void Output_kbdProtocolNKRO_capability( uint8_t state, uint8_t stateType, uint8_t *args )
|
void Output_kbdProtocolNKRO_capability( uint8_t state, uint8_t stateType, uint8_t *args )
|
||||||
{
|
{
|
||||||
|
#if enableKeyboard_define == 1
|
||||||
// Display capability name
|
// Display capability name
|
||||||
if ( stateType == 0xFF && state == 0xFF )
|
if ( stateType == 0xFF && state == 0xFF )
|
||||||
{
|
{
|
||||||
@ -217,12 +228,14 @@ void Output_kbdProtocolNKRO_capability( uint8_t state, uint8_t stateType, uint8_
|
|||||||
|
|
||||||
// Set the keyboard protocol to NKRO Mode
|
// Set the keyboard protocol to NKRO Mode
|
||||||
USBKeys_Protocol = 1;
|
USBKeys_Protocol = 1;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Toggle Keyboard Protocol
|
// Toggle Keyboard Protocol
|
||||||
void Output_toggleKbdProtocol_capability( uint8_t state, uint8_t stateType, uint8_t *args )
|
void Output_toggleKbdProtocol_capability( uint8_t state, uint8_t stateType, uint8_t *args )
|
||||||
{
|
{
|
||||||
|
#if enableKeyboard_define == 1
|
||||||
// Display capability name
|
// Display capability name
|
||||||
if ( stateType == 0xFF && state == 0xFF )
|
if ( stateType == 0xFF && state == 0xFF )
|
||||||
{
|
{
|
||||||
@ -239,12 +252,14 @@ void Output_toggleKbdProtocol_capability( uint8_t state, uint8_t stateType, uint
|
|||||||
// Toggle the keyboard protocol Mode
|
// Toggle the keyboard protocol Mode
|
||||||
USBKeys_Protocol = !USBKeys_Protocol;
|
USBKeys_Protocol = !USBKeys_Protocol;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Sends a Consumer Control code to the USB Output buffer
|
// Sends a Consumer Control code to the USB Output buffer
|
||||||
void Output_consCtrlSend_capability( uint8_t state, uint8_t stateType, uint8_t *args )
|
void Output_consCtrlSend_capability( uint8_t state, uint8_t stateType, uint8_t *args )
|
||||||
{
|
{
|
||||||
|
#if enableKeyboard_define == 1
|
||||||
// Display capability name
|
// Display capability name
|
||||||
if ( stateType == 0xFF && state == 0xFF )
|
if ( stateType == 0xFF && state == 0xFF )
|
||||||
{
|
{
|
||||||
@ -273,6 +288,7 @@ void Output_consCtrlSend_capability( uint8_t state, uint8_t stateType, uint8_t *
|
|||||||
|
|
||||||
// Set consumer control code
|
// Set consumer control code
|
||||||
USBKeys_ConsCtrl = *(uint16_t*)(&args[0]);
|
USBKeys_ConsCtrl = *(uint16_t*)(&args[0]);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -294,6 +310,7 @@ void Output_noneSend_capability( uint8_t state, uint8_t stateType, uint8_t *args
|
|||||||
// Sends a System Control code to the USB Output buffer
|
// Sends a System Control code to the USB Output buffer
|
||||||
void Output_sysCtrlSend_capability( uint8_t state, uint8_t stateType, uint8_t *args )
|
void Output_sysCtrlSend_capability( uint8_t state, uint8_t stateType, uint8_t *args )
|
||||||
{
|
{
|
||||||
|
#if enableKeyboard_define == 1
|
||||||
// Display capability name
|
// Display capability name
|
||||||
if ( stateType == 0xFF && state == 0xFF )
|
if ( stateType == 0xFF && state == 0xFF )
|
||||||
{
|
{
|
||||||
@ -322,6 +339,7 @@ void Output_sysCtrlSend_capability( uint8_t state, uint8_t stateType, uint8_t *a
|
|||||||
|
|
||||||
// Set system control code
|
// Set system control code
|
||||||
USBKeys_SysCtrl = args[0];
|
USBKeys_SysCtrl = args[0];
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -329,6 +347,7 @@ void Output_sysCtrlSend_capability( uint8_t state, uint8_t stateType, uint8_t *a
|
|||||||
// Argument #1: USB Code
|
// Argument #1: USB Code
|
||||||
void Output_usbCodeSend_capability( uint8_t state, uint8_t stateType, uint8_t *args )
|
void Output_usbCodeSend_capability( uint8_t state, uint8_t stateType, uint8_t *args )
|
||||||
{
|
{
|
||||||
|
#if enableKeyboard_define == 1
|
||||||
// Display capability name
|
// Display capability name
|
||||||
if ( stateType == 0xFF && state == 0xFF )
|
if ( stateType == 0xFF && state == 0xFF )
|
||||||
{
|
{
|
||||||
@ -529,6 +548,7 @@ void Output_usbCodeSend_capability( uint8_t state, uint8_t stateType, uint8_t *a
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Output_flashMode_capability( uint8_t state, uint8_t stateType, uint8_t *args )
|
void Output_flashMode_capability( uint8_t state, uint8_t stateType, uint8_t *args )
|
||||||
@ -544,6 +564,7 @@ void Output_flashMode_capability( uint8_t state, uint8_t stateType, uint8_t *arg
|
|||||||
Output_firmwareReload();
|
Output_firmwareReload();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if enableMouse_define == 1
|
||||||
// Sends a mouse command over the USB Output buffer
|
// Sends a mouse command over the USB Output buffer
|
||||||
// XXX This function *will* be changing in the future
|
// XXX This function *will* be changing in the future
|
||||||
// If you use it, be prepared that your .kll files will break in the future (post KLL 0.5)
|
// If you use it, be prepared that your .kll files will break in the future (post KLL 0.5)
|
||||||
@ -600,6 +621,7 @@ void Output_usbMouse_capability( uint8_t state, uint8_t stateType, uint8_t *args
|
|||||||
if ( mouse_x || mouse_y )
|
if ( mouse_x || mouse_y )
|
||||||
USBMouse_Changed |= USBMouseChangeState_Relative;
|
USBMouse_Changed |= USBMouseChangeState_Relative;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -643,11 +665,6 @@ inline void Output_send()
|
|||||||
// Non-standard USB state manipulation, usually does nothing
|
// Non-standard USB state manipulation, usually does nothing
|
||||||
usb_device_check();
|
usb_device_check();
|
||||||
|
|
||||||
// Boot Mode Only, unset stale keys
|
|
||||||
if ( USBKeys_Protocol == 0 )
|
|
||||||
for ( uint8_t c = USBKeys_Sent; c < USB_BOOT_MAX_KEYS; c++ )
|
|
||||||
USBKeys_Keys[c] = 0;
|
|
||||||
|
|
||||||
// XXX - Behaves oddly on Mac OSX, might help with corrupted packets specific to OSX? -HaaTa
|
// XXX - Behaves oddly on Mac OSX, might help with corrupted packets specific to OSX? -HaaTa
|
||||||
/*
|
/*
|
||||||
// Check if idle count has been exceed, this forces usb_keyboard_send and usb_mouse_send to update
|
// Check if idle count has been exceed, this forces usb_keyboard_send and usb_mouse_send to update
|
||||||
@ -661,9 +678,17 @@ inline void Output_send()
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#if enableMouse_define == 1
|
||||||
// Process mouse actions
|
// Process mouse actions
|
||||||
while ( USBMouse_Changed )
|
while ( USBMouse_Changed )
|
||||||
usb_mouse_send();
|
usb_mouse_send();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if enableKeyboard_define == 1
|
||||||
|
// Boot Mode Only, unset stale keys
|
||||||
|
if ( USBKeys_Protocol == 0 )
|
||||||
|
for ( uint8_t c = USBKeys_Sent; c < USB_BOOT_MAX_KEYS; c++ )
|
||||||
|
USBKeys_Keys[c] = 0;
|
||||||
|
|
||||||
// Send keypresses while there are pending changes
|
// Send keypresses while there are pending changes
|
||||||
while ( USBKeys_Changed )
|
while ( USBKeys_Changed )
|
||||||
@ -684,6 +709,7 @@ inline void Output_send()
|
|||||||
Scan_finishedWithOutput( USBKeys_Sent );
|
Scan_finishedWithOutput( USBKeys_Sent );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -697,28 +723,41 @@ inline void Output_firmwareReload()
|
|||||||
// USB Input buffer available
|
// USB Input buffer available
|
||||||
inline unsigned int Output_availablechar()
|
inline unsigned int Output_availablechar()
|
||||||
{
|
{
|
||||||
|
#if enableVirtualSerialPort_define == 1
|
||||||
return usb_serial_available();
|
return usb_serial_available();
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// USB Get Character from input buffer
|
// USB Get Character from input buffer
|
||||||
inline int Output_getchar()
|
inline int Output_getchar()
|
||||||
{
|
{
|
||||||
|
#if enableVirtualSerialPort_define == 1
|
||||||
// XXX Make sure to check output_availablechar() first! Information is lost with the cast (error codes) (AVR)
|
// XXX Make sure to check output_availablechar() first! Information is lost with the cast (error codes) (AVR)
|
||||||
return (int)usb_serial_getchar();
|
return (int)usb_serial_getchar();
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// USB Send Character to output buffer
|
// USB Send Character to output buffer
|
||||||
inline int Output_putchar( char c )
|
inline int Output_putchar( char c )
|
||||||
{
|
{
|
||||||
|
#if enableVirtualSerialPort_define == 1
|
||||||
return usb_serial_putchar( c );
|
return usb_serial_putchar( c );
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// USB Send String to output buffer, null terminated
|
// USB Send String to output buffer, null terminated
|
||||||
inline int Output_putstr( char* str )
|
inline int Output_putstr( char* str )
|
||||||
{
|
{
|
||||||
|
#if enableVirtualSerialPort_define == 1
|
||||||
#if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) // AVR
|
#if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) // AVR
|
||||||
uint16_t count = 0;
|
uint16_t count = 0;
|
||||||
#elif defined(_mk20dx128_) || defined(_mk20dx128vlf5_) || defined(_mk20dx256_) || defined(_mk20dx256vlh7_) // ARM
|
#elif defined(_mk20dx128_) || defined(_mk20dx128vlf5_) || defined(_mk20dx256_) || defined(_mk20dx256vlh7_) // ARM
|
||||||
@ -729,6 +768,9 @@ inline int Output_putstr( char* str )
|
|||||||
count++;
|
count++;
|
||||||
|
|
||||||
return usb_serial_write( str, count );
|
return usb_serial_write( str, count );
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -739,6 +781,43 @@ inline void Output_softReset()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// USB RawIO buffer available
|
||||||
|
inline unsigned int Output_rawio_availablechar()
|
||||||
|
{
|
||||||
|
#if enableRawIO_define == 1
|
||||||
|
return usb_rawio_available();
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// USB RawIO get buffer
|
||||||
|
// XXX Must be a 64 byte buffer
|
||||||
|
inline int Output_rawio_getbuffer( char* buffer )
|
||||||
|
{
|
||||||
|
#if enableRawIO_define == 1
|
||||||
|
// No timeout, fail immediately
|
||||||
|
return usb_rawio_rx( (void*)buffer, 0 );
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// USB RawIO send buffer
|
||||||
|
// XXX Must be a 64 byte buffer
|
||||||
|
inline int Output_rawio_sendbuffer( char* buffer )
|
||||||
|
{
|
||||||
|
#if enableRawIO_define == 1
|
||||||
|
// No timeout, fail immediately
|
||||||
|
return usb_rawio_tx( (void*)buffer, 0 );
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Update USB current (mA)
|
// Update USB current (mA)
|
||||||
// Triggers power change event
|
// Triggers power change event
|
||||||
void Output_update_usb_current( unsigned int current )
|
void Output_update_usb_current( unsigned int current )
|
||||||
@ -892,3 +971,15 @@ void cliFunc_setMod( char* args )
|
|||||||
USBKeys_ModifiersCLI = numToInt( arg1Ptr );
|
USBKeys_ModifiersCLI = numToInt( arg1Ptr );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cliFunc_usbInitTime( char* args )
|
||||||
|
{
|
||||||
|
// Calculate overall USB initialization time
|
||||||
|
// XXX A protocol analyzer will be more accurate, however, this is built-in and easier to collect data
|
||||||
|
print(NL);
|
||||||
|
info_msg("USB Init Time: ");
|
||||||
|
printInt32( USBInit_TimeEnd - USBInit_TimeStart );
|
||||||
|
print(" ms - ");
|
||||||
|
printInt16( USBInit_Ticks );
|
||||||
|
print(" ticks");
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -99,6 +99,10 @@ extern uint8_t Output_DebugMode; // 0 - Debug disabled, 1 - Debug enab
|
|||||||
|
|
||||||
extern uint16_t Output_ExtCurrent_Available; // mA - Set by outside module if not using USB (i.e. Interconnect)
|
extern uint16_t Output_ExtCurrent_Available; // mA - Set by outside module if not using USB (i.e. Interconnect)
|
||||||
|
|
||||||
|
extern volatile uint32_t USBInit_TimeStart; // Timetamp when usb_init was triggered
|
||||||
|
extern volatile uint32_t USBInit_TimeEnd; // Timetamp since last call to the Configuration endpoint
|
||||||
|
extern volatile uint16_t USBInit_Ticks; // Number of times the end time has been updated
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ----- Functions -----
|
// ----- Functions -----
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
###| CMake Kiibohd Controller USB Module |###
|
###| CMake Kiibohd Controller USB Module |###
|
||||||
#
|
#
|
||||||
# Written by Jacob Alexander in 2011-2015 for the Kiibohd Controller
|
# Written by Jacob Alexander in 2011-2016 for the Kiibohd Controller
|
||||||
#
|
#
|
||||||
# Released into the Public Domain
|
# Released into the Public Domain
|
||||||
#
|
#
|
||||||
@ -30,6 +30,7 @@ elseif ( ${COMPILER_FAMILY} MATCHES "arm" )
|
|||||||
arm/usb_keyboard.c
|
arm/usb_keyboard.c
|
||||||
arm/usb_mem.c
|
arm/usb_mem.c
|
||||||
arm/usb_mouse.c
|
arm/usb_mouse.c
|
||||||
|
arm/usb_rawio.c
|
||||||
arm/usb_serial.c
|
arm/usb_serial.c
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -51,7 +51,8 @@
|
|||||||
// ----- Macros -----
|
// ----- Macros -----
|
||||||
|
|
||||||
// Used to build a bitmap lookup table from a byte addressable array
|
// Used to build a bitmap lookup table from a byte addressable array
|
||||||
#define byteLookup( byte ) case (( byte ) * ( 8 )): bytePosition = byte; byteShift = 0; break; \
|
#define byteLookup( byte ) \
|
||||||
|
case (( byte ) * ( 8 )): bytePosition = byte; byteShift = 0; break; \
|
||||||
case (( byte ) * ( 8 ) + ( 1 )): bytePosition = byte; byteShift = 1; break; \
|
case (( byte ) * ( 8 ) + ( 1 )): bytePosition = byte; byteShift = 1; break; \
|
||||||
case (( byte ) * ( 8 ) + ( 2 )): bytePosition = byte; byteShift = 2; break; \
|
case (( byte ) * ( 8 ) + ( 2 )): bytePosition = byte; byteShift = 2; break; \
|
||||||
case (( byte ) * ( 8 ) + ( 3 )): bytePosition = byte; byteShift = 3; break; \
|
case (( byte ) * ( 8 ) + ( 3 )): bytePosition = byte; byteShift = 3; break; \
|
||||||
@ -72,6 +73,7 @@ void cliFunc_sendKeys ( char* args );
|
|||||||
void cliFunc_sendUART ( char* args );
|
void cliFunc_sendUART ( char* args );
|
||||||
void cliFunc_setKeys ( char* args );
|
void cliFunc_setKeys ( char* args );
|
||||||
void cliFunc_setMod ( char* args );
|
void cliFunc_setMod ( char* args );
|
||||||
|
void cliFunc_usbInitTime( char* args );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -86,6 +88,7 @@ CLIDict_Entry( sendKeys, "Send the prepared list of USB codes and modifier by
|
|||||||
CLIDict_Entry( sendUART, "Send characters over UART0." );
|
CLIDict_Entry( sendUART, "Send characters over UART0." );
|
||||||
CLIDict_Entry( setKeys, "Prepare a space separated list of USB codes (decimal). Waits until \033[35msendKeys\033[0m." );
|
CLIDict_Entry( setKeys, "Prepare a space separated list of USB codes (decimal). Waits until \033[35msendKeys\033[0m." );
|
||||||
CLIDict_Entry( setMod, "Set the modfier byte:" NL "\t\t1 LCtrl, 2 LShft, 4 LAlt, 8 LGUI, 16 RCtrl, 32 RShft, 64 RAlt, 128 RGUI" );
|
CLIDict_Entry( setMod, "Set the modfier byte:" NL "\t\t1 LCtrl, 2 LShft, 4 LAlt, 8 LGUI, 16 RCtrl, 32 RShft, 64 RAlt, 128 RGUI" );
|
||||||
|
CLIDict_Entry( usbInitTime, "Displays the time in ms from usb_init() till the last setup call." );
|
||||||
|
|
||||||
CLIDict_Def( outputCLIDict, "USB Module Commands" ) = {
|
CLIDict_Def( outputCLIDict, "USB Module Commands" ) = {
|
||||||
CLIDict_Item( kbdProtocol ),
|
CLIDict_Item( kbdProtocol ),
|
||||||
@ -96,6 +99,7 @@ CLIDict_Def( outputCLIDict, "USB Module Commands" ) = {
|
|||||||
CLIDict_Item( sendUART ),
|
CLIDict_Item( sendUART ),
|
||||||
CLIDict_Item( setKeys ),
|
CLIDict_Item( setKeys ),
|
||||||
CLIDict_Item( setMod ),
|
CLIDict_Item( setMod ),
|
||||||
|
CLIDict_Item( usbInitTime ),
|
||||||
{ 0, 0, 0 } // Null entry for dictionary end
|
{ 0, 0, 0 } // Null entry for dictionary end
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -167,6 +171,11 @@ uint16_t Output_ExtCurrent_Available = 0;
|
|||||||
// Initially 100 mA, but may be negotiated higher (e.g. 500 mA)
|
// Initially 100 mA, but may be negotiated higher (e.g. 500 mA)
|
||||||
uint16_t Output_USBCurrent_Available = 0;
|
uint16_t Output_USBCurrent_Available = 0;
|
||||||
|
|
||||||
|
// USB Init Time (ms)
|
||||||
|
volatile uint32_t USBInit_TimeStart;
|
||||||
|
volatile uint32_t USBInit_TimeEnd;
|
||||||
|
volatile uint16_t USBInit_Ticks;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ----- Capabilities -----
|
// ----- Capabilities -----
|
||||||
@ -174,6 +183,7 @@ uint16_t Output_USBCurrent_Available = 0;
|
|||||||
// Set Boot Keyboard Protocol
|
// Set Boot Keyboard Protocol
|
||||||
void Output_kbdProtocolBoot_capability( uint8_t state, uint8_t stateType, uint8_t *args )
|
void Output_kbdProtocolBoot_capability( uint8_t state, uint8_t stateType, uint8_t *args )
|
||||||
{
|
{
|
||||||
|
#if enableKeyboard_define == 1
|
||||||
// Display capability name
|
// Display capability name
|
||||||
if ( stateType == 0xFF && state == 0xFF )
|
if ( stateType == 0xFF && state == 0xFF )
|
||||||
{
|
{
|
||||||
@ -195,12 +205,14 @@ void Output_kbdProtocolBoot_capability( uint8_t state, uint8_t stateType, uint8_
|
|||||||
|
|
||||||
// Set the keyboard protocol to Boot Mode
|
// Set the keyboard protocol to Boot Mode
|
||||||
USBKeys_Protocol = 0;
|
USBKeys_Protocol = 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Set NKRO Keyboard Protocol
|
// Set NKRO Keyboard Protocol
|
||||||
void Output_kbdProtocolNKRO_capability( uint8_t state, uint8_t stateType, uint8_t *args )
|
void Output_kbdProtocolNKRO_capability( uint8_t state, uint8_t stateType, uint8_t *args )
|
||||||
{
|
{
|
||||||
|
#if enableKeyboard_define == 1
|
||||||
// Display capability name
|
// Display capability name
|
||||||
if ( stateType == 0xFF && state == 0xFF )
|
if ( stateType == 0xFF && state == 0xFF )
|
||||||
{
|
{
|
||||||
@ -222,12 +234,14 @@ void Output_kbdProtocolNKRO_capability( uint8_t state, uint8_t stateType, uint8_
|
|||||||
|
|
||||||
// Set the keyboard protocol to NKRO Mode
|
// Set the keyboard protocol to NKRO Mode
|
||||||
USBKeys_Protocol = 1;
|
USBKeys_Protocol = 1;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Toggle Keyboard Protocol
|
// Toggle Keyboard Protocol
|
||||||
void Output_toggleKbdProtocol_capability( uint8_t state, uint8_t stateType, uint8_t *args )
|
void Output_toggleKbdProtocol_capability( uint8_t state, uint8_t stateType, uint8_t *args )
|
||||||
{
|
{
|
||||||
|
#if enableKeyboard_define == 1
|
||||||
// Display capability name
|
// Display capability name
|
||||||
if ( stateType == 0xFF && state == 0xFF )
|
if ( stateType == 0xFF && state == 0xFF )
|
||||||
{
|
{
|
||||||
@ -244,12 +258,14 @@ void Output_toggleKbdProtocol_capability( uint8_t state, uint8_t stateType, uint
|
|||||||
// Toggle the keyboard protocol Mode
|
// Toggle the keyboard protocol Mode
|
||||||
USBKeys_Protocol = !USBKeys_Protocol;
|
USBKeys_Protocol = !USBKeys_Protocol;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Sends a Consumer Control code to the USB Output buffer
|
// Sends a Consumer Control code to the USB Output buffer
|
||||||
void Output_consCtrlSend_capability( uint8_t state, uint8_t stateType, uint8_t *args )
|
void Output_consCtrlSend_capability( uint8_t state, uint8_t stateType, uint8_t *args )
|
||||||
{
|
{
|
||||||
|
#if enableKeyboard_define == 1
|
||||||
// Display capability name
|
// Display capability name
|
||||||
if ( stateType == 0xFF && state == 0xFF )
|
if ( stateType == 0xFF && state == 0xFF )
|
||||||
{
|
{
|
||||||
@ -278,6 +294,7 @@ void Output_consCtrlSend_capability( uint8_t state, uint8_t stateType, uint8_t *
|
|||||||
|
|
||||||
// Set consumer control code
|
// Set consumer control code
|
||||||
USBKeys_ConsCtrl = *(uint16_t*)(&args[0]);
|
USBKeys_ConsCtrl = *(uint16_t*)(&args[0]);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -299,6 +316,7 @@ void Output_noneSend_capability( uint8_t state, uint8_t stateType, uint8_t *args
|
|||||||
// Sends a System Control code to the USB Output buffer
|
// Sends a System Control code to the USB Output buffer
|
||||||
void Output_sysCtrlSend_capability( uint8_t state, uint8_t stateType, uint8_t *args )
|
void Output_sysCtrlSend_capability( uint8_t state, uint8_t stateType, uint8_t *args )
|
||||||
{
|
{
|
||||||
|
#if enableKeyboard_define == 1
|
||||||
// Display capability name
|
// Display capability name
|
||||||
if ( stateType == 0xFF && state == 0xFF )
|
if ( stateType == 0xFF && state == 0xFF )
|
||||||
{
|
{
|
||||||
@ -327,6 +345,7 @@ void Output_sysCtrlSend_capability( uint8_t state, uint8_t stateType, uint8_t *a
|
|||||||
|
|
||||||
// Set system control code
|
// Set system control code
|
||||||
USBKeys_SysCtrl = args[0];
|
USBKeys_SysCtrl = args[0];
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -334,6 +353,7 @@ void Output_sysCtrlSend_capability( uint8_t state, uint8_t stateType, uint8_t *a
|
|||||||
// Argument #1: USB Code
|
// Argument #1: USB Code
|
||||||
void Output_usbCodeSend_capability( uint8_t state, uint8_t stateType, uint8_t *args )
|
void Output_usbCodeSend_capability( uint8_t state, uint8_t stateType, uint8_t *args )
|
||||||
{
|
{
|
||||||
|
#if enableKeyboard_define == 1
|
||||||
// Display capability name
|
// Display capability name
|
||||||
if ( stateType == 0xFF && state == 0xFF )
|
if ( stateType == 0xFF && state == 0xFF )
|
||||||
{
|
{
|
||||||
@ -534,6 +554,7 @@ void Output_usbCodeSend_capability( uint8_t state, uint8_t stateType, uint8_t *a
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Output_flashMode_capability( uint8_t state, uint8_t stateType, uint8_t *args )
|
void Output_flashMode_capability( uint8_t state, uint8_t stateType, uint8_t *args )
|
||||||
@ -557,6 +578,7 @@ void Output_flashMode_capability( uint8_t state, uint8_t stateType, uint8_t *arg
|
|||||||
// Argument #3: USB Y Axis (16 bit) relative
|
// Argument #3: USB Y Axis (16 bit) relative
|
||||||
void Output_usbMouse_capability( uint8_t state, uint8_t stateType, uint8_t *args )
|
void Output_usbMouse_capability( uint8_t state, uint8_t stateType, uint8_t *args )
|
||||||
{
|
{
|
||||||
|
#if enableMouse_define == 1
|
||||||
// Display capability name
|
// Display capability name
|
||||||
if ( stateType == 0xFF && state == 0xFF )
|
if ( stateType == 0xFF && state == 0xFF )
|
||||||
{
|
{
|
||||||
@ -604,6 +626,7 @@ void Output_usbMouse_capability( uint8_t state, uint8_t stateType, uint8_t *args
|
|||||||
|
|
||||||
if ( mouse_x || mouse_y )
|
if ( mouse_x || mouse_y )
|
||||||
USBMouse_Changed |= USBMouseChangeState_Relative;
|
USBMouse_Changed |= USBMouseChangeState_Relative;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -652,10 +675,6 @@ inline void Output_send()
|
|||||||
usb_device_check();
|
usb_device_check();
|
||||||
|
|
||||||
// Boot Mode Only, unset stale keys
|
// Boot Mode Only, unset stale keys
|
||||||
if ( USBKeys_Protocol == 0 )
|
|
||||||
for ( uint8_t c = USBKeys_Sent; c < USB_BOOT_MAX_KEYS; c++ )
|
|
||||||
USBKeys_Keys[c] = 0;
|
|
||||||
|
|
||||||
// XXX - Behaves oddly on Mac OSX, might help with corrupted packets specific to OSX? -HaaTa
|
// XXX - Behaves oddly on Mac OSX, might help with corrupted packets specific to OSX? -HaaTa
|
||||||
/*
|
/*
|
||||||
// Check if idle count has been exceed, this forces usb_keyboard_send and usb_mouse_send to update
|
// Check if idle count has been exceed, this forces usb_keyboard_send and usb_mouse_send to update
|
||||||
@ -669,9 +688,16 @@ inline void Output_send()
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#if enableMouse_define == 1
|
||||||
// Process mouse actions
|
// Process mouse actions
|
||||||
while ( USBMouse_Changed )
|
while ( USBMouse_Changed )
|
||||||
usb_mouse_send();
|
usb_mouse_send();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if enableKeyboard_define == 1
|
||||||
|
if ( USBKeys_Protocol == 0 )
|
||||||
|
for ( uint8_t c = USBKeys_Sent; c < USB_BOOT_MAX_KEYS; c++ )
|
||||||
|
USBKeys_Keys[c] = 0;
|
||||||
|
|
||||||
// Send keypresses while there are pending changes
|
// Send keypresses while there are pending changes
|
||||||
while ( USBKeys_Changed )
|
while ( USBKeys_Changed )
|
||||||
@ -692,6 +718,7 @@ inline void Output_send()
|
|||||||
Scan_finishedWithOutput( USBKeys_Sent );
|
Scan_finishedWithOutput( USBKeys_Sent );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -705,18 +732,24 @@ void Output_firmwareReload()
|
|||||||
// USB Input buffer available
|
// USB Input buffer available
|
||||||
inline unsigned int Output_availablechar()
|
inline unsigned int Output_availablechar()
|
||||||
{
|
{
|
||||||
|
#if enableVirtualSerialPort_define == 1
|
||||||
return usb_serial_available() + uart_serial_available();
|
return usb_serial_available() + uart_serial_available();
|
||||||
|
#else
|
||||||
|
return uart_serial_available();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// USB Get Character from input buffer
|
// USB Get Character from input buffer
|
||||||
inline int Output_getchar()
|
inline int Output_getchar()
|
||||||
{
|
{
|
||||||
|
#if enableVirtualSerialPort_define == 1
|
||||||
// XXX Make sure to check output_availablechar() first! Information is lost with the cast (error codes) (AVR)
|
// XXX Make sure to check output_availablechar() first! Information is lost with the cast (error codes) (AVR)
|
||||||
if ( usb_serial_available() > 0 )
|
if ( usb_serial_available() > 0 )
|
||||||
{
|
{
|
||||||
return (int)usb_serial_getchar();
|
return (int)usb_serial_getchar();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if ( uart_serial_available() > 0 )
|
if ( uart_serial_available() > 0 )
|
||||||
{
|
{
|
||||||
@ -730,11 +763,15 @@ inline int Output_getchar()
|
|||||||
// USB Send Character to output buffer
|
// USB Send Character to output buffer
|
||||||
inline int Output_putchar( char c )
|
inline int Output_putchar( char c )
|
||||||
{
|
{
|
||||||
|
#if enableVirtualSerialPort_define == 1
|
||||||
// First send to UART
|
// First send to UART
|
||||||
uart_serial_putchar( c );
|
uart_serial_putchar( c );
|
||||||
|
|
||||||
// Then send to USB
|
// Then send to USB
|
||||||
return usb_serial_putchar( c );
|
return usb_serial_putchar( c );
|
||||||
|
#else
|
||||||
|
return uart_serial_putchar( c );
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -750,11 +787,15 @@ inline int Output_putstr( char* str )
|
|||||||
while ( str[count] != '\0' )
|
while ( str[count] != '\0' )
|
||||||
count++;
|
count++;
|
||||||
|
|
||||||
|
#if enableVirtualSerialPort_define == 1
|
||||||
// First send to UART
|
// First send to UART
|
||||||
uart_serial_write( str, count );
|
uart_serial_write( str, count );
|
||||||
|
|
||||||
// Then send to USB
|
// Then send to USB
|
||||||
return usb_serial_write( str, count );
|
return usb_serial_write( str, count );
|
||||||
|
#else
|
||||||
|
return uart_serial_write( str, count );
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -938,3 +979,15 @@ void cliFunc_setMod( char* args )
|
|||||||
USBKeys_ModifiersCLI = numToInt( arg1Ptr );
|
USBKeys_ModifiersCLI = numToInt( arg1Ptr );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cliFunc_usbInitTime( char* args )
|
||||||
|
{
|
||||||
|
// Calculate overall USB initialization time
|
||||||
|
// XXX A protocol analyzer will be more accurate, however, this is built-in and easier to collect data
|
||||||
|
print(NL);
|
||||||
|
info_msg("USB Init Time: ");
|
||||||
|
printInt32( USBInit_TimeEnd - USBInit_TimeStart );
|
||||||
|
print(" ms - ");
|
||||||
|
printInt16( USBInit_Ticks );
|
||||||
|
print(" ticks");
|
||||||
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user