USBDevice

Dependents:   QEI_X1_LCD_test3 macnica_test

Committer:
toucyy
Date:
Thu Apr 18 07:49:37 2013 +0000
Revision:
0:2d8d0b73e1ff
[mbed] converted /QEI_HelloWorld/USBDevice

Who changed what in which revision?

UserRevisionLine numberNew contents of line
toucyy 0:2d8d0b73e1ff 1 /* Copyright (c) 2010-2011 mbed.org, MIT License
toucyy 0:2d8d0b73e1ff 2 *
toucyy 0:2d8d0b73e1ff 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
toucyy 0:2d8d0b73e1ff 4 * and associated documentation files (the "Software"), to deal in the Software without
toucyy 0:2d8d0b73e1ff 5 * restriction, including without limitation the rights to use, copy, modify, merge, publish,
toucyy 0:2d8d0b73e1ff 6 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
toucyy 0:2d8d0b73e1ff 7 * Software is furnished to do so, subject to the following conditions:
toucyy 0:2d8d0b73e1ff 8 *
toucyy 0:2d8d0b73e1ff 9 * The above copyright notice and this permission notice shall be included in all copies or
toucyy 0:2d8d0b73e1ff 10 * substantial portions of the Software.
toucyy 0:2d8d0b73e1ff 11 *
toucyy 0:2d8d0b73e1ff 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
toucyy 0:2d8d0b73e1ff 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
toucyy 0:2d8d0b73e1ff 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
toucyy 0:2d8d0b73e1ff 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
toucyy 0:2d8d0b73e1ff 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
toucyy 0:2d8d0b73e1ff 17 */
toucyy 0:2d8d0b73e1ff 18
toucyy 0:2d8d0b73e1ff 19 #include "stdint.h"
toucyy 0:2d8d0b73e1ff 20 #include "USBAudio.h"
toucyy 0:2d8d0b73e1ff 21 #include "USBBusInterface.h"
toucyy 0:2d8d0b73e1ff 22 #include "USBAudio_Types.h"
toucyy 0:2d8d0b73e1ff 23
toucyy 0:2d8d0b73e1ff 24
toucyy 0:2d8d0b73e1ff 25
toucyy 0:2d8d0b73e1ff 26 USBAudio::USBAudio(uint32_t frequency, uint8_t channel_nb, uint16_t vendor_id, uint16_t product_id, uint16_t product_release): USBDevice(vendor_id, product_id, product_release) {
toucyy 0:2d8d0b73e1ff 27 mute = 0;
toucyy 0:2d8d0b73e1ff 28 volCur = 0x0080;
toucyy 0:2d8d0b73e1ff 29 volMin = 0x0000;
toucyy 0:2d8d0b73e1ff 30 volMax = 0x0100;
toucyy 0:2d8d0b73e1ff 31 volRes = 0x0004;
toucyy 0:2d8d0b73e1ff 32 available = false;
toucyy 0:2d8d0b73e1ff 33
toucyy 0:2d8d0b73e1ff 34 FREQ = frequency;
toucyy 0:2d8d0b73e1ff 35
toucyy 0:2d8d0b73e1ff 36 this->channel_nb = channel_nb;
toucyy 0:2d8d0b73e1ff 37
toucyy 0:2d8d0b73e1ff 38 // stereo -> *2, mono -> *1
toucyy 0:2d8d0b73e1ff 39 PACKET_SIZE_ISO = (FREQ / 500) * channel_nb;
toucyy 0:2d8d0b73e1ff 40
toucyy 0:2d8d0b73e1ff 41 // STEREO -> left and right
toucyy 0:2d8d0b73e1ff 42 channel_config = (channel_nb == 1) ? CHANNEL_M : CHANNEL_L + CHANNEL_R;
toucyy 0:2d8d0b73e1ff 43
toucyy 0:2d8d0b73e1ff 44 SOF_handler = false;
toucyy 0:2d8d0b73e1ff 45
toucyy 0:2d8d0b73e1ff 46 buf_stream = NULL;
toucyy 0:2d8d0b73e1ff 47
toucyy 0:2d8d0b73e1ff 48 // connect the device
toucyy 0:2d8d0b73e1ff 49 USBDevice::connect();
toucyy 0:2d8d0b73e1ff 50 }
toucyy 0:2d8d0b73e1ff 51
toucyy 0:2d8d0b73e1ff 52 bool USBAudio::read(uint8_t * buf) {
toucyy 0:2d8d0b73e1ff 53 buf_stream = buf;
toucyy 0:2d8d0b73e1ff 54 while (!available);
toucyy 0:2d8d0b73e1ff 55 available = false;
toucyy 0:2d8d0b73e1ff 56 buf_stream = NULL;
toucyy 0:2d8d0b73e1ff 57 return true;
toucyy 0:2d8d0b73e1ff 58 }
toucyy 0:2d8d0b73e1ff 59
toucyy 0:2d8d0b73e1ff 60 bool USBAudio::readNB(uint8_t * buf) {
toucyy 0:2d8d0b73e1ff 61 buf_stream = buf;
toucyy 0:2d8d0b73e1ff 62 SOF_handler = false;
toucyy 0:2d8d0b73e1ff 63 while (!SOF_handler);
toucyy 0:2d8d0b73e1ff 64 if (available) {
toucyy 0:2d8d0b73e1ff 65 available = false;
toucyy 0:2d8d0b73e1ff 66 buf_stream = NULL;
toucyy 0:2d8d0b73e1ff 67 return true;
toucyy 0:2d8d0b73e1ff 68 }
toucyy 0:2d8d0b73e1ff 69 buf_stream = NULL;
toucyy 0:2d8d0b73e1ff 70 return false;
toucyy 0:2d8d0b73e1ff 71 }
toucyy 0:2d8d0b73e1ff 72
toucyy 0:2d8d0b73e1ff 73
toucyy 0:2d8d0b73e1ff 74 float USBAudio::getVolume() {
toucyy 0:2d8d0b73e1ff 75 return (mute) ? 0.0 : (float)volCur/(float)volMax;
toucyy 0:2d8d0b73e1ff 76 }
toucyy 0:2d8d0b73e1ff 77
toucyy 0:2d8d0b73e1ff 78
toucyy 0:2d8d0b73e1ff 79 // Called in ISR context on each start of frame
toucyy 0:2d8d0b73e1ff 80 void USBAudio::SOF(int frameNumber) {
toucyy 0:2d8d0b73e1ff 81 uint16_t size = 0;
toucyy 0:2d8d0b73e1ff 82
toucyy 0:2d8d0b73e1ff 83 // read the isochronous endpoint
toucyy 0:2d8d0b73e1ff 84 if (buf_stream != NULL) {
toucyy 0:2d8d0b73e1ff 85 USBDevice::readEP_NB(EP3OUT, buf_stream, &size, PACKET_SIZE_ISO);
toucyy 0:2d8d0b73e1ff 86 }
toucyy 0:2d8d0b73e1ff 87
toucyy 0:2d8d0b73e1ff 88 // if we read something, modify the flag "available"
toucyy 0:2d8d0b73e1ff 89 available = (size) ? true : false;
toucyy 0:2d8d0b73e1ff 90
toucyy 0:2d8d0b73e1ff 91 // activate readings on the isochronous
toucyy 0:2d8d0b73e1ff 92 readStart(EP3OUT, PACKET_SIZE_ISO);
toucyy 0:2d8d0b73e1ff 93
toucyy 0:2d8d0b73e1ff 94 SOF_handler = true;
toucyy 0:2d8d0b73e1ff 95 }
toucyy 0:2d8d0b73e1ff 96
toucyy 0:2d8d0b73e1ff 97
toucyy 0:2d8d0b73e1ff 98 // Called in ISR context
toucyy 0:2d8d0b73e1ff 99 // Set configuration. Return false if the configuration is not supported.
toucyy 0:2d8d0b73e1ff 100 bool USBAudio::USBCallback_setConfiguration(uint8_t configuration) {
toucyy 0:2d8d0b73e1ff 101 if (configuration != DEFAULT_CONFIGURATION) {
toucyy 0:2d8d0b73e1ff 102 return false;
toucyy 0:2d8d0b73e1ff 103 }
toucyy 0:2d8d0b73e1ff 104
toucyy 0:2d8d0b73e1ff 105 // Configure isochronous endpoint
toucyy 0:2d8d0b73e1ff 106 realiseEndpoint(EP3OUT, PACKET_SIZE_ISO, ISOCHRONOUS);
toucyy 0:2d8d0b73e1ff 107
toucyy 0:2d8d0b73e1ff 108 // activate readings on this endpoint
toucyy 0:2d8d0b73e1ff 109 readStart(EP3OUT, PACKET_SIZE_ISO);
toucyy 0:2d8d0b73e1ff 110 return true;
toucyy 0:2d8d0b73e1ff 111 }
toucyy 0:2d8d0b73e1ff 112
toucyy 0:2d8d0b73e1ff 113
toucyy 0:2d8d0b73e1ff 114 // Called in ISR context
toucyy 0:2d8d0b73e1ff 115 // Set alternate setting. Return false if the alternate setting is not supported
toucyy 0:2d8d0b73e1ff 116 bool USBAudio::USBCallback_setInterface(uint16_t interface, uint8_t alternate) {
toucyy 0:2d8d0b73e1ff 117 if (interface == 0 && alternate == 0) {
toucyy 0:2d8d0b73e1ff 118 return true;
toucyy 0:2d8d0b73e1ff 119 }
toucyy 0:2d8d0b73e1ff 120 if (interface == 1 && (alternate == 0 || alternate == 1)) {
toucyy 0:2d8d0b73e1ff 121 return true;
toucyy 0:2d8d0b73e1ff 122 }
toucyy 0:2d8d0b73e1ff 123 return false;
toucyy 0:2d8d0b73e1ff 124 }
toucyy 0:2d8d0b73e1ff 125
toucyy 0:2d8d0b73e1ff 126
toucyy 0:2d8d0b73e1ff 127
toucyy 0:2d8d0b73e1ff 128 // Called in ISR context
toucyy 0:2d8d0b73e1ff 129 // Called by USBDevice on Endpoint0 request
toucyy 0:2d8d0b73e1ff 130 // This is used to handle extensions to standard requests and class specific requests.
toucyy 0:2d8d0b73e1ff 131 // Return true if class handles this request
toucyy 0:2d8d0b73e1ff 132 bool USBAudio::USBCallback_request() {
toucyy 0:2d8d0b73e1ff 133 bool success = false;
toucyy 0:2d8d0b73e1ff 134 CONTROL_TRANSFER * transfer = getTransferPtr();
toucyy 0:2d8d0b73e1ff 135
toucyy 0:2d8d0b73e1ff 136 // Process class-specific requests
toucyy 0:2d8d0b73e1ff 137 if (transfer->setup.bmRequestType.Type == CLASS_TYPE) {
toucyy 0:2d8d0b73e1ff 138
toucyy 0:2d8d0b73e1ff 139 // Feature Unit: Interface = 0, ID = 2
toucyy 0:2d8d0b73e1ff 140 if (transfer->setup.wIndex == 0x0200) {
toucyy 0:2d8d0b73e1ff 141
toucyy 0:2d8d0b73e1ff 142 // Master Channel
toucyy 0:2d8d0b73e1ff 143 if ((transfer->setup.wValue & 0xff) == 0) {
toucyy 0:2d8d0b73e1ff 144
toucyy 0:2d8d0b73e1ff 145 switch (transfer->setup.wValue >> 8) {
toucyy 0:2d8d0b73e1ff 146 case MUTE_CONTROL:
toucyy 0:2d8d0b73e1ff 147 switch (transfer->setup.bRequest) {
toucyy 0:2d8d0b73e1ff 148 case REQUEST_GET_CUR:
toucyy 0:2d8d0b73e1ff 149 transfer->remaining = 1;
toucyy 0:2d8d0b73e1ff 150 transfer->ptr = &mute;
toucyy 0:2d8d0b73e1ff 151 transfer->direction = DEVICE_TO_HOST;
toucyy 0:2d8d0b73e1ff 152 success = true;
toucyy 0:2d8d0b73e1ff 153 break;
toucyy 0:2d8d0b73e1ff 154
toucyy 0:2d8d0b73e1ff 155 case REQUEST_SET_CUR:
toucyy 0:2d8d0b73e1ff 156 transfer->remaining = 1;
toucyy 0:2d8d0b73e1ff 157 transfer->notify = true;
toucyy 0:2d8d0b73e1ff 158 transfer->direction = HOST_TO_DEVICE;
toucyy 0:2d8d0b73e1ff 159 success = true;
toucyy 0:2d8d0b73e1ff 160 break;
toucyy 0:2d8d0b73e1ff 161 default:
toucyy 0:2d8d0b73e1ff 162 break;
toucyy 0:2d8d0b73e1ff 163 }
toucyy 0:2d8d0b73e1ff 164 break;
toucyy 0:2d8d0b73e1ff 165 case VOLUME_CONTROL:
toucyy 0:2d8d0b73e1ff 166 switch (transfer->setup.bRequest) {
toucyy 0:2d8d0b73e1ff 167 case REQUEST_GET_CUR:
toucyy 0:2d8d0b73e1ff 168 transfer->remaining = 2;
toucyy 0:2d8d0b73e1ff 169 transfer->ptr = (uint8_t *)&volCur;
toucyy 0:2d8d0b73e1ff 170 transfer->direction = DEVICE_TO_HOST;
toucyy 0:2d8d0b73e1ff 171 success = true;
toucyy 0:2d8d0b73e1ff 172 break;
toucyy 0:2d8d0b73e1ff 173 case REQUEST_GET_MIN:
toucyy 0:2d8d0b73e1ff 174 transfer->remaining = 2;
toucyy 0:2d8d0b73e1ff 175 transfer->ptr = (uint8_t *)&volMin;
toucyy 0:2d8d0b73e1ff 176 transfer->direction = DEVICE_TO_HOST;
toucyy 0:2d8d0b73e1ff 177 success = true;
toucyy 0:2d8d0b73e1ff 178 break;
toucyy 0:2d8d0b73e1ff 179 case REQUEST_GET_MAX:
toucyy 0:2d8d0b73e1ff 180 transfer->remaining = 2;
toucyy 0:2d8d0b73e1ff 181 transfer->ptr = (uint8_t *)&volMax;
toucyy 0:2d8d0b73e1ff 182 transfer->direction = DEVICE_TO_HOST;
toucyy 0:2d8d0b73e1ff 183 success = true;
toucyy 0:2d8d0b73e1ff 184 break;
toucyy 0:2d8d0b73e1ff 185 case REQUEST_GET_RES:
toucyy 0:2d8d0b73e1ff 186 transfer->remaining = 2;
toucyy 0:2d8d0b73e1ff 187 transfer->ptr = (uint8_t *)&volRes;
toucyy 0:2d8d0b73e1ff 188 transfer->direction = DEVICE_TO_HOST;
toucyy 0:2d8d0b73e1ff 189 success = true;
toucyy 0:2d8d0b73e1ff 190 break;
toucyy 0:2d8d0b73e1ff 191
toucyy 0:2d8d0b73e1ff 192 case REQUEST_SET_CUR:
toucyy 0:2d8d0b73e1ff 193 transfer->remaining = 2;
toucyy 0:2d8d0b73e1ff 194 transfer->notify = true;
toucyy 0:2d8d0b73e1ff 195 transfer->direction = HOST_TO_DEVICE;
toucyy 0:2d8d0b73e1ff 196 success = true;
toucyy 0:2d8d0b73e1ff 197 break;
toucyy 0:2d8d0b73e1ff 198 case REQUEST_SET_MIN:
toucyy 0:2d8d0b73e1ff 199 transfer->remaining = 2;
toucyy 0:2d8d0b73e1ff 200 transfer->notify = true;
toucyy 0:2d8d0b73e1ff 201 transfer->direction = HOST_TO_DEVICE;
toucyy 0:2d8d0b73e1ff 202 success = true;
toucyy 0:2d8d0b73e1ff 203 break;
toucyy 0:2d8d0b73e1ff 204 case REQUEST_SET_MAX:
toucyy 0:2d8d0b73e1ff 205 transfer->remaining = 2;
toucyy 0:2d8d0b73e1ff 206 transfer->notify = true;
toucyy 0:2d8d0b73e1ff 207 transfer->direction = HOST_TO_DEVICE;
toucyy 0:2d8d0b73e1ff 208 success = true;
toucyy 0:2d8d0b73e1ff 209 break;
toucyy 0:2d8d0b73e1ff 210 case REQUEST_SET_RES:
toucyy 0:2d8d0b73e1ff 211 transfer->remaining = 2;
toucyy 0:2d8d0b73e1ff 212 transfer->notify = true;
toucyy 0:2d8d0b73e1ff 213 transfer->direction = HOST_TO_DEVICE;
toucyy 0:2d8d0b73e1ff 214 success = true;
toucyy 0:2d8d0b73e1ff 215 break;
toucyy 0:2d8d0b73e1ff 216 }
toucyy 0:2d8d0b73e1ff 217 break;
toucyy 0:2d8d0b73e1ff 218 default:
toucyy 0:2d8d0b73e1ff 219 break;
toucyy 0:2d8d0b73e1ff 220 }
toucyy 0:2d8d0b73e1ff 221 }
toucyy 0:2d8d0b73e1ff 222 }
toucyy 0:2d8d0b73e1ff 223 }
toucyy 0:2d8d0b73e1ff 224 return success;
toucyy 0:2d8d0b73e1ff 225 }
toucyy 0:2d8d0b73e1ff 226
toucyy 0:2d8d0b73e1ff 227
toucyy 0:2d8d0b73e1ff 228 // Called in ISR context when a data OUT stage has been performed
toucyy 0:2d8d0b73e1ff 229 void USBAudio::USBCallback_requestCompleted(uint8_t * buf, uint16_t length) {
toucyy 0:2d8d0b73e1ff 230 uint16_t data = *((uint16_t *)buf);
toucyy 0:2d8d0b73e1ff 231 CONTROL_TRANSFER * transfer = getTransferPtr();
toucyy 0:2d8d0b73e1ff 232 switch (transfer->setup.wValue >> 8) {
toucyy 0:2d8d0b73e1ff 233 case MUTE_CONTROL:
toucyy 0:2d8d0b73e1ff 234 switch (transfer->setup.bRequest) {
toucyy 0:2d8d0b73e1ff 235 case REQUEST_SET_CUR:
toucyy 0:2d8d0b73e1ff 236 mute = data & 0xff;
toucyy 0:2d8d0b73e1ff 237 updateVol.call();
toucyy 0:2d8d0b73e1ff 238 break;
toucyy 0:2d8d0b73e1ff 239 default:
toucyy 0:2d8d0b73e1ff 240 break;
toucyy 0:2d8d0b73e1ff 241 }
toucyy 0:2d8d0b73e1ff 242 break;
toucyy 0:2d8d0b73e1ff 243 case VOLUME_CONTROL:
toucyy 0:2d8d0b73e1ff 244 switch (transfer->setup.bRequest) {
toucyy 0:2d8d0b73e1ff 245 case REQUEST_SET_CUR:
toucyy 0:2d8d0b73e1ff 246 volCur = data;
toucyy 0:2d8d0b73e1ff 247 updateVol.call();
toucyy 0:2d8d0b73e1ff 248 break;
toucyy 0:2d8d0b73e1ff 249 default:
toucyy 0:2d8d0b73e1ff 250 break;
toucyy 0:2d8d0b73e1ff 251 }
toucyy 0:2d8d0b73e1ff 252 break;
toucyy 0:2d8d0b73e1ff 253 default:
toucyy 0:2d8d0b73e1ff 254 break;
toucyy 0:2d8d0b73e1ff 255 }
toucyy 0:2d8d0b73e1ff 256 }
toucyy 0:2d8d0b73e1ff 257
toucyy 0:2d8d0b73e1ff 258
toucyy 0:2d8d0b73e1ff 259
toucyy 0:2d8d0b73e1ff 260 #define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \
toucyy 0:2d8d0b73e1ff 261 + (3 * INTERFACE_DESCRIPTOR_LENGTH) \
toucyy 0:2d8d0b73e1ff 262 + (1 * CONTROL_INTERFACE_DESCRIPTOR_LENGTH) \
toucyy 0:2d8d0b73e1ff 263 + (1 * INPUT_TERMINAL_DESCRIPTOR_LENGTH) \
toucyy 0:2d8d0b73e1ff 264 + (1 * FEATURE_UNIT_DESCRIPTOR_LENGTH) \
toucyy 0:2d8d0b73e1ff 265 + (1 * OUTPUT_TERMINAL_DESCRIPTOR_LENGTH) \
toucyy 0:2d8d0b73e1ff 266 + (1 * STREAMING_INTERFACE_DESCRIPTOR_LENGTH) \
toucyy 0:2d8d0b73e1ff 267 + (1 * FORMAT_TYPE_I_DESCRIPTOR_LENGTH) \
toucyy 0:2d8d0b73e1ff 268 + (1 * (ENDPOINT_DESCRIPTOR_LENGTH + 2)) \
toucyy 0:2d8d0b73e1ff 269 + (1 * STREAMING_ENDPOINT_DESCRIPTOR_LENGTH) )
toucyy 0:2d8d0b73e1ff 270
toucyy 0:2d8d0b73e1ff 271 #define TOTAL_CONTROL_INTF_LENGTH (CONTROL_INTERFACE_DESCRIPTOR_LENGTH + \
toucyy 0:2d8d0b73e1ff 272 INPUT_TERMINAL_DESCRIPTOR_LENGTH + \
toucyy 0:2d8d0b73e1ff 273 FEATURE_UNIT_DESCRIPTOR_LENGTH + \
toucyy 0:2d8d0b73e1ff 274 OUTPUT_TERMINAL_DESCRIPTOR_LENGTH)
toucyy 0:2d8d0b73e1ff 275
toucyy 0:2d8d0b73e1ff 276 uint8_t * USBAudio::configurationDesc() {
toucyy 0:2d8d0b73e1ff 277 static uint8_t configDescriptor[] = {
toucyy 0:2d8d0b73e1ff 278 // Configuration 1
toucyy 0:2d8d0b73e1ff 279 CONFIGURATION_DESCRIPTOR_LENGTH, // bLength
toucyy 0:2d8d0b73e1ff 280 CONFIGURATION_DESCRIPTOR, // bDescriptorType
toucyy 0:2d8d0b73e1ff 281 LSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (LSB)
toucyy 0:2d8d0b73e1ff 282 MSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (MSB)
toucyy 0:2d8d0b73e1ff 283 0x02, // bNumInterfaces
toucyy 0:2d8d0b73e1ff 284 DEFAULT_CONFIGURATION, // bConfigurationValue
toucyy 0:2d8d0b73e1ff 285 0x00, // iConfiguration
toucyy 0:2d8d0b73e1ff 286 0x80, // bmAttributes
toucyy 0:2d8d0b73e1ff 287 50, // bMaxPower
toucyy 0:2d8d0b73e1ff 288
toucyy 0:2d8d0b73e1ff 289 // Interface 0, Alternate Setting 0, Audio Control
toucyy 0:2d8d0b73e1ff 290 INTERFACE_DESCRIPTOR_LENGTH, // bLength
toucyy 0:2d8d0b73e1ff 291 INTERFACE_DESCRIPTOR, // bDescriptorType
toucyy 0:2d8d0b73e1ff 292 0x00, // bInterfaceNumber
toucyy 0:2d8d0b73e1ff 293 0x00, // bAlternateSetting
toucyy 0:2d8d0b73e1ff 294 0x00, // bNumEndpoints
toucyy 0:2d8d0b73e1ff 295 AUDIO_CLASS, // bInterfaceClass
toucyy 0:2d8d0b73e1ff 296 SUBCLASS_AUDIOCONTROL, // bInterfaceSubClass
toucyy 0:2d8d0b73e1ff 297 0x00, // bInterfaceProtocol
toucyy 0:2d8d0b73e1ff 298 0x00, // iInterface
toucyy 0:2d8d0b73e1ff 299
toucyy 0:2d8d0b73e1ff 300
toucyy 0:2d8d0b73e1ff 301 // Audio Control Interface
toucyy 0:2d8d0b73e1ff 302 CONTROL_INTERFACE_DESCRIPTOR_LENGTH, // bLength
toucyy 0:2d8d0b73e1ff 303 INTERFACE_DESCRIPTOR_TYPE, // bDescriptorType
toucyy 0:2d8d0b73e1ff 304 CONTROL_HEADER, // bDescriptorSubtype
toucyy 0:2d8d0b73e1ff 305 LSB(0x0100), // bcdADC (LSB)
toucyy 0:2d8d0b73e1ff 306 MSB(0x0100), // bcdADC (MSB)
toucyy 0:2d8d0b73e1ff 307 LSB(TOTAL_CONTROL_INTF_LENGTH), // wTotalLength
toucyy 0:2d8d0b73e1ff 308 MSB(TOTAL_CONTROL_INTF_LENGTH), // wTotalLength
toucyy 0:2d8d0b73e1ff 309 0x01, // bInCollection
toucyy 0:2d8d0b73e1ff 310 0x01, // baInterfaceNr
toucyy 0:2d8d0b73e1ff 311
toucyy 0:2d8d0b73e1ff 312 // Audio Input Terminal
toucyy 0:2d8d0b73e1ff 313 INPUT_TERMINAL_DESCRIPTOR_LENGTH, // bLength
toucyy 0:2d8d0b73e1ff 314 INTERFACE_DESCRIPTOR_TYPE, // bDescriptorType
toucyy 0:2d8d0b73e1ff 315 CONTROL_INPUT_TERMINAL, // bDescriptorSubtype
toucyy 0:2d8d0b73e1ff 316 0x01, // bTerminalID
toucyy 0:2d8d0b73e1ff 317 LSB(TERMINAL_USB_STREAMING), // wTerminalType
toucyy 0:2d8d0b73e1ff 318 MSB(TERMINAL_USB_STREAMING), // wTerminalType
toucyy 0:2d8d0b73e1ff 319 0x00, // bAssocTerminal
toucyy 0:2d8d0b73e1ff 320 channel_nb, // bNrChannels
toucyy 0:2d8d0b73e1ff 321 LSB(channel_config), // wChannelConfig
toucyy 0:2d8d0b73e1ff 322 MSB(channel_config), // wChannelConfig
toucyy 0:2d8d0b73e1ff 323 0x00, // iChannelNames
toucyy 0:2d8d0b73e1ff 324 0x00, // iTerminal
toucyy 0:2d8d0b73e1ff 325
toucyy 0:2d8d0b73e1ff 326 // Audio Feature Unit
toucyy 0:2d8d0b73e1ff 327 FEATURE_UNIT_DESCRIPTOR_LENGTH, // bLength
toucyy 0:2d8d0b73e1ff 328 INTERFACE_DESCRIPTOR_TYPE, // bDescriptorType
toucyy 0:2d8d0b73e1ff 329 CONTROL_FEATURE_UNIT, // bDescriptorSubtype
toucyy 0:2d8d0b73e1ff 330 0x02, // bUnitID
toucyy 0:2d8d0b73e1ff 331 0x01, // bSourceID
toucyy 0:2d8d0b73e1ff 332 0x01, // bControlSize
toucyy 0:2d8d0b73e1ff 333 CONTROL_MUTE |
toucyy 0:2d8d0b73e1ff 334 CONTROL_VOLUME, // bmaControls(0)
toucyy 0:2d8d0b73e1ff 335 0x00, // bmaControls(1)
toucyy 0:2d8d0b73e1ff 336 0x00, // iTerminal
toucyy 0:2d8d0b73e1ff 337
toucyy 0:2d8d0b73e1ff 338 // Audio Output Terminal
toucyy 0:2d8d0b73e1ff 339 OUTPUT_TERMINAL_DESCRIPTOR_LENGTH, // bLength
toucyy 0:2d8d0b73e1ff 340 INTERFACE_DESCRIPTOR_TYPE, // bDescriptorType
toucyy 0:2d8d0b73e1ff 341 CONTROL_OUTPUT_TERMINAL, // bDescriptorSubtype
toucyy 0:2d8d0b73e1ff 342 0x03, // bTerminalID
toucyy 0:2d8d0b73e1ff 343 LSB(TERMINAL_SPEAKER), // wTerminalType
toucyy 0:2d8d0b73e1ff 344 MSB(TERMINAL_SPEAKER), // wTerminalType
toucyy 0:2d8d0b73e1ff 345 0x00, // bAssocTerminal
toucyy 0:2d8d0b73e1ff 346 0x02, // bSourceID
toucyy 0:2d8d0b73e1ff 347 0x00, // iTerminal
toucyy 0:2d8d0b73e1ff 348
toucyy 0:2d8d0b73e1ff 349
toucyy 0:2d8d0b73e1ff 350 // Interface 1, Alternate Setting 0, Audio Streaming - Zero Bandwith
toucyy 0:2d8d0b73e1ff 351 INTERFACE_DESCRIPTOR_LENGTH, // bLength
toucyy 0:2d8d0b73e1ff 352 INTERFACE_DESCRIPTOR, // bDescriptorType
toucyy 0:2d8d0b73e1ff 353 0x01, // bInterfaceNumber
toucyy 0:2d8d0b73e1ff 354 0x00, // bAlternateSetting
toucyy 0:2d8d0b73e1ff 355 0x00, // bNumEndpoints
toucyy 0:2d8d0b73e1ff 356 AUDIO_CLASS, // bInterfaceClass
toucyy 0:2d8d0b73e1ff 357 SUBCLASS_AUDIOSTREAMING, // bInterfaceSubClass
toucyy 0:2d8d0b73e1ff 358 0x00, // bInterfaceProtocol
toucyy 0:2d8d0b73e1ff 359 0x00, // iInterface
toucyy 0:2d8d0b73e1ff 360
toucyy 0:2d8d0b73e1ff 361 // Interface 1, Alternate Setting 1, Audio Streaming - Operational
toucyy 0:2d8d0b73e1ff 362 INTERFACE_DESCRIPTOR_LENGTH, // bLength
toucyy 0:2d8d0b73e1ff 363 INTERFACE_DESCRIPTOR, // bDescriptorType
toucyy 0:2d8d0b73e1ff 364 0x01, // bInterfaceNumber
toucyy 0:2d8d0b73e1ff 365 0x01, // bAlternateSetting
toucyy 0:2d8d0b73e1ff 366 0x01, // bNumEndpoints
toucyy 0:2d8d0b73e1ff 367 AUDIO_CLASS, // bInterfaceClass
toucyy 0:2d8d0b73e1ff 368 SUBCLASS_AUDIOSTREAMING, // bInterfaceSubClass
toucyy 0:2d8d0b73e1ff 369 0x00, // bInterfaceProtocol
toucyy 0:2d8d0b73e1ff 370 0x00, // iInterface
toucyy 0:2d8d0b73e1ff 371
toucyy 0:2d8d0b73e1ff 372 // Audio Streaming Interface
toucyy 0:2d8d0b73e1ff 373 STREAMING_INTERFACE_DESCRIPTOR_LENGTH, // bLength
toucyy 0:2d8d0b73e1ff 374 INTERFACE_DESCRIPTOR_TYPE, // bDescriptorType
toucyy 0:2d8d0b73e1ff 375 STREAMING_GENERAL, // bDescriptorSubtype
toucyy 0:2d8d0b73e1ff 376 0x01, // bTerminalLink
toucyy 0:2d8d0b73e1ff 377 0x00, // bDelay
toucyy 0:2d8d0b73e1ff 378 LSB(FORMAT_PCM), // wFormatTag
toucyy 0:2d8d0b73e1ff 379 MSB(FORMAT_PCM), // wFormatTag
toucyy 0:2d8d0b73e1ff 380
toucyy 0:2d8d0b73e1ff 381 // Audio Type I Format
toucyy 0:2d8d0b73e1ff 382 FORMAT_TYPE_I_DESCRIPTOR_LENGTH, // bLength
toucyy 0:2d8d0b73e1ff 383 INTERFACE_DESCRIPTOR_TYPE, // bDescriptorType
toucyy 0:2d8d0b73e1ff 384 STREAMING_FORMAT_TYPE, // bDescriptorSubtype
toucyy 0:2d8d0b73e1ff 385 FORMAT_TYPE_I, // bFormatType
toucyy 0:2d8d0b73e1ff 386 channel_nb, // bNrChannels
toucyy 0:2d8d0b73e1ff 387 0x02, // bSubFrameSize
toucyy 0:2d8d0b73e1ff 388 16, // bBitResolution
toucyy 0:2d8d0b73e1ff 389 0x01, // bSamFreqType
toucyy 0:2d8d0b73e1ff 390 LSB(FREQ), // tSamFreq
toucyy 0:2d8d0b73e1ff 391 (FREQ >> 8) & 0xff, // tSamFreq
toucyy 0:2d8d0b73e1ff 392 (FREQ >> 16) & 0xff, // tSamFreq
toucyy 0:2d8d0b73e1ff 393
toucyy 0:2d8d0b73e1ff 394 // Endpoint - Standard Descriptor
toucyy 0:2d8d0b73e1ff 395 ENDPOINT_DESCRIPTOR_LENGTH + 2, // bLength
toucyy 0:2d8d0b73e1ff 396 ENDPOINT_DESCRIPTOR, // bDescriptorType
toucyy 0:2d8d0b73e1ff 397 PHY_TO_DESC(EPISO_OUT), // bEndpointAddress
toucyy 0:2d8d0b73e1ff 398 E_ISOCHRONOUS, // bmAttributes
toucyy 0:2d8d0b73e1ff 399 LSB(PACKET_SIZE_ISO), // wMaxPacketSize
toucyy 0:2d8d0b73e1ff 400 MSB(PACKET_SIZE_ISO), // wMaxPacketSize
toucyy 0:2d8d0b73e1ff 401 0x01, // bInterval
toucyy 0:2d8d0b73e1ff 402 0x00, // bRefresh
toucyy 0:2d8d0b73e1ff 403 0x00, // bSynchAddress
toucyy 0:2d8d0b73e1ff 404
toucyy 0:2d8d0b73e1ff 405 // Endpoint - Audio Streaming
toucyy 0:2d8d0b73e1ff 406 STREAMING_ENDPOINT_DESCRIPTOR_LENGTH, // bLength
toucyy 0:2d8d0b73e1ff 407 ENDPOINT_DESCRIPTOR_TYPE, // bDescriptorType
toucyy 0:2d8d0b73e1ff 408 ENDPOINT_GENERAL, // bDescriptor
toucyy 0:2d8d0b73e1ff 409 0x00, // bmAttributes
toucyy 0:2d8d0b73e1ff 410 0x00, // bLockDelayUnits
toucyy 0:2d8d0b73e1ff 411 LSB(0x0000), // wLockDelay
toucyy 0:2d8d0b73e1ff 412 MSB(0x0000), // wLockDelay
toucyy 0:2d8d0b73e1ff 413
toucyy 0:2d8d0b73e1ff 414 // Terminator
toucyy 0:2d8d0b73e1ff 415 0 // bLength
toucyy 0:2d8d0b73e1ff 416 };
toucyy 0:2d8d0b73e1ff 417 return configDescriptor;
toucyy 0:2d8d0b73e1ff 418 }
toucyy 0:2d8d0b73e1ff 419
toucyy 0:2d8d0b73e1ff 420 uint8_t * USBAudio::stringIinterfaceDesc() {
toucyy 0:2d8d0b73e1ff 421 static uint8_t stringIinterfaceDescriptor[] = {
toucyy 0:2d8d0b73e1ff 422 0x0c, //bLength
toucyy 0:2d8d0b73e1ff 423 STRING_DESCRIPTOR, //bDescriptorType 0x03
toucyy 0:2d8d0b73e1ff 424 'A',0,'u',0,'d',0,'i',0,'o',0 //bString iInterface - Audio
toucyy 0:2d8d0b73e1ff 425 };
toucyy 0:2d8d0b73e1ff 426 return stringIinterfaceDescriptor;
toucyy 0:2d8d0b73e1ff 427 }
toucyy 0:2d8d0b73e1ff 428
toucyy 0:2d8d0b73e1ff 429 uint8_t * USBAudio::stringIproductDesc() {
toucyy 0:2d8d0b73e1ff 430 static uint8_t stringIproductDescriptor[] = {
toucyy 0:2d8d0b73e1ff 431 0x16, //bLength
toucyy 0:2d8d0b73e1ff 432 STRING_DESCRIPTOR, //bDescriptorType 0x03
toucyy 0:2d8d0b73e1ff 433 'M',0,'b',0,'e',0,'d',0,' ',0,'A',0,'u',0,'d',0,'i',0,'o',0 //bString iProduct - Mbed Audio
toucyy 0:2d8d0b73e1ff 434 };
toucyy 0:2d8d0b73e1ff 435 return stringIproductDescriptor;
toucyy 0:2d8d0b73e1ff 436 }