ram version see usbmsd_sd.cpp ram ok fs CANNOT be installed - too small use for illustrative purpose only

Dependencies:   USBDevice USBMSD_SD mbed

Fork of USBMSD_SD_HelloWorld_Mbed by Samuel Mokrani

Committer:
samux
Date:
Wed Nov 16 17:17:42 2011 +0000
Revision:
11:a26e7b7a1221
GOOD COMMIT: msd and hid work even on MAC...

Who changed what in which revision?

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