uint8_t * USBMouse::configurationDesc() { static uint8_t configurationDescriptor[] = { CONFIGURATION_DESCRIPTOR_LENGTH, // bLength CONFIGURATION_DESCRIPTOR, // bDescriptorType LSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (LSB) MSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (MSB) 0x01, // bNumInterfaces DEFAULT_CONFIGURATION, // bConfigurationValue 0x00, // iConfiguration C_RESERVED | C_SELF_POWERED, // bmAttributes C_POWER(0), // bMaxPower INTERFACE_DESCRIPTOR_LENGTH, // bLength INTERFACE_DESCRIPTOR, // bDescriptorType 0x00, // bInterfaceNumber 0x00, // bAlternateSetting 0x02, // bNumEndpoints HID_CLASS, // bInterfaceClass HID_SUBCLASS_BOOT, // bInterfaceSubClass HID_PROTOCOL_MOUSE, // 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 (uint8_t)(LSB(reportDescLength())), // wDescriptorLength (LSB) (uint8_t)(MSB(reportDescLength())), // 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 configurationDescriptor; }
// Called in ISR context // Called by USBDevice on Endpoint0 request // This is used to handle extensions to standard requests // and class specific requests // Return true if class handles this request bool USBHID::USBCallback_request() { bool success = false; CONTROL_TRANSFER * transfer = getTransferPtr(); uint8_t *hidDescriptor; // Process additional standard requests if ((transfer->setup.bmRequestType.Type == STANDARD_TYPE)) { switch (transfer->setup.bRequest) { case GET_DESCRIPTOR: switch (DESCRIPTOR_TYPE(transfer->setup.wValue)) { case REPORT_DESCRIPTOR: if ((reportDesc() != NULL) \ && (reportDescLength() != 0)) { transfer->remaining = reportDescLength(); transfer->ptr = reportDesc(); transfer->direction = DEVICE_TO_HOST; success = true; } break; case HID_DESCRIPTOR: // Find the HID descriptor, after the configuration descriptor hidDescriptor = findDescriptor(HID_DESCRIPTOR); if (hidDescriptor != NULL) { transfer->remaining = HID_DESCRIPTOR_LENGTH; transfer->ptr = hidDescriptor; transfer->direction = DEVICE_TO_HOST; success = true; } break; default: break; } break; default: break; } } // Process class-specific requests if (transfer->setup.bmRequestType.Type == CLASS_TYPE) { switch (transfer->setup.bRequest) { case SET_REPORT: // First byte will be used for report ID outputReport.data[0] = transfer->setup.wValue & 0xff; outputReport.length = transfer->setup.wLength + 1; transfer->remaining = sizeof(outputReport.data) - 1; transfer->ptr = &outputReport.data[1]; transfer->direction = HOST_TO_DEVICE; transfer->notify = true; success = true; default: break; } } return success; }