B. H. / Mbed 2 deprecated trolololol

Dependencies:   mbed

Committer:
znuh
Date:
Tue Nov 29 21:26:20 2011 +0000
Revision:
0:505207de8566

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
znuh 0:505207de8566 1 /* USBHID.c */
znuh 0:505207de8566 2 /* Human Interface Device (HID) class */
znuh 0:505207de8566 3 /* Copyright (c) 2011 ARM Limited. All rights reserved. */
znuh 0:505207de8566 4
znuh 0:505207de8566 5 #include "stdint.h"
znuh 0:505207de8566 6 #include "USBBusInterface.h"
znuh 0:505207de8566 7 #include "USBHID.h"
znuh 0:505207de8566 8
znuh 0:505207de8566 9 /* Output report from SET_REPORT request */
znuh 0:505207de8566 10 static HID_REPORT outputReport;
znuh 0:505207de8566 11
znuh 0:505207de8566 12 bool USBHID::USBClass_HID_request(void)
znuh 0:505207de8566 13 {
znuh 0:505207de8566 14 /* Called in ISR context */
znuh 0:505207de8566 15
znuh 0:505207de8566 16 bool success = false;
znuh 0:505207de8566 17 CONTROL_TRANSFER *transfer = USBDevice_getTransferPtr();
znuh 0:505207de8566 18 uint8_t *hidDescriptor;
znuh 0:505207de8566 19
znuh 0:505207de8566 20 /* Process additional standard requests */
znuh 0:505207de8566 21
znuh 0:505207de8566 22 if ((transfer->setup.bmRequestType.Type == STANDARD_TYPE))
znuh 0:505207de8566 23 {
znuh 0:505207de8566 24 switch (transfer->setup.bRequest)
znuh 0:505207de8566 25 {
znuh 0:505207de8566 26 case GET_DESCRIPTOR:
znuh 0:505207de8566 27 switch (DESCRIPTOR_TYPE(transfer->setup.wValue))
znuh 0:505207de8566 28 {
znuh 0:505207de8566 29 case REPORT_DESCRIPTOR:
znuh 0:505207de8566 30 if ((ReportDesc() != NULL) \
znuh 0:505207de8566 31 && (ReportDescLength() != 0))
znuh 0:505207de8566 32 {
znuh 0:505207de8566 33 transfer->remaining = ReportDescLength();
znuh 0:505207de8566 34 transfer->ptr = ReportDesc();
znuh 0:505207de8566 35 transfer->direction = DEVICE_TO_HOST;
znuh 0:505207de8566 36 success = true;
znuh 0:505207de8566 37 }
znuh 0:505207de8566 38 break;
znuh 0:505207de8566 39 case HID_DESCRIPTOR:
znuh 0:505207de8566 40 /* Find the HID descriptor, after the configuration descriptor */
znuh 0:505207de8566 41 hidDescriptor = USBDevice_findDescriptor(HID_DESCRIPTOR);
znuh 0:505207de8566 42 if (hidDescriptor != NULL) /* NULL = Not found */
znuh 0:505207de8566 43 {
znuh 0:505207de8566 44 transfer->remaining = HID_DESCRIPTOR_LENGTH;
znuh 0:505207de8566 45 transfer->ptr = hidDescriptor;
znuh 0:505207de8566 46 transfer->direction = DEVICE_TO_HOST;
znuh 0:505207de8566 47 success = true;
znuh 0:505207de8566 48 }
znuh 0:505207de8566 49 break;
znuh 0:505207de8566 50
znuh 0:505207de8566 51 default:
znuh 0:505207de8566 52 break;
znuh 0:505207de8566 53 }
znuh 0:505207de8566 54 break;
znuh 0:505207de8566 55 default:
znuh 0:505207de8566 56 break;
znuh 0:505207de8566 57 }
znuh 0:505207de8566 58 }
znuh 0:505207de8566 59
znuh 0:505207de8566 60 /* Process class-specific requests */
znuh 0:505207de8566 61
znuh 0:505207de8566 62 if (transfer->setup.bmRequestType.Type == CLASS_TYPE)
znuh 0:505207de8566 63 {
znuh 0:505207de8566 64 switch (transfer->setup.bRequest)
znuh 0:505207de8566 65 {
znuh 0:505207de8566 66 case SET_REPORT:
znuh 0:505207de8566 67 /* First byte will be used for report ID */
znuh 0:505207de8566 68 outputReport.data[0] = transfer->setup.wValue & 0xff;
znuh 0:505207de8566 69 outputReport.length = transfer->setup.wLength + 1;
znuh 0:505207de8566 70
znuh 0:505207de8566 71 transfer->remaining = sizeof(outputReport.data) - 1;
znuh 0:505207de8566 72 transfer->ptr = &outputReport.data[1];
znuh 0:505207de8566 73 transfer->direction = HOST_TO_DEVICE;
znuh 0:505207de8566 74 transfer->notify = true; /* Callback on completion */
znuh 0:505207de8566 75 success = true;
znuh 0:505207de8566 76 default:
znuh 0:505207de8566 77 break;
znuh 0:505207de8566 78 }
znuh 0:505207de8566 79 }
znuh 0:505207de8566 80
znuh 0:505207de8566 81 return success;
znuh 0:505207de8566 82 }
znuh 0:505207de8566 83
znuh 0:505207de8566 84 void USBHID::USBClass_HID_requestCompleted(void)
znuh 0:505207de8566 85 {
znuh 0:505207de8566 86 /* SET_REPORT request - data is now valid */
znuh 0:505207de8566 87
znuh 0:505207de8566 88 HID_callbackSetReport(&outputReport);
znuh 0:505207de8566 89 }
znuh 0:505207de8566 90
znuh 0:505207de8566 91 bool USBHID::USBHID_send(uint8_t endpoint, HID_REPORT *report)
znuh 0:505207de8566 92 {
znuh 0:505207de8566 93 return USBDevice_write(endpoint, report->data, report->length, MAX_HID_REPORT_SIZE);
znuh 0:505207de8566 94 }
znuh 0:505207de8566 95
znuh 0:505207de8566 96 bool USBHID::USBHID_read(uint8_t endpoint, HID_REPORT *report)
znuh 0:505207de8566 97 {
znuh 0:505207de8566 98 uint16_t bytesRead = 0;
znuh 0:505207de8566 99 bool result;
znuh 0:505207de8566 100 if(!USBDevice_readStart(endpoint, MAX_HID_REPORT_SIZE))
znuh 0:505207de8566 101 return false;
znuh 0:505207de8566 102 result = USBDevice_read(endpoint, report->data, &bytesRead, MAX_HID_REPORT_SIZE);
znuh 0:505207de8566 103 report->length = bytesRead;
znuh 0:505207de8566 104 return result;
znuh 0:505207de8566 105 }
znuh 0:505207de8566 106
znuh 0:505207de8566 107 bool USBHID::USBHID_readNB(uint8_t endpoint, HID_REPORT *report)
znuh 0:505207de8566 108 {
znuh 0:505207de8566 109 uint16_t bytesRead = 0;
znuh 0:505207de8566 110 bool result;
znuh 0:505207de8566 111 if(!USBDevice_readStart(endpoint, MAX_HID_REPORT_SIZE))
znuh 0:505207de8566 112 return false;
znuh 0:505207de8566 113 result = USBDevice_readNB(endpoint, report->data, &bytesRead, MAX_HID_REPORT_SIZE);
znuh 0:505207de8566 114 report->length = bytesRead;
znuh 0:505207de8566 115 return result;
znuh 0:505207de8566 116 }
znuh 0:505207de8566 117
znuh 0:505207de8566 118
znuh 0:505207de8566 119 #define DEFAULT_CONFIGURATION (1)
znuh 0:505207de8566 120
znuh 0:505207de8566 121 USBHID::USBHID(uint16_t vendor_id, uint16_t product_id, uint16_t product_release): USBDevice(vendor_id, product_id, product_release)
znuh 0:505207de8566 122 {
znuh 0:505207de8566 123 USBDevice_init();
znuh 0:505207de8566 124 USBDevice_connect();
znuh 0:505207de8566 125 }
znuh 0:505207de8566 126
znuh 0:505207de8566 127 uint16_t USBHID::ReportDescLength() {
znuh 0:505207de8566 128 ReportDesc();
znuh 0:505207de8566 129 return reportLength;
znuh 0:505207de8566 130 }
znuh 0:505207de8566 131
znuh 0:505207de8566 132 /*
znuh 0:505207de8566 133 * Route callbacks from lower layers to class(es)
znuh 0:505207de8566 134 */
znuh 0:505207de8566 135
znuh 0:505207de8566 136 void USBHID::USBCallback_busReset(void) {
znuh 0:505207de8566 137 /* Called in ISR context */
znuh 0:505207de8566 138 /* Called by USBDevice layer on bus reset */
znuh 0:505207de8566 139
znuh 0:505207de8566 140 /* May be used to reset state */
znuh 0:505207de8566 141 }
znuh 0:505207de8566 142
znuh 0:505207de8566 143 bool USBHID::USBCallback_request() {
znuh 0:505207de8566 144 /* Called in ISR context */
znuh 0:505207de8566 145 /* Called by USBDevice on Endpoint0 request */
znuh 0:505207de8566 146
znuh 0:505207de8566 147 /* This is used to handle extensions to standard requests */
znuh 0:505207de8566 148 /* and class specific requests. */
znuh 0:505207de8566 149
znuh 0:505207de8566 150 /* Return true if class handles this request */
znuh 0:505207de8566 151 return USBClass_HID_request();
znuh 0:505207de8566 152 }
znuh 0:505207de8566 153
znuh 0:505207de8566 154 void USBHID::USBCallback_requestCompleted() {
znuh 0:505207de8566 155 /* Called in ISR context */
znuh 0:505207de8566 156 /* Called by USBDevice on Endpoint0 request completion */
znuh 0:505207de8566 157 /* if the 'notify' flag has been set to true */
znuh 0:505207de8566 158
znuh 0:505207de8566 159 /* In this case it is used to indicate that a HID report has */
znuh 0:505207de8566 160 /* been received from the host on endpoint 0 */
znuh 0:505207de8566 161
znuh 0:505207de8566 162 USBClass_HID_requestCompleted();
znuh 0:505207de8566 163 }
znuh 0:505207de8566 164
znuh 0:505207de8566 165 void USBHID::HID_callbackSetReport(HID_REPORT *report) {
znuh 0:505207de8566 166 /* Called in ISR context */
znuh 0:505207de8566 167
znuh 0:505207de8566 168 /* HID Report received by SET_REPORT request */
znuh 0:505207de8566 169 /* First byte of data will be the report ID */
znuh 0:505207de8566 170 }
znuh 0:505207de8566 171
znuh 0:505207de8566 172 bool USBHID::USBCallback_setConfiguration(uint8_t configuration) {
znuh 0:505207de8566 173 /* Called in ISR context */
znuh 0:505207de8566 174
znuh 0:505207de8566 175 /* Set configuration. Return false if the */
znuh 0:505207de8566 176 /* configuration is not supported. */
znuh 0:505207de8566 177 if (configuration != DEFAULT_CONFIGURATION) {
znuh 0:505207de8566 178 return false;
znuh 0:505207de8566 179 }
znuh 0:505207de8566 180
znuh 0:505207de8566 181 /* Configure endpoints > 0 */
znuh 0:505207de8566 182 USBDevice_addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT);
znuh 0:505207de8566 183 return true;
znuh 0:505207de8566 184 }
znuh 0:505207de8566 185
znuh 0:505207de8566 186 uint8_t * USBHID::StringIinterfaceDesc() {
znuh 0:505207de8566 187 static uint8_t stringIinterfaceDescriptor[] = {
znuh 0:505207de8566 188 0x08, /*bLength*/
znuh 0:505207de8566 189 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
znuh 0:505207de8566 190 'H',0,'I',0,'D',0, /*bString iInterface - HID*/
znuh 0:505207de8566 191 };
znuh 0:505207de8566 192 return stringIinterfaceDescriptor;
znuh 0:505207de8566 193 }
znuh 0:505207de8566 194
znuh 0:505207de8566 195 uint8_t * USBHID::StringIproductDesc() {
znuh 0:505207de8566 196 static uint8_t stringIproductDescriptor[] = {
znuh 0:505207de8566 197 0x16, /*bLength*/
znuh 0:505207de8566 198 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
znuh 0:505207de8566 199 'H',0,'I',0,'D',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0 /*bString iProduct - HID device*/
znuh 0:505207de8566 200 };
znuh 0:505207de8566 201 return stringIproductDescriptor;
znuh 0:505207de8566 202 }
znuh 0:505207de8566 203
znuh 0:505207de8566 204 #define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \
znuh 0:505207de8566 205 + (1 * INTERFACE_DESCRIPTOR_LENGTH) \
znuh 0:505207de8566 206 + (1 * HID_DESCRIPTOR_LENGTH) \
znuh 0:505207de8566 207 + (1 * ENDPOINT_DESCRIPTOR_LENGTH))
znuh 0:505207de8566 208
znuh 0:505207de8566 209 uint8_t * USBHID::ConfigurationDesc() {
znuh 0:505207de8566 210 static uint8_t configurationDescriptor[] = {
znuh 0:505207de8566 211 CONFIGURATION_DESCRIPTOR_LENGTH,/* bLength */
znuh 0:505207de8566 212 CONFIGURATION_DESCRIPTOR, /* bDescriptorType */
znuh 0:505207de8566 213 LSB(TOTAL_DESCRIPTOR_LENGTH), /* wTotalLength (LSB) */
znuh 0:505207de8566 214 MSB(TOTAL_DESCRIPTOR_LENGTH), /* wTotalLength (MSB) */
znuh 0:505207de8566 215 0x01, /* bNumInterfaces */
znuh 0:505207de8566 216 DEFAULT_CONFIGURATION, /* bConfigurationValue */
znuh 0:505207de8566 217 0x00, /* iConfiguration */
znuh 0:505207de8566 218 C_RESERVED | C_SELF_POWERED, /* bmAttributes */
znuh 0:505207de8566 219 C_POWER(0), /* bMaxPower */
znuh 0:505207de8566 220
znuh 0:505207de8566 221 INTERFACE_DESCRIPTOR_LENGTH, /* bLength */
znuh 0:505207de8566 222 INTERFACE_DESCRIPTOR, /* bDescriptorType */
znuh 0:505207de8566 223 0x00, /* bInterfaceNumber */
znuh 0:505207de8566 224 0x00, /* bAlternateSetting */
znuh 0:505207de8566 225 0x01, /* bNumEndpoints */
znuh 0:505207de8566 226 HID_CLASS, /* bInterfaceClass */
znuh 0:505207de8566 227 HID_SUBCLASS_NONE, /* bInterfaceSubClass */
znuh 0:505207de8566 228 HID_PROTOCOL_NONE, /* bInterfaceProtocol */
znuh 0:505207de8566 229 0x00, /* iInterface */
znuh 0:505207de8566 230
znuh 0:505207de8566 231 HID_DESCRIPTOR_LENGTH, /* bLength */
znuh 0:505207de8566 232 HID_DESCRIPTOR, /* bDescriptorType */
znuh 0:505207de8566 233 LSB(HID_VERSION_1_11), /* bcdHID (LSB) */
znuh 0:505207de8566 234 MSB(HID_VERSION_1_11), /* bcdHID (MSB) */
znuh 0:505207de8566 235 0x00, /* bCountryCode */
znuh 0:505207de8566 236 0x01, /* bNumDescriptors */
znuh 0:505207de8566 237 REPORT_DESCRIPTOR, /* bDescriptorType */
znuh 0:505207de8566 238 LSB(this->ReportDescLength()), /* wDescriptorLength (LSB) */
znuh 0:505207de8566 239 MSB(this->ReportDescLength()), /* wDescriptorLength (MSB) */
znuh 0:505207de8566 240
znuh 0:505207de8566 241 ENDPOINT_DESCRIPTOR_LENGTH, /* bLength */
znuh 0:505207de8566 242 ENDPOINT_DESCRIPTOR, /* bDescriptorType */
znuh 0:505207de8566 243 PHY_TO_DESC(EPINT_IN), /* bEndpointAddress */
znuh 0:505207de8566 244 E_INTERRUPT, /* bmAttributes */
znuh 0:505207de8566 245 LSB(MAX_PACKET_SIZE_EPINT), /* wMaxPacketSize (LSB) */
znuh 0:505207de8566 246 MSB(MAX_PACKET_SIZE_EPINT), /* wMaxPacketSize (MSB) */
znuh 0:505207de8566 247 10, /* bInterval (milliseconds) */
znuh 0:505207de8566 248 };
znuh 0:505207de8566 249 return configurationDescriptor;
znuh 0:505207de8566 250 }
znuh 0:505207de8566 251