USBAudio example using a microphone

Dependencies:   USBDevice mbed

Committer:
samux
Date:
Fri Dec 16 12:31:41 2011 +0000
Revision:
0:539ec61e1fbb
works with m0 and m3 (sinus) but the code is different to have the same result...

Who changed what in which revision?

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