USB_HID_STACK/USBHID.c
- Committer:
- chris
- Date:
- 2011-10-21
- Revision:
- 1:4d08e0ebf5dd
- Parent:
- 0:e98d1c2b16c6
File content as of revision 1:4d08e0ebf5dd:
/* USBClass_HID.c */ /* Human Interface Device (HID) class */ /* Copyright (c) 2011 ARM Limited. All rights reserved. */ #include "stdint.h" #include "USBEndpoints.h" #include "USBDevice_Types.h" #include "USBBusInterface.h" #include "USBHID.h" static USBHID * instHID; /* Output report from SET_REPORT request */ static HID_REPORT outputReport; void setInstanceHID(USBHID * _inst){ instHID = _inst;}; bool USBClass_HID_request(void) { /* Called in ISR context */ bool success = false; CONTROL_TRANSFER *transfer = USBDevice_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: printf("get report descr\r\n"); if ((instHID->ReportDesc() != NULL) \ && (instHID->ReportDescLength() != 0)) { transfer->remaining = instHID->ReportDescLength(); transfer->ptr = instHID->ReportDesc(); transfer->direction = DEVICE_TO_HOST; success = true; } break; case HID_DESCRIPTOR: /* Find the HID descriptor, after the configuration descriptor */ hidDescriptor = USBDevice_findDescriptor(HID_DESCRIPTOR); if (hidDescriptor != NULL) /* NULL = Not found */ { 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; /* Callback on completion */ success = true; default: break; } } return success; } void USBClass_HID_requestCompleted(void) { /* SET_REPORT request - data is now valid */ instHID->HID_callbackSetReport(&outputReport); } bool USBClass_HID_sendInputReport(uint8_t endpoint, HID_REPORT *report) { EP_STATUS result; if (report->length > MAX_HID_REPORT_SIZE) { return false; } /* Block if not configured */ while (!USBDevice_isConfigured()); /* Send report */ result = USBBusInterface_endpointWrite(endpoint, report->data, report->length); if (result != EP_PENDING) { return false; } /* Wait for completion */ do { result = USBBusInterface_endpointWriteResult(endpoint); } while ((result == EP_PENDING) && USBDevice_isConfigured()); return (result == EP_COMPLETED); } #if 0 bool USBClass_HID_getOutputReport(uint8_t endpoint, HID_REPORT *report) { EP_RESULT result; uint32_t bytesRead = 0; /* Block if not configured */ while (!USBDevice_isConfigured()); /* Read report */ result = USBBusInterface_endpointRead(endpoint, report->data, MAX_HID_REPORT_SIZE); if (result != EP_PENDING) { return false; } /* Wait for completion */ do { result = USBBusInterface_endpointReadResult(endpoint, &bytesRead); } while ((result == EP_PENDING) && USBDevice_isConfigured()); report->length = bytesRead; return (result == EP_SUCCESS); } #endif #define DEFAULT_CONFIGURATION (1) USBHID::USBHID(){ setInstanceHID(this); USBDevice_init(); USBDevice_connect(); } uint16_t USBHID::ReportDescLength() { ReportDesc(); return reportLength; } /* * Route callbacks from lower layers to class(es) */ void USBHID::USBCallback_busReset(void) { /* Called in ISR context */ /* Called by USBDevice layer on bus reset */ /* May be used to reset state */ } bool USBHID::USBCallback_request() { /* 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 */ return USBClass_HID_request(); } void USBHID::USBCallback_requestCompleted() { /* Called in ISR context */ /* Called by USBDevice on Endpoint0 request completion */ /* if the 'notify' flag has been set to true */ /* In this case it is used to indicate that a HID report has */ /* been received from the host on endpoint 0 */ USBClass_HID_requestCompleted(); } void USBHID::HID_callbackSetReport(HID_REPORT *report) { /* Called in ISR context */ /* HID Report received by SET_REPORT request */ /* First byte of data will be the report ID */ } bool USBHID::USBCallback_setConfiguration(uint8_t configuration) { /* Called in ISR context */ /* Set configuration. Return false if the */ /* configuration is not supported. */ if (configuration != DEFAULT_CONFIGURATION) { return false; } /* Configure endpoints > 0 */ USBDevice_addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT); return true; }