Embed:
(wiki syntax)
Show/hide line numbers
USBHID.c
00001 /* USBClass_HID.c */ 00002 /* Human Interface Device (HID) class */ 00003 /* Copyright (c) 2011 ARM Limited. All rights reserved. */ 00004 00005 #include "stdint.h" 00006 00007 #include "USBEndpoints.h" 00008 #include "USBDevice_Types.h" 00009 #include "USBBusInterface.h" 00010 #include "USBHID.h" 00011 00012 static USBHID * instHID; 00013 00014 /* Output report from SET_REPORT request */ 00015 static HID_REPORT outputReport; 00016 00017 void setInstanceHID(USBHID * _inst){ instHID = _inst;}; 00018 00019 bool USBClass_HID_request(void) 00020 { 00021 /* Called in ISR context */ 00022 00023 bool success = false; 00024 CONTROL_TRANSFER *transfer = USBDevice_getTransferPtr(); 00025 uint8_t *hidDescriptor; 00026 00027 /* Process additional standard requests */ 00028 00029 if ((transfer->setup.bmRequestType.Type == STANDARD_TYPE)) 00030 { 00031 switch (transfer->setup.bRequest) 00032 { 00033 case GET_DESCRIPTOR: 00034 switch (DESCRIPTOR_TYPE(transfer->setup.wValue)) 00035 { 00036 case REPORT_DESCRIPTOR: 00037 printf("get report descr\r\n"); 00038 if ((instHID->ReportDesc() != NULL) \ 00039 && (instHID->ReportDescLength() != 0)) 00040 { 00041 transfer->remaining = instHID->ReportDescLength(); 00042 transfer->ptr = instHID->ReportDesc(); 00043 transfer->direction = DEVICE_TO_HOST; 00044 success = true; 00045 } 00046 break; 00047 case HID_DESCRIPTOR: 00048 /* Find the HID descriptor, after the configuration descriptor */ 00049 hidDescriptor = USBDevice_findDescriptor(HID_DESCRIPTOR); 00050 if (hidDescriptor != NULL) /* NULL = Not found */ 00051 { 00052 transfer->remaining = HID_DESCRIPTOR_LENGTH; 00053 transfer->ptr = hidDescriptor; 00054 transfer->direction = DEVICE_TO_HOST; 00055 success = true; 00056 } 00057 break; 00058 00059 default: 00060 break; 00061 } 00062 break; 00063 default: 00064 break; 00065 } 00066 } 00067 00068 /* Process class-specific requests */ 00069 00070 if (transfer->setup.bmRequestType.Type == CLASS_TYPE) 00071 { 00072 switch (transfer->setup.bRequest) 00073 { 00074 case SET_REPORT: 00075 /* First byte will be used for report ID */ 00076 outputReport.data[0] = transfer->setup.wValue & 0xff; 00077 outputReport.length = transfer->setup.wLength + 1; 00078 00079 transfer->remaining = sizeof(outputReport.data) - 1; 00080 transfer->ptr = &outputReport.data[1]; 00081 transfer->direction = HOST_TO_DEVICE; 00082 transfer->notify = true; /* Callback on completion */ 00083 success = true; 00084 default: 00085 break; 00086 } 00087 } 00088 00089 return success; 00090 } 00091 00092 void USBClass_HID_requestCompleted(void) 00093 { 00094 /* SET_REPORT request - data is now valid */ 00095 00096 instHID->HID_callbackSetReport(&outputReport); 00097 } 00098 00099 bool USBClass_HID_sendInputReport(uint8_t endpoint, HID_REPORT *report) 00100 { 00101 EP_STATUS result; 00102 00103 if (report->length > MAX_HID_REPORT_SIZE) 00104 { 00105 return false; 00106 } 00107 00108 /* Block if not configured */ 00109 while (!USBDevice_isConfigured()); 00110 00111 /* Send report */ 00112 result = USBBusInterface_endpointWrite(endpoint, report->data, report->length); 00113 00114 if (result != EP_PENDING) 00115 { 00116 return false; 00117 } 00118 00119 /* Wait for completion */ 00120 do { 00121 result = USBBusInterface_endpointWriteResult(endpoint); 00122 } while ((result == EP_PENDING) && USBDevice_isConfigured()); 00123 00124 return (result == EP_COMPLETED); 00125 } 00126 00127 #if 0 00128 bool USBClass_HID_getOutputReport(uint8_t endpoint, HID_REPORT *report) 00129 { 00130 EP_RESULT result; 00131 uint32_t bytesRead = 0; 00132 00133 /* Block if not configured */ 00134 while (!USBDevice_isConfigured()); 00135 00136 /* Read report */ 00137 result = USBBusInterface_endpointRead(endpoint, report->data, MAX_HID_REPORT_SIZE); 00138 00139 if (result != EP_PENDING) 00140 { 00141 return false; 00142 } 00143 00144 /* Wait for completion */ 00145 do { 00146 result = USBBusInterface_endpointReadResult(endpoint, &bytesRead); 00147 } while ((result == EP_PENDING) && USBDevice_isConfigured()); 00148 00149 report->length = bytesRead; 00150 00151 return (result == EP_SUCCESS); 00152 } 00153 #endif 00154 00155 00156 #define DEFAULT_CONFIGURATION (1) 00157 00158 USBHID::USBHID(){ 00159 setInstanceHID(this); 00160 USBDevice_init(); 00161 USBDevice_connect(); 00162 } 00163 00164 uint16_t USBHID::ReportDescLength() { 00165 ReportDesc(); 00166 return reportLength; 00167 } 00168 00169 /* 00170 * Route callbacks from lower layers to class(es) 00171 */ 00172 00173 void USBHID::USBCallback_busReset(void) { 00174 /* Called in ISR context */ 00175 /* Called by USBDevice layer on bus reset */ 00176 00177 /* May be used to reset state */ 00178 } 00179 00180 bool USBHID::USBCallback_request() { 00181 /* Called in ISR context */ 00182 /* Called by USBDevice on Endpoint0 request */ 00183 00184 /* This is used to handle extensions to standard requests */ 00185 /* and class specific requests. */ 00186 00187 /* Return true if class handles this request */ 00188 return USBClass_HID_request(); 00189 } 00190 00191 void USBHID::USBCallback_requestCompleted() { 00192 /* Called in ISR context */ 00193 /* Called by USBDevice on Endpoint0 request completion */ 00194 /* if the 'notify' flag has been set to true */ 00195 00196 /* In this case it is used to indicate that a HID report has */ 00197 /* been received from the host on endpoint 0 */ 00198 00199 USBClass_HID_requestCompleted(); 00200 } 00201 00202 void USBHID::HID_callbackSetReport(HID_REPORT *report) { 00203 /* Called in ISR context */ 00204 00205 /* HID Report received by SET_REPORT request */ 00206 /* First byte of data will be the report ID */ 00207 } 00208 00209 bool USBHID::USBCallback_setConfiguration(uint8_t configuration) { 00210 /* Called in ISR context */ 00211 00212 /* Set configuration. Return false if the */ 00213 /* configuration is not supported. */ 00214 if (configuration != DEFAULT_CONFIGURATION) { 00215 return false; 00216 } 00217 00218 /* Configure endpoints > 0 */ 00219 USBDevice_addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT); 00220 return true; 00221 } 00222
Generated on Fri Jul 15 2022 02:22:27 by 1.7.2