library

Dependents:   USB_CDC_MSD_Hello

Committer:
sherckuith
Date:
Fri Aug 24 02:01:51 2012 +0000
Revision:
0:d5bb9a9c3e24
[mbed] converted /USB_CDC_MSD_Hello/USBDevice

Who changed what in which revision?

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