SD card interface

Committer:
lharoon
Date:
Mon Oct 08 11:14:07 2012 +0000
Revision:
0:22612ae617a0
1st edition

Who changed what in which revision?

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