Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: FastIO FastPWM SimpleDMA mbed
Fork of Pinscape_Controller by
Diff: USBJoystick/USBJoystick.cpp
- Revision:
- 35:e959ffba78fd
- Parent:
- 33:d832bcab089e
- Child:
- 37:ed52738445fc
--- a/USBJoystick/USBJoystick.cpp Thu Dec 03 07:34:57 2015 +0000
+++ b/USBJoystick/USBJoystick.cpp Sat Dec 19 06:37:19 2015 +0000
@@ -22,11 +22,12 @@
#include "config.h" // Pinscape configuration
+
+
// Length of our joystick reports. Important: This must be kept in sync
// with the actual joystick report format sent in update().
const int reportLen = 14;
-#ifdef ENABLE_JOYSTICK
bool USBJoystick::update(int16_t x, int16_t y, int16_t z, uint32_t buttons, uint16_t status)
{
_x = x;
@@ -39,7 +40,7 @@
// send the report
return update();
}
-
+
bool USBJoystick::update()
{
HID_REPORT report;
@@ -62,6 +63,30 @@
return sendTO(&report, 100);
}
+bool USBJoystick::kbUpdate(uint8_t data[8])
+{
+ // set up the report
+ HID_REPORT report;
+ report.data[0] = REPORT_ID_KB; // report ID = keyboard
+ memcpy(&report.data[1], data, 8); // copy the kb report data
+ report.length = 9; // length = ID prefix + kb report length
+
+ // send it to endpoint 4 (the keyboard interface endpoint)
+ return writeTO(EP4IN, report.data, report.length, MAX_PACKET_SIZE_EPINT, 100);
+}
+
+bool USBJoystick::mediaUpdate(uint8_t data)
+{
+ // set up the report
+ HID_REPORT report;
+ report.data[0] = REPORT_ID_MEDIA; // report ID = media
+ report.data[1] = data; // key pressed bits
+ report.length = 2;
+
+ // send it
+ return writeTO(EP4IN, report.data, report.length, MAX_PACKET_SIZE_EPINT, 100);
+}
+
bool USBJoystick::updateExposure(int &idx, int npix, const uint16_t *pix)
{
HID_REPORT report;
@@ -91,10 +116,10 @@
}
// send the report
- return send(&report);
+ return sendTO(&report, 100);
}
-bool USBJoystick::reportConfig(int numOutputs, int unitNo)
+bool USBJoystick::reportConfig(int numOutputs, int unitNo, int plungerZero, int plungerMax)
{
HID_REPORT report;
@@ -111,9 +136,13 @@
// write the unit number
put(4, unitNo);
+ // write the plunger zero and max values
+ put(6, plungerZero);
+ put(8, plungerMax);
+
// send the report
report.length = reportLen;
- return send(&report);
+ return sendTO(&report, 100);
}
bool USBJoystick::move(int16_t x, int16_t y)
@@ -136,8 +165,6 @@
return update();
}
-#else /* ENABLE_JOYSTICK */
-
bool USBJoystick::updateStatus(uint32_t status)
{
HID_REPORT report;
@@ -152,9 +179,6 @@
return sendTO(&report, 100);
}
-#endif /* ENABLE_JOYSTICK */
-
-
void USBJoystick::_init() {
_x = 0;
@@ -166,93 +190,183 @@
}
-uint8_t * USBJoystick::reportDesc()
-{
-#ifdef ENABLE_JOYSTICK
- // Joystick reports are enabled. Use the full joystick report
- // format.
- static uint8_t reportDescriptor[] =
- {
- USAGE_PAGE(1), 0x01, // Generic desktop
- USAGE(1), 0x04, // Joystick
- COLLECTION(1), 0x01, // Application
+// --------------------------------------------------------------------------
+//
+// USB HID Report Descriptor - Joystick
+//
+static uint8_t reportDescriptorJS[] =
+{
+ USAGE_PAGE(1), 0x01, // Generic desktop
+ USAGE(1), 0x04, // Joystick
+ COLLECTION(1), 0x01, // Application
+
+ // input report (device to host)
+
+ USAGE_PAGE(1), 0x06, // generic device controls - for config status
+ USAGE(1), 0x00, // undefined device control
+ LOGICAL_MINIMUM(1), 0x00, // 8-bit values
+ LOGICAL_MAXIMUM(1), 0xFF,
+ REPORT_SIZE(1), 0x08, // 8 bits per report
+ REPORT_COUNT(1), 0x04, // 4 reports (4 bytes)
+ INPUT(1), 0x02, // Data, Variable, Absolute
+
+ USAGE_PAGE(1), 0x09, // Buttons
+ USAGE_MINIMUM(1), 0x01, // { buttons }
+ USAGE_MAXIMUM(1), 0x20, // { 1-32 }
+ LOGICAL_MINIMUM(1), 0x00, // 1-bit buttons - 0...
+ LOGICAL_MAXIMUM(1), 0x01, // ...to 1
+ REPORT_SIZE(1), 0x01, // 1 bit per report
+ REPORT_COUNT(1), 0x20, // 32 reports
+ UNIT_EXPONENT(1), 0x00, // Unit_Exponent (0)
+ UNIT(1), 0x00, // Unit (None)
+ INPUT(1), 0x02, // Data, Variable, Absolute
+
+ USAGE_PAGE(1), 0x01, // Generic desktop
+ USAGE(1), 0x30, // X axis
+ USAGE(1), 0x31, // Y axis
+ USAGE(1), 0x32, // Z axis
+ LOGICAL_MINIMUM(2), 0x00,0xF0, // each value ranges -4096
+ LOGICAL_MAXIMUM(2), 0x00,0x10, // ...to +4096
+ REPORT_SIZE(1), 0x10, // 16 bits per report
+ REPORT_COUNT(1), 0x03, // 3 reports (X, Y, Z)
+ INPUT(1), 0x02, // Data, Variable, Absolute
- // input report (device to host)
+ // output report (host to device)
+ REPORT_SIZE(1), 0x08, // 8 bits per report
+ REPORT_COUNT(1), 0x08, // output report count - 8-byte LedWiz format
+ 0x09, 0x01, // usage
+ 0x91, 0x01, // Output (array)
+
+ END_COLLECTION(0)
+};
+
+//
+// USB HID Report Descriptor - Keyboard/Media Control
+//
+static uint8_t reportDescriptorKB[] =
+{
+ USAGE_PAGE(1), 0x01, // Generic Desktop
+ USAGE(1), 0x06, // Keyboard
+ COLLECTION(1), 0x01, // Application
+ REPORT_ID(1), REPORT_ID_KB,
- USAGE_PAGE(1), 0x06, // generic device controls - for config status
- USAGE(1), 0x00, // undefined device control
- LOGICAL_MINIMUM(1), 0x00, // 8-bit values
- LOGICAL_MAXIMUM(1), 0xFF,
- REPORT_SIZE(1), 0x08, // 8 bits per report
- REPORT_COUNT(1), 0x04, // 4 reports (4 bytes)
- INPUT(1), 0x02, // Data, Variable, Absolute
+ USAGE_PAGE(1), 0x07, // Key Codes
+ USAGE_MINIMUM(1), 0xE0,
+ USAGE_MAXIMUM(1), 0xE7,
+ LOGICAL_MINIMUM(1), 0x00,
+ LOGICAL_MAXIMUM(1), 0x01,
+ REPORT_SIZE(1), 0x01,
+ REPORT_COUNT(1), 0x08,
+ INPUT(1), 0x02, // Data, Variable, Absolute
+ REPORT_COUNT(1), 0x01,
+ REPORT_SIZE(1), 0x08,
+ INPUT(1), 0x01, // Constant
+
+ REPORT_COUNT(1), 0x05,
+ REPORT_SIZE(1), 0x01,
+ USAGE_PAGE(1), 0x08, // LEDs
+ USAGE_MINIMUM(1), 0x01,
+ USAGE_MAXIMUM(1), 0x05,
+ OUTPUT(1), 0x02, // Data, Variable, Absolute
+ REPORT_COUNT(1), 0x01,
+ REPORT_SIZE(1), 0x03,
+ OUTPUT(1), 0x01, // Constant
- USAGE_PAGE(1), 0x09, // Buttons
- USAGE_MINIMUM(1), 0x01, // { buttons }
- USAGE_MAXIMUM(1), 0x20, // { 1-32 }
- LOGICAL_MINIMUM(1), 0x00, // 1-bit buttons - 0...
- LOGICAL_MAXIMUM(1), 0x01, // ...to 1
- REPORT_SIZE(1), 0x01, // 1 bit per report
- REPORT_COUNT(1), 0x20, // 32 reports
- UNIT_EXPONENT(1), 0x00, // Unit_Exponent (0)
- UNIT(1), 0x00, // Unit (None)
- INPUT(1), 0x02, // Data, Variable, Absolute
-
- USAGE_PAGE(1), 0x01, // Generic desktop
- USAGE(1), 0x30, // X axis
- USAGE(1), 0x31, // Y axis
- USAGE(1), 0x32, // Z axis
- LOGICAL_MINIMUM(2), 0x00,0xF0, // each value ranges -4096
- LOGICAL_MAXIMUM(2), 0x00,0x10, // ...to +4096
- REPORT_SIZE(1), 0x10, // 16 bits per report
- REPORT_COUNT(1), 0x03, // 3 reports (X, Y, Z)
- INPUT(1), 0x02, // Data, Variable, Absolute
-
- // output report (host to device)
- REPORT_SIZE(1), 0x08, // 8 bits per report
- REPORT_COUNT(1), 0x08, // output report count - 8-byte LedWiz format
- 0x09, 0x01, // usage
- 0x91, 0x01, // Output (array)
+ REPORT_COUNT(1), 0x06,
+ REPORT_SIZE(1), 0x08,
+ LOGICAL_MINIMUM(1), 0x00,
+ LOGICAL_MAXIMUM(1), 0x65,
+ USAGE_PAGE(1), 0x07, // Key Codes
+ USAGE_MINIMUM(1), 0x00,
+ USAGE_MAXIMUM(1), 0x65,
+ INPUT(1), 0x00, // Data, Array
+ END_COLLECTION(0),
- END_COLLECTION(0)
+ // Media Control
+ USAGE_PAGE(1), 0x0C,
+ USAGE(1), 0x01,
+ COLLECTION(1), 0x01,
+ REPORT_ID(1), REPORT_ID_MEDIA,
+ USAGE_PAGE(1), 0x0C,
+ LOGICAL_MINIMUM(1), 0x00,
+ LOGICAL_MAXIMUM(1), 0x01,
+ REPORT_SIZE(1), 0x01,
+ REPORT_COUNT(1), 0x07,
+ USAGE(1), 0xE9, // Volume Up
+ USAGE(1), 0xEA, // Volume Down
+ USAGE(1), 0xE2, // Mute
+ USAGE(1), 0xB5, // Next Track
+ USAGE(1), 0xB6, // Previous Track
+ USAGE(1), 0xB7, // Stop
+ USAGE(1), 0xCD, // Play / Pause
+ INPUT(1), 0x02, // Input (Data, Variable, Absolute)
+ REPORT_COUNT(1), 0x01,
+ INPUT(1), 0x01,
+ END_COLLECTION(0),
+};
- };
-#else /* defined(ENABLE_JOYSTICK) */
+//
+// USB HID Report Descriptor - LedWiz only, with no joystick or keyboard
+// input reporting
+//
+static uint8_t reportDescriptorLW[] =
+{
+ USAGE_PAGE(1), 0x01, // Generic desktop
+ USAGE(1), 0x00, // Undefined
- // Joystick reports are disabled. We still want to appear
- // as a USB device for the LedWiz output emulation, but we
- // don't want to appear as a joystick.
+ COLLECTION(1), 0x01, // Application
- static uint8_t reportDescriptor[] =
- {
- USAGE_PAGE(1), 0x01, // Generic desktop
- USAGE(1), 0x00, // Undefined
+ // input report (device to host)
+ USAGE_PAGE(1), 0x06, // generic device controls - for config status
+ USAGE(1), 0x00, // undefined device control
+ LOGICAL_MINIMUM(1), 0x00, // 8-bit values
+ LOGICAL_MAXIMUM(1), 0xFF,
+ REPORT_SIZE(1), 0x08, // 8 bits per report
+ REPORT_COUNT(1), reportLen, // standard report length (same as if we were in joystick mode)
+ INPUT(1), 0x02, // Data, Variable, Absolute
+
+ // output report (host to device)
+ REPORT_SIZE(1), 0x08, // 8 bits per report
+ REPORT_COUNT(1), 0x08, // output report count (LEDWiz messages)
+ 0x09, 0x01, // usage
+ 0x91, 0x01, // Output (array)
+
+ END_COLLECTION(0)
+};
+
- COLLECTION(1), 0x01, // Application
-
- // input report (device to host)
- USAGE_PAGE(1), 0x06, // generic device controls - for config status
- USAGE(1), 0x00, // undefined device control
- LOGICAL_MINIMUM(1), 0x00, // 8-bit values
- LOGICAL_MAXIMUM(1), 0xFF,
- REPORT_SIZE(1), 0x08, // 8 bits per report
- REPORT_COUNT(1), reportLen, // standard report length (same as if we were in joystick mode)
- INPUT(1), 0x02, // Data, Variable, Absolute
-
- // output report (host to device)
- REPORT_SIZE(1), 0x08, // 8 bits per report
- REPORT_COUNT(1), 0x08, // output report count (LEDWiz messages)
- 0x09, 0x01, // usage
- 0x91, 0x01, // Output (array)
-
- END_COLLECTION(0)
- };
-
-#endif /* defined(ENABLE_JOYSTICK) */
-
- reportLength = sizeof(reportDescriptor);
- return reportDescriptor;
-}
+uint8_t * USBJoystick::reportDescN(int idx)
+{
+ if (enableJoystick)
+ {
+ // Joystick reports are enabled. Use the full joystick report
+ // format, or full keyboard report format, depending on which
+ // interface is being requested.
+ switch (idx)
+ {
+ case 0:
+ // joystick interface
+ reportLength = sizeof(reportDescriptorJS);
+ return reportDescriptorJS;
+
+ case 1:
+ // keyboard interface
+ reportLength = sizeof(reportDescriptorKB);
+ return reportDescriptorKB;
+
+ default:
+ // unknown interface
+ reportLength = 0;
+ return 0;
+ }
+ }
+ else
+ {
+ // Joystick reports are disabled. Use the LedWiz-only format.
+ reportLength = sizeof(reportDescriptorLW);
+ return reportDescriptorLW;
+ }
+}
uint8_t * USBJoystick::stringImanufacturerDesc() {
static uint8_t stringImanufacturerDescriptor[] = {
@@ -282,3 +396,206 @@
};
return stringIproductDescriptor;
}
+
+#define DEFAULT_CONFIGURATION (1)
+
+uint8_t * USBJoystick::configurationDesc()
+{
+ int rptlen0 = reportDescLengthN(0);
+ int rptlen1 = reportDescLengthN(1);
+ if (useKB)
+ {
+ int cfglenKB = ((1 * CONFIGURATION_DESCRIPTOR_LENGTH)
+ + (2 * INTERFACE_DESCRIPTOR_LENGTH)
+ + (2 * HID_DESCRIPTOR_LENGTH)
+ + (4 * ENDPOINT_DESCRIPTOR_LENGTH));
+ static uint8_t configurationDescriptorWithKB[] =
+ {
+ CONFIGURATION_DESCRIPTOR_LENGTH,// bLength
+ CONFIGURATION_DESCRIPTOR, // bDescriptorType
+ LSB(cfglenKB), // wTotalLength (LSB)
+ MSB(cfglenKB), // wTotalLength (MSB)
+ 0x02, // bNumInterfaces - TWO INTERFACES (JOYSTICK + KEYBOARD)
+ DEFAULT_CONFIGURATION, // bConfigurationValue
+ 0x00, // iConfiguration
+ C_RESERVED | C_SELF_POWERED, // bmAttributes
+ C_POWER(0), // bMaxPowerHello World from Mbed
+
+ // INTERFACE 0 - JOYSTICK/LEDWIZ
+ INTERFACE_DESCRIPTOR_LENGTH, // bLength
+ INTERFACE_DESCRIPTOR, // bDescriptorType
+ 0x00, // bInterfaceNumber - first interface = 0
+ 0x00, // bAlternateSetting
+ 0x02, // bNumEndpoints
+ HID_CLASS, // bInterfaceClass
+ HID_SUBCLASS_NONE, // bInterfaceSubClass
+ HID_PROTOCOL_NONE, // bInterfaceProtocol
+ 0x00, // iInterface
+
+ HID_DESCRIPTOR_LENGTH, // bLength
+ HID_DESCRIPTOR, // bDescriptorType
+ LSB(HID_VERSION_1_11), // bcdHID (LSB)
+ MSB(HID_VERSION_1_11), // bcdHID (MSB)
+ 0x00, // bCountryCode
+ 0x01, // bNumDescriptors
+ REPORT_DESCRIPTOR, // bDescriptorType
+ LSB(rptlen0), // wDescriptorLength (LSB)
+ MSB(rptlen0), // wDescriptorLength (MSB)
+
+ ENDPOINT_DESCRIPTOR_LENGTH, // bLength
+ ENDPOINT_DESCRIPTOR, // bDescriptorType
+ PHY_TO_DESC(EPINT_IN), // bEndpointAddress - EPINT == EP1
+ E_INTERRUPT, // bmAttributes
+ LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB)
+ MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB)
+ 1, // bInterval (milliseconds)
+
+ ENDPOINT_DESCRIPTOR_LENGTH, // bLength
+ ENDPOINT_DESCRIPTOR, // bDescriptorType
+ PHY_TO_DESC(EPINT_OUT), // bEndpointAddress - EPINT == EP1
+ E_INTERRUPT, // bmAttributes
+ LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB)
+ MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB)
+ 1, // bInterval (milliseconds)
+
+ // INTERFACE 1 - KEYBOARD
+ INTERFACE_DESCRIPTOR_LENGTH, // bLength
+ INTERFACE_DESCRIPTOR, // bDescriptorType
+ 0x01, // bInterfaceNumber - second interface = 1
+ 0x00, // bAlternateSetting
+ 0x02, // bNumEndpoints
+ HID_CLASS, // bInterfaceClass
+ 1, // bInterfaceSubClass - KEYBOARD
+ 1, // bInterfaceProtocol - KEYBOARD
+ 0x00, // iInterface
+
+ HID_DESCRIPTOR_LENGTH, // bLength
+ HID_DESCRIPTOR, // bDescriptorType
+ LSB(HID_VERSION_1_11), // bcdHID (LSB)
+ MSB(HID_VERSION_1_11), // bcdHID (MSB)
+ 0x00, // bCountryCode
+ 0x01, // bNumDescriptors
+ REPORT_DESCRIPTOR, // bDescriptorType
+ LSB(rptlen1), // wDescriptorLength (LSB)
+ MSB(rptlen1), // wDescriptorLength (MSB)
+
+ ENDPOINT_DESCRIPTOR_LENGTH, // bLength
+ ENDPOINT_DESCRIPTOR, // bDescriptorType
+ PHY_TO_DESC(EP4IN), // bEndpointAddress
+ E_INTERRUPT, // bmAttributes
+ LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB)
+ MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB)
+ 1, // bInterval (milliseconds)
+
+ ENDPOINT_DESCRIPTOR_LENGTH, // bLength
+ ENDPOINT_DESCRIPTOR, // bDescriptorType
+ PHY_TO_DESC(EP4OUT), // bEndpointAddress
+ E_INTERRUPT, // bmAttributes
+ LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB)
+ MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB)
+ 1, // bInterval (milliseconds)
+ };
+
+ // Keyboard + joystick interfaces
+ return configurationDescriptorWithKB;
+ }
+ else
+ {
+ // No keyboard - joystick interface only
+ int cfglenNoKB = ((1 * CONFIGURATION_DESCRIPTOR_LENGTH)
+ + (1 * INTERFACE_DESCRIPTOR_LENGTH)
+ + (1 * HID_DESCRIPTOR_LENGTH)
+ + (2 * ENDPOINT_DESCRIPTOR_LENGTH));
+ static uint8_t configurationDescriptorNoKB[] =
+ {
+ CONFIGURATION_DESCRIPTOR_LENGTH,// bLength
+ CONFIGURATION_DESCRIPTOR, // bDescriptorType
+ LSB(cfglenNoKB), // wTotalLength (LSB)
+ MSB(cfglenNoKB), // wTotalLength (MSB)
+ 0x01, // bNumInterfaces
+ DEFAULT_CONFIGURATION, // bConfigurationValue
+ 0x00, // iConfiguration
+ C_RESERVED | C_SELF_POWERED, // bmAttributes
+ C_POWER(0), // bMaxPowerHello World from Mbed
+
+ INTERFACE_DESCRIPTOR_LENGTH, // bLength
+ INTERFACE_DESCRIPTOR, // bDescriptorType
+ 0x00, // bInterfaceNumber
+ 0x00, // bAlternateSetting
+ 0x02, // bNumEndpoints
+ HID_CLASS, // bInterfaceClass
+ 1, // bInterfaceSubClass
+ 1, // bInterfaceProtocol (keyboard)
+ 0x00, // iInterface
+
+ HID_DESCRIPTOR_LENGTH, // bLength
+ HID_DESCRIPTOR, // bDescriptorType
+ LSB(HID_VERSION_1_11), // bcdHID (LSB)
+ MSB(HID_VERSION_1_11), // bcdHID (MSB)
+ 0x00, // bCountryCode
+ 0x01, // bNumDescriptors
+ REPORT_DESCRIPTOR, // bDescriptorType
+ (uint8_t)(LSB(rptlen0)), // wDescriptorLength (LSB)
+ (uint8_t)(MSB(rptlen0)), // wDescriptorLength (MSB)
+
+ ENDPOINT_DESCRIPTOR_LENGTH, // bLength
+ ENDPOINT_DESCRIPTOR, // bDescriptorType
+ PHY_TO_DESC(EPINT_IN), // bEndpointAddress
+ E_INTERRUPT, // bmAttributes
+ LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB)
+ MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB)
+ 1, // bInterval (milliseconds)
+
+ ENDPOINT_DESCRIPTOR_LENGTH, // bLength
+ ENDPOINT_DESCRIPTOR, // bDescriptorType
+ PHY_TO_DESC(EPINT_OUT), // bEndpointAddress
+ E_INTERRUPT, // bmAttributes
+ LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB)
+ MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB)
+ 1, // bInterval (milliseconds)
+ };
+
+ return configurationDescriptorNoKB;
+ }
+}
+
+// Set the configuration. We need to set up the endpoints for
+// our active interfaces.
+bool USBJoystick::USBCallback_setConfiguration(uint8_t configuration)
+{
+ // we only have one valid configuration
+ if (configuration != DEFAULT_CONFIGURATION)
+ return false;
+
+ // Configure endpoint 1 - we use this in all cases, for either
+ // the combined joystick/ledwiz interface or just the ledwiz interface
+ addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT);
+ addEndpoint(EPINT_OUT, MAX_PACKET_SIZE_EPINT);
+ readStart(EPINT_OUT, MAX_HID_REPORT_SIZE);
+
+ // if the keyboard is enabled, configure endpoint 4 for the kb interface
+ if (useKB)
+ {
+ addEndpoint(EP4IN, MAX_PACKET_SIZE_EPINT);
+ addEndpoint(EP4OUT, MAX_PACKET_SIZE_EPINT);
+ readStart(EP4OUT, MAX_PACKET_SIZE_EPINT);
+ }
+
+ // success
+ return true;
+}
+
+// Handle messages on endpoint 4 - this is the keyboard interface.
+// The host uses this to send updates for the keyboard indicator LEDs
+// (caps lock, num lock, etc). We don't do anything with these, but
+// we at least need to read them to keep the pipe from clogging up.
+bool USBJoystick::EP4_OUT_callback()
+{
+ // read this message
+ uint32_t bytesRead = 0;
+ uint8_t led[65];
+ USBDevice::readEP(EP4OUT, led, &bytesRead, MAX_HID_REPORT_SIZE);
+
+ // start the next read
+ return readStart(EP4OUT, MAX_HID_REPORT_SIZE);
+}
