Dependencies:   ChaNFSSD mbed ChaNFS

Committer:
okini3939
Date:
Thu Nov 10 03:20:42 2011 +0000
Revision:
1:efbcfbae4747
Parent:
0:02c293160df3

        

Who changed what in which revision?

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