USB Mouse (relative) example for mbed NXP LPC11U24 beta
Diff: USB_HID_STACK/USBHID.c
- Revision:
- 0:163560051396
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USB_HID_STACK/USBHID.c Mon Oct 24 10:26:27 2011 +0000 @@ -0,0 +1,222 @@ +/* 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; +} +