Fork of the official USBDevice library

Fork of USBDevice by mbed official

Committer:
screamer
Date:
Fri Apr 28 17:01:10 2017 +0000
Branch:
device-files
Revision:
76:f0fd8d911b24
Parent:
73:8d28a0cb7b43
Changed the layout of USBDevice implementation for various targets to match mbed-os/targets. This also reduces the amount of files being compiled as USBDevice code for other targets is not compiled.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
screamer 73:8d28a0cb7b43 1 /* Copyright (c) 2010-2011 mbed.org, MIT License
screamer 73:8d28a0cb7b43 2 *
screamer 73:8d28a0cb7b43 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
screamer 73:8d28a0cb7b43 4 * and associated documentation files (the "Software"), to deal in the Software without
screamer 73:8d28a0cb7b43 5 * restriction, including without limitation the rights to use, copy, modify, merge, publish,
screamer 73:8d28a0cb7b43 6 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
screamer 73:8d28a0cb7b43 7 * Software is furnished to do so, subject to the following conditions:
screamer 73:8d28a0cb7b43 8 *
screamer 73:8d28a0cb7b43 9 * The above copyright notice and this permission notice shall be included in all copies or
screamer 73:8d28a0cb7b43 10 * substantial portions of the Software.
screamer 73:8d28a0cb7b43 11 *
screamer 73:8d28a0cb7b43 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
screamer 73:8d28a0cb7b43 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
screamer 73:8d28a0cb7b43 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
screamer 73:8d28a0cb7b43 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
screamer 73:8d28a0cb7b43 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
screamer 73:8d28a0cb7b43 17 */
screamer 73:8d28a0cb7b43 18
screamer 73:8d28a0cb7b43 19 #include "stdint.h"
screamer 73:8d28a0cb7b43 20 #include "USBHAL.h"
screamer 73:8d28a0cb7b43 21 #include "USBHID.h"
screamer 73:8d28a0cb7b43 22
screamer 73:8d28a0cb7b43 23
screamer 73:8d28a0cb7b43 24 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)
screamer 73:8d28a0cb7b43 25 {
screamer 73:8d28a0cb7b43 26 output_length = output_report_length;
screamer 73:8d28a0cb7b43 27 input_length = input_report_length;
screamer 73:8d28a0cb7b43 28 if(connect) {
screamer 73:8d28a0cb7b43 29 USBDevice::connect();
screamer 73:8d28a0cb7b43 30 }
screamer 73:8d28a0cb7b43 31 }
screamer 73:8d28a0cb7b43 32
screamer 73:8d28a0cb7b43 33
screamer 73:8d28a0cb7b43 34 bool USBHID::send(HID_REPORT *report)
screamer 73:8d28a0cb7b43 35 {
screamer 73:8d28a0cb7b43 36 return write(EPINT_IN, report->data, report->length, MAX_HID_REPORT_SIZE);
screamer 73:8d28a0cb7b43 37 }
screamer 73:8d28a0cb7b43 38
screamer 73:8d28a0cb7b43 39 bool USBHID::sendNB(HID_REPORT *report)
screamer 73:8d28a0cb7b43 40 {
screamer 73:8d28a0cb7b43 41 return writeNB(EPINT_IN, report->data, report->length, MAX_HID_REPORT_SIZE);
screamer 73:8d28a0cb7b43 42 }
screamer 73:8d28a0cb7b43 43
screamer 73:8d28a0cb7b43 44
screamer 73:8d28a0cb7b43 45 bool USBHID::read(HID_REPORT *report)
screamer 73:8d28a0cb7b43 46 {
screamer 73:8d28a0cb7b43 47 uint32_t bytesRead = 0;
screamer 73:8d28a0cb7b43 48 bool result;
screamer 73:8d28a0cb7b43 49 result = USBDevice::readEP(EPINT_OUT, report->data, &bytesRead, MAX_HID_REPORT_SIZE);
screamer 73:8d28a0cb7b43 50 if(!readStart(EPINT_OUT, MAX_HID_REPORT_SIZE))
screamer 73:8d28a0cb7b43 51 return false;
screamer 73:8d28a0cb7b43 52 report->length = bytesRead;
screamer 73:8d28a0cb7b43 53 return result;
screamer 73:8d28a0cb7b43 54 }
screamer 73:8d28a0cb7b43 55
screamer 73:8d28a0cb7b43 56
screamer 73:8d28a0cb7b43 57 bool USBHID::readNB(HID_REPORT *report)
screamer 73:8d28a0cb7b43 58 {
screamer 73:8d28a0cb7b43 59 uint32_t bytesRead = 0;
screamer 73:8d28a0cb7b43 60 bool result;
screamer 73:8d28a0cb7b43 61 result = USBDevice::readEP_NB(EPINT_OUT, report->data, &bytesRead, MAX_HID_REPORT_SIZE);
screamer 73:8d28a0cb7b43 62 // if readEP_NB did not succeed, does not issue a readStart
screamer 73:8d28a0cb7b43 63 if (!result)
screamer 73:8d28a0cb7b43 64 return false;
screamer 73:8d28a0cb7b43 65 report->length = bytesRead;
screamer 73:8d28a0cb7b43 66 if(!readStart(EPINT_OUT, MAX_HID_REPORT_SIZE))
screamer 73:8d28a0cb7b43 67 return false;
screamer 73:8d28a0cb7b43 68 return result;
screamer 73:8d28a0cb7b43 69 }
screamer 73:8d28a0cb7b43 70
screamer 73:8d28a0cb7b43 71
screamer 73:8d28a0cb7b43 72 uint16_t USBHID::reportDescLength() {
screamer 73:8d28a0cb7b43 73 reportDesc();
screamer 73:8d28a0cb7b43 74 return reportLength;
screamer 73:8d28a0cb7b43 75 }
screamer 73:8d28a0cb7b43 76
screamer 73:8d28a0cb7b43 77
screamer 73:8d28a0cb7b43 78
screamer 73:8d28a0cb7b43 79 //
screamer 73:8d28a0cb7b43 80 // Route callbacks from lower layers to class(es)
screamer 73:8d28a0cb7b43 81 //
screamer 73:8d28a0cb7b43 82
screamer 73:8d28a0cb7b43 83
screamer 73:8d28a0cb7b43 84 // Called in ISR context
screamer 73:8d28a0cb7b43 85 // Called by USBDevice on Endpoint0 request
screamer 73:8d28a0cb7b43 86 // This is used to handle extensions to standard requests
screamer 73:8d28a0cb7b43 87 // and class specific requests
screamer 73:8d28a0cb7b43 88 // Return true if class handles this request
screamer 73:8d28a0cb7b43 89 bool USBHID::USBCallback_request() {
screamer 73:8d28a0cb7b43 90 bool success = false;
screamer 73:8d28a0cb7b43 91 CONTROL_TRANSFER * transfer = getTransferPtr();
screamer 73:8d28a0cb7b43 92 uint8_t *hidDescriptor;
screamer 73:8d28a0cb7b43 93
screamer 73:8d28a0cb7b43 94 // Process additional standard requests
screamer 73:8d28a0cb7b43 95
screamer 73:8d28a0cb7b43 96 if ((transfer->setup.bmRequestType.Type == STANDARD_TYPE))
screamer 73:8d28a0cb7b43 97 {
screamer 73:8d28a0cb7b43 98 switch (transfer->setup.bRequest)
screamer 73:8d28a0cb7b43 99 {
screamer 73:8d28a0cb7b43 100 case GET_DESCRIPTOR:
screamer 73:8d28a0cb7b43 101 switch (DESCRIPTOR_TYPE(transfer->setup.wValue))
screamer 73:8d28a0cb7b43 102 {
screamer 73:8d28a0cb7b43 103 case REPORT_DESCRIPTOR:
screamer 73:8d28a0cb7b43 104 if ((reportDesc() != NULL) \
screamer 73:8d28a0cb7b43 105 && (reportDescLength() != 0))
screamer 73:8d28a0cb7b43 106 {
screamer 73:8d28a0cb7b43 107 transfer->remaining = reportDescLength();
screamer 73:8d28a0cb7b43 108 transfer->ptr = reportDesc();
screamer 73:8d28a0cb7b43 109 transfer->direction = DEVICE_TO_HOST;
screamer 73:8d28a0cb7b43 110 success = true;
screamer 73:8d28a0cb7b43 111 }
screamer 73:8d28a0cb7b43 112 break;
screamer 73:8d28a0cb7b43 113 case HID_DESCRIPTOR:
screamer 73:8d28a0cb7b43 114 // Find the HID descriptor, after the configuration descriptor
screamer 73:8d28a0cb7b43 115 hidDescriptor = findDescriptor(HID_DESCRIPTOR);
screamer 73:8d28a0cb7b43 116 if (hidDescriptor != NULL)
screamer 73:8d28a0cb7b43 117 {
screamer 73:8d28a0cb7b43 118 transfer->remaining = HID_DESCRIPTOR_LENGTH;
screamer 73:8d28a0cb7b43 119 transfer->ptr = hidDescriptor;
screamer 73:8d28a0cb7b43 120 transfer->direction = DEVICE_TO_HOST;
screamer 73:8d28a0cb7b43 121 success = true;
screamer 73:8d28a0cb7b43 122 }
screamer 73:8d28a0cb7b43 123 break;
screamer 73:8d28a0cb7b43 124
screamer 73:8d28a0cb7b43 125 default:
screamer 73:8d28a0cb7b43 126 break;
screamer 73:8d28a0cb7b43 127 }
screamer 73:8d28a0cb7b43 128 break;
screamer 73:8d28a0cb7b43 129 default:
screamer 73:8d28a0cb7b43 130 break;
screamer 73:8d28a0cb7b43 131 }
screamer 73:8d28a0cb7b43 132 }
screamer 73:8d28a0cb7b43 133
screamer 73:8d28a0cb7b43 134 // Process class-specific requests
screamer 73:8d28a0cb7b43 135
screamer 73:8d28a0cb7b43 136 if (transfer->setup.bmRequestType.Type == CLASS_TYPE)
screamer 73:8d28a0cb7b43 137 {
screamer 73:8d28a0cb7b43 138 switch (transfer->setup.bRequest)
screamer 73:8d28a0cb7b43 139 {
screamer 73:8d28a0cb7b43 140 case SET_REPORT:
screamer 73:8d28a0cb7b43 141 // First byte will be used for report ID
screamer 73:8d28a0cb7b43 142 outputReport.data[0] = transfer->setup.wValue & 0xff;
screamer 73:8d28a0cb7b43 143 outputReport.length = transfer->setup.wLength + 1;
screamer 73:8d28a0cb7b43 144
screamer 73:8d28a0cb7b43 145 transfer->remaining = sizeof(outputReport.data) - 1;
screamer 73:8d28a0cb7b43 146 transfer->ptr = &outputReport.data[1];
screamer 73:8d28a0cb7b43 147 transfer->direction = HOST_TO_DEVICE;
screamer 73:8d28a0cb7b43 148 transfer->notify = true;
screamer 73:8d28a0cb7b43 149 success = true;
screamer 73:8d28a0cb7b43 150 default:
screamer 73:8d28a0cb7b43 151 break;
screamer 73:8d28a0cb7b43 152 }
screamer 73:8d28a0cb7b43 153 }
screamer 73:8d28a0cb7b43 154
screamer 73:8d28a0cb7b43 155 return success;
screamer 73:8d28a0cb7b43 156 }
screamer 73:8d28a0cb7b43 157
screamer 73:8d28a0cb7b43 158
screamer 73:8d28a0cb7b43 159 #define DEFAULT_CONFIGURATION (1)
screamer 73:8d28a0cb7b43 160
screamer 73:8d28a0cb7b43 161
screamer 73:8d28a0cb7b43 162 // Called in ISR context
screamer 73:8d28a0cb7b43 163 // Set configuration. Return false if the
screamer 73:8d28a0cb7b43 164 // configuration is not supported
screamer 73:8d28a0cb7b43 165 bool USBHID::USBCallback_setConfiguration(uint8_t configuration) {
screamer 73:8d28a0cb7b43 166 if (configuration != DEFAULT_CONFIGURATION) {
screamer 73:8d28a0cb7b43 167 return false;
screamer 73:8d28a0cb7b43 168 }
screamer 73:8d28a0cb7b43 169
screamer 73:8d28a0cb7b43 170 // Configure endpoints > 0
screamer 73:8d28a0cb7b43 171 addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT);
screamer 73:8d28a0cb7b43 172 addEndpoint(EPINT_OUT, MAX_PACKET_SIZE_EPINT);
screamer 73:8d28a0cb7b43 173
screamer 73:8d28a0cb7b43 174 // We activate the endpoint to be able to recceive data
screamer 73:8d28a0cb7b43 175 readStart(EPINT_OUT, MAX_PACKET_SIZE_EPINT);
screamer 73:8d28a0cb7b43 176 return true;
screamer 73:8d28a0cb7b43 177 }
screamer 73:8d28a0cb7b43 178
screamer 73:8d28a0cb7b43 179
screamer 73:8d28a0cb7b43 180 uint8_t * USBHID::stringIinterfaceDesc() {
screamer 73:8d28a0cb7b43 181 static uint8_t stringIinterfaceDescriptor[] = {
screamer 73:8d28a0cb7b43 182 0x08, //bLength
screamer 73:8d28a0cb7b43 183 STRING_DESCRIPTOR, //bDescriptorType 0x03
screamer 73:8d28a0cb7b43 184 'H',0,'I',0,'D',0, //bString iInterface - HID
screamer 73:8d28a0cb7b43 185 };
screamer 73:8d28a0cb7b43 186 return stringIinterfaceDescriptor;
screamer 73:8d28a0cb7b43 187 }
screamer 73:8d28a0cb7b43 188
screamer 73:8d28a0cb7b43 189 uint8_t * USBHID::stringIproductDesc() {
screamer 73:8d28a0cb7b43 190 static uint8_t stringIproductDescriptor[] = {
screamer 73:8d28a0cb7b43 191 0x16, //bLength
screamer 73:8d28a0cb7b43 192 STRING_DESCRIPTOR, //bDescriptorType 0x03
screamer 73:8d28a0cb7b43 193 'H',0,'I',0,'D',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0 //bString iProduct - HID device
screamer 73:8d28a0cb7b43 194 };
screamer 73:8d28a0cb7b43 195 return stringIproductDescriptor;
screamer 73:8d28a0cb7b43 196 }
screamer 73:8d28a0cb7b43 197
screamer 73:8d28a0cb7b43 198
screamer 73:8d28a0cb7b43 199
screamer 73:8d28a0cb7b43 200 uint8_t * USBHID::reportDesc() {
screamer 73:8d28a0cb7b43 201 static uint8_t reportDescriptor[] = {
screamer 73:8d28a0cb7b43 202 USAGE_PAGE(2), LSB(0xFFAB), MSB(0xFFAB),
screamer 73:8d28a0cb7b43 203 USAGE(2), LSB(0x0200), MSB(0x0200),
screamer 73:8d28a0cb7b43 204 COLLECTION(1), 0x01, // Collection (Application)
screamer 73:8d28a0cb7b43 205
screamer 73:8d28a0cb7b43 206 REPORT_SIZE(1), 0x08, // 8 bits
screamer 73:8d28a0cb7b43 207 LOGICAL_MINIMUM(1), 0x00,
screamer 73:8d28a0cb7b43 208 LOGICAL_MAXIMUM(1), 0xFF,
screamer 73:8d28a0cb7b43 209
screamer 73:8d28a0cb7b43 210 REPORT_COUNT(1), input_length,
screamer 73:8d28a0cb7b43 211 USAGE(1), 0x01,
screamer 73:8d28a0cb7b43 212 INPUT(1), 0x02, // Data, Var, Abs
screamer 73:8d28a0cb7b43 213
screamer 73:8d28a0cb7b43 214 REPORT_COUNT(1), output_length,
screamer 73:8d28a0cb7b43 215 USAGE(1), 0x02,
screamer 73:8d28a0cb7b43 216 OUTPUT(1), 0x02, // Data, Var, Abs
screamer 73:8d28a0cb7b43 217
screamer 73:8d28a0cb7b43 218 END_COLLECTION(0),
screamer 73:8d28a0cb7b43 219 };
screamer 73:8d28a0cb7b43 220 reportLength = sizeof(reportDescriptor);
screamer 73:8d28a0cb7b43 221 return reportDescriptor;
screamer 73:8d28a0cb7b43 222 }
screamer 73:8d28a0cb7b43 223
screamer 73:8d28a0cb7b43 224 #define DEFAULT_CONFIGURATION (1)
screamer 73:8d28a0cb7b43 225 #define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \
screamer 73:8d28a0cb7b43 226 + (1 * INTERFACE_DESCRIPTOR_LENGTH) \
screamer 73:8d28a0cb7b43 227 + (1 * HID_DESCRIPTOR_LENGTH) \
screamer 73:8d28a0cb7b43 228 + (2 * ENDPOINT_DESCRIPTOR_LENGTH))
screamer 73:8d28a0cb7b43 229
screamer 73:8d28a0cb7b43 230 uint8_t * USBHID::configurationDesc() {
screamer 73:8d28a0cb7b43 231 static uint8_t configurationDescriptor[] = {
screamer 73:8d28a0cb7b43 232 CONFIGURATION_DESCRIPTOR_LENGTH, // bLength
screamer 73:8d28a0cb7b43 233 CONFIGURATION_DESCRIPTOR, // bDescriptorType
screamer 73:8d28a0cb7b43 234 LSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (LSB)
screamer 73:8d28a0cb7b43 235 MSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (MSB)
screamer 73:8d28a0cb7b43 236 0x01, // bNumInterfaces
screamer 73:8d28a0cb7b43 237 DEFAULT_CONFIGURATION, // bConfigurationValue
screamer 73:8d28a0cb7b43 238 0x00, // iConfiguration
screamer 73:8d28a0cb7b43 239 C_RESERVED | C_SELF_POWERED, // bmAttributes
screamer 73:8d28a0cb7b43 240 C_POWER(0), // bMaxPower
screamer 73:8d28a0cb7b43 241
screamer 73:8d28a0cb7b43 242 INTERFACE_DESCRIPTOR_LENGTH, // bLength
screamer 73:8d28a0cb7b43 243 INTERFACE_DESCRIPTOR, // bDescriptorType
screamer 73:8d28a0cb7b43 244 0x00, // bInterfaceNumber
screamer 73:8d28a0cb7b43 245 0x00, // bAlternateSetting
screamer 73:8d28a0cb7b43 246 0x02, // bNumEndpoints
screamer 73:8d28a0cb7b43 247 HID_CLASS, // bInterfaceClass
screamer 73:8d28a0cb7b43 248 HID_SUBCLASS_NONE, // bInterfaceSubClass
screamer 73:8d28a0cb7b43 249 HID_PROTOCOL_NONE, // bInterfaceProtocol
screamer 73:8d28a0cb7b43 250 0x00, // iInterface
screamer 73:8d28a0cb7b43 251
screamer 73:8d28a0cb7b43 252 HID_DESCRIPTOR_LENGTH, // bLength
screamer 73:8d28a0cb7b43 253 HID_DESCRIPTOR, // bDescriptorType
screamer 73:8d28a0cb7b43 254 LSB(HID_VERSION_1_11), // bcdHID (LSB)
screamer 73:8d28a0cb7b43 255 MSB(HID_VERSION_1_11), // bcdHID (MSB)
screamer 73:8d28a0cb7b43 256 0x00, // bCountryCode
screamer 73:8d28a0cb7b43 257 0x01, // bNumDescriptors
screamer 73:8d28a0cb7b43 258 REPORT_DESCRIPTOR, // bDescriptorType
screamer 73:8d28a0cb7b43 259 (uint8_t)(LSB(reportDescLength())), // wDescriptorLength (LSB)
screamer 73:8d28a0cb7b43 260 (uint8_t)(MSB(reportDescLength())), // wDescriptorLength (MSB)
screamer 73:8d28a0cb7b43 261
screamer 73:8d28a0cb7b43 262 ENDPOINT_DESCRIPTOR_LENGTH, // bLength
screamer 73:8d28a0cb7b43 263 ENDPOINT_DESCRIPTOR, // bDescriptorType
screamer 73:8d28a0cb7b43 264 PHY_TO_DESC(EPINT_IN), // bEndpointAddress
screamer 73:8d28a0cb7b43 265 E_INTERRUPT, // bmAttributes
screamer 73:8d28a0cb7b43 266 LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB)
screamer 73:8d28a0cb7b43 267 MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB)
screamer 73:8d28a0cb7b43 268 1, // bInterval (milliseconds)
screamer 73:8d28a0cb7b43 269
screamer 73:8d28a0cb7b43 270 ENDPOINT_DESCRIPTOR_LENGTH, // bLength
screamer 73:8d28a0cb7b43 271 ENDPOINT_DESCRIPTOR, // bDescriptorType
screamer 73:8d28a0cb7b43 272 PHY_TO_DESC(EPINT_OUT), // bEndpointAddress
screamer 73:8d28a0cb7b43 273 E_INTERRUPT, // bmAttributes
screamer 73:8d28a0cb7b43 274 LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB)
screamer 73:8d28a0cb7b43 275 MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB)
screamer 73:8d28a0cb7b43 276 1, // bInterval (milliseconds)
screamer 73:8d28a0cb7b43 277 };
screamer 73:8d28a0cb7b43 278 return configurationDescriptor;
screamer 73:8d28a0cb7b43 279 }