USB device stack

Dependents:   mbed-mX-USB-TEST1 USBMSD_SD_HID_HelloWorld HidTest MIDI_usb_bridge ... more

Legacy Warning

This is an mbed 2 library. To learn more about mbed OS 5, visit the docs.

Pull requests against this repository are no longer supported. Please raise against mbed OS 5 as documented above.

Committer:
Kojto
Date:
Thu Jul 27 12:14:04 2017 +0100
Revision:
71:53949e6131f6
Parent:
70:2c525a50f1b6
Update libraries

Fixes the previous commmit, as some devices were not copied. USBDevice contains
now targets directory with all targets implementations

Who changed what in which revision?

UserRevisionLine numberNew contents of line
samux 1:80ab0d068708 1 /* Copyright (c) 2010-2011 mbed.org, MIT License
samux 1:80ab0d068708 2 *
samux 1:80ab0d068708 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
samux 1:80ab0d068708 4 * and associated documentation files (the "Software"), to deal in the Software without
samux 1:80ab0d068708 5 * restriction, including without limitation the rights to use, copy, modify, merge, publish,
samux 1:80ab0d068708 6 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
samux 1:80ab0d068708 7 * Software is furnished to do so, subject to the following conditions:
samux 1:80ab0d068708 8 *
samux 1:80ab0d068708 9 * The above copyright notice and this permission notice shall be included in all copies or
samux 1:80ab0d068708 10 * substantial portions of the Software.
samux 1:80ab0d068708 11 *
samux 1:80ab0d068708 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
samux 1:80ab0d068708 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
samux 1:80ab0d068708 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
samux 1:80ab0d068708 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
samux 1:80ab0d068708 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
samux 1:80ab0d068708 17 */
samux 1:80ab0d068708 18
samux 1:80ab0d068708 19 #include "stdint.h"
samux 1:80ab0d068708 20 #include "USBAudio.h"
samux 1:80ab0d068708 21 #include "USBAudio_Types.h"
samux 1:80ab0d068708 22
samux 1:80ab0d068708 23
samux 1:80ab0d068708 24
samux 1:80ab0d068708 25 USBAudio::USBAudio(uint32_t frequency_in, uint8_t channel_nb_in, uint32_t frequency_out, uint8_t channel_nb_out, uint16_t vendor_id, uint16_t product_id, uint16_t product_release): USBDevice(vendor_id, product_id, product_release) {
samux 1:80ab0d068708 26 mute = 0;
samux 1:80ab0d068708 27 volCur = 0x0080;
samux 1:80ab0d068708 28 volMin = 0x0000;
samux 1:80ab0d068708 29 volMax = 0x0100;
samux 1:80ab0d068708 30 volRes = 0x0004;
samux 1:80ab0d068708 31 available = false;
samux 1:80ab0d068708 32
samux 1:80ab0d068708 33 FREQ_IN = frequency_in;
samux 1:80ab0d068708 34 FREQ_OUT = frequency_out;
samux 1:80ab0d068708 35
samux 1:80ab0d068708 36 this->channel_nb_in = channel_nb_in;
samux 1:80ab0d068708 37 this->channel_nb_out = channel_nb_out;
samux 1:80ab0d068708 38
samux 1:80ab0d068708 39 // stereo -> *2, mono -> *1
samux 1:80ab0d068708 40 PACKET_SIZE_ISO_IN = (FREQ_IN / 500) * channel_nb_in;
samux 1:80ab0d068708 41 PACKET_SIZE_ISO_OUT = (FREQ_OUT / 500) * channel_nb_out;
samux 1:80ab0d068708 42
samux 1:80ab0d068708 43 // STEREO -> left and right
samux 1:80ab0d068708 44 channel_config_in = (channel_nb_in == 1) ? CHANNEL_M : CHANNEL_L + CHANNEL_R;
samux 1:80ab0d068708 45 channel_config_out = (channel_nb_out == 1) ? CHANNEL_M : CHANNEL_L + CHANNEL_R;
samux 1:80ab0d068708 46
samux 1:80ab0d068708 47 SOF_handler = false;
samux 1:80ab0d068708 48
samux 1:80ab0d068708 49 buf_stream_out = NULL;
samux 1:80ab0d068708 50 buf_stream_in = NULL;
samux 1:80ab0d068708 51
samux 1:80ab0d068708 52 interruptOUT = false;
samux 1:80ab0d068708 53 writeIN = false;
samux 1:80ab0d068708 54 interruptIN = false;
samux 1:80ab0d068708 55 available = false;
samux 1:80ab0d068708 56
samux 1:80ab0d068708 57 volume = 0;
samux 1:80ab0d068708 58
samux 1:80ab0d068708 59 // connect the device
samux 1:80ab0d068708 60 USBDevice::connect();
samux 1:80ab0d068708 61 }
samux 1:80ab0d068708 62
samux 1:80ab0d068708 63 bool USBAudio::read(uint8_t * buf) {
samux 1:80ab0d068708 64 buf_stream_in = buf;
samux 1:80ab0d068708 65 SOF_handler = false;
samux 1:80ab0d068708 66 while (!available || !SOF_handler);
samux 1:80ab0d068708 67 available = false;
samux 1:80ab0d068708 68 return true;
samux 1:80ab0d068708 69 }
samux 1:80ab0d068708 70
samux 1:80ab0d068708 71 bool USBAudio::readNB(uint8_t * buf) {
samux 1:80ab0d068708 72 buf_stream_in = buf;
samux 1:80ab0d068708 73 SOF_handler = false;
samux 1:80ab0d068708 74 while (!SOF_handler);
samux 1:80ab0d068708 75 if (available) {
samux 1:80ab0d068708 76 available = false;
samux 1:80ab0d068708 77 buf_stream_in = NULL;
samux 1:80ab0d068708 78 return true;
samux 1:80ab0d068708 79 }
samux 1:80ab0d068708 80 return false;
samux 1:80ab0d068708 81 }
samux 1:80ab0d068708 82
samux 1:80ab0d068708 83 bool USBAudio::readWrite(uint8_t * buf_read, uint8_t * buf_write) {
samux 1:80ab0d068708 84 buf_stream_in = buf_read;
samux 1:80ab0d068708 85 SOF_handler = false;
samux 1:80ab0d068708 86 writeIN = false;
samux 1:80ab0d068708 87 if (interruptIN) {
Kojto 70:2c525a50f1b6 88 USBDevice::writeNB(EPISO_IN, buf_write, PACKET_SIZE_ISO_OUT, PACKET_SIZE_ISO_OUT);
samux 1:80ab0d068708 89 } else {
samux 1:80ab0d068708 90 buf_stream_out = buf_write;
samux 1:80ab0d068708 91 }
samux 1:80ab0d068708 92 while (!available);
samux 1:80ab0d068708 93 if (interruptIN) {
samux 1:80ab0d068708 94 while (!writeIN);
samux 1:80ab0d068708 95 }
samux 1:80ab0d068708 96 while (!SOF_handler);
samux 1:80ab0d068708 97 return true;
samux 1:80ab0d068708 98 }
samux 1:80ab0d068708 99
samux 1:80ab0d068708 100
samux 1:80ab0d068708 101 bool USBAudio::write(uint8_t * buf) {
samux 1:80ab0d068708 102 writeIN = false;
samux 1:80ab0d068708 103 SOF_handler = false;
samux 1:80ab0d068708 104 if (interruptIN) {
Kojto 70:2c525a50f1b6 105 USBDevice::writeNB(EPISO_IN, buf, PACKET_SIZE_ISO_OUT, PACKET_SIZE_ISO_OUT);
samux 1:80ab0d068708 106 } else {
samux 1:80ab0d068708 107 buf_stream_out = buf;
samux 1:80ab0d068708 108 }
samux 1:80ab0d068708 109 while (!SOF_handler);
samux 1:80ab0d068708 110 if (interruptIN) {
samux 1:80ab0d068708 111 while (!writeIN);
samux 1:80ab0d068708 112 }
samux 1:80ab0d068708 113 return true;
samux 1:80ab0d068708 114 }
samux 1:80ab0d068708 115
Kojto 70:2c525a50f1b6 116 void USBAudio::writeSync(uint8_t *buf, AudioSampleCorrectType jitter_nb)
Kojto 70:2c525a50f1b6 117 {
Kojto 70:2c525a50f1b6 118 if ((jitter_nb != RemoveOneSample) && (jitter_nb != AddOneSample)) {
Kojto 70:2c525a50f1b6 119 jitter_nb = NoCorrection;
Kojto 70:2c525a50f1b6 120 }
Kojto 70:2c525a50f1b6 121 /* each sample is 2 bytes */
Kojto 70:2c525a50f1b6 122 USBDevice::writeNB(EPISO_IN, buf, PACKET_SIZE_ISO_OUT + jitter_nb *(this->channel_nb_out*2), PACKET_SIZE_ISO_OUT+this->channel_nb_out*2);
Kojto 70:2c525a50f1b6 123 }
Kojto 70:2c525a50f1b6 124
Kojto 70:2c525a50f1b6 125 uint32_t USBAudio::readSync(uint8_t *buf)
Kojto 70:2c525a50f1b6 126 {
Kojto 70:2c525a50f1b6 127 uint32_t size = 0;
Kojto 70:2c525a50f1b6 128 USBDevice::readEP(EPISO_OUT, (uint8_t *)buf, &size, PACKET_SIZE_ISO_IN);
Kojto 70:2c525a50f1b6 129 return size;
Kojto 70:2c525a50f1b6 130 }
samux 1:80ab0d068708 131
samux 1:80ab0d068708 132 float USBAudio::getVolume() {
samux 1:80ab0d068708 133 return (mute) ? 0.0 : volume;
samux 1:80ab0d068708 134 }
samux 1:80ab0d068708 135
samux 1:80ab0d068708 136
mbed_official 47:a0cd9646ecd1 137 bool USBAudio::EPISO_OUT_callback() {
samux 1:80ab0d068708 138 uint32_t size = 0;
samux 1:80ab0d068708 139 interruptOUT = true;
samux 1:80ab0d068708 140 if (buf_stream_in != NULL) {
Kojto 70:2c525a50f1b6 141 readEP(EPISO_OUT, (uint8_t *)buf_stream_in, &size, PACKET_SIZE_ISO_IN);
samux 1:80ab0d068708 142 available = true;
samux 1:80ab0d068708 143 buf_stream_in = NULL;
samux 1:80ab0d068708 144 }
Kojto 70:2c525a50f1b6 145 else {
Kojto 70:2c525a50f1b6 146 if (rxDone)
Kojto 70:2c525a50f1b6 147 rxDone.call();
Kojto 70:2c525a50f1b6 148 }
Kojto 70:2c525a50f1b6 149 readStart(EPISO_OUT, PACKET_SIZE_ISO_IN);
samux 1:80ab0d068708 150 return false;
samux 1:80ab0d068708 151 }
samux 1:80ab0d068708 152
samux 1:80ab0d068708 153
mbed_official 47:a0cd9646ecd1 154 bool USBAudio::EPISO_IN_callback() {
samux 1:80ab0d068708 155 interruptIN = true;
samux 1:80ab0d068708 156 writeIN = true;
Kojto 70:2c525a50f1b6 157 if (txDone)
Kojto 70:2c525a50f1b6 158 txDone.call();
samux 1:80ab0d068708 159 return true;
samux 1:80ab0d068708 160 }
samux 1:80ab0d068708 161
samux 1:80ab0d068708 162
samux 1:80ab0d068708 163
samux 1:80ab0d068708 164 // Called in ISR context on each start of frame
samux 1:80ab0d068708 165 void USBAudio::SOF(int frameNumber) {
samux 1:80ab0d068708 166 uint32_t size = 0;
samux 1:80ab0d068708 167
samux 1:80ab0d068708 168 if (!interruptOUT) {
samux 1:80ab0d068708 169 // read the isochronous endpoint
samux 1:80ab0d068708 170 if (buf_stream_in != NULL) {
Kojto 70:2c525a50f1b6 171 if (USBDevice::readEP_NB(EPISO_OUT, (uint8_t *)buf_stream_in, &size, PACKET_SIZE_ISO_IN)) {
samux 1:80ab0d068708 172 if (size) {
samux 1:80ab0d068708 173 available = true;
Kojto 70:2c525a50f1b6 174 readStart(EPISO_OUT, PACKET_SIZE_ISO_IN);
samux 1:80ab0d068708 175 buf_stream_in = NULL;
samux 1:80ab0d068708 176 }
samux 1:80ab0d068708 177 }
samux 1:80ab0d068708 178 }
samux 1:80ab0d068708 179 }
samux 1:80ab0d068708 180
samux 1:80ab0d068708 181 if (!interruptIN) {
samux 1:80ab0d068708 182 // write if needed
samux 1:80ab0d068708 183 if (buf_stream_out != NULL) {
Kojto 70:2c525a50f1b6 184 USBDevice::writeNB(EPISO_IN, (uint8_t *)buf_stream_out, PACKET_SIZE_ISO_OUT, PACKET_SIZE_ISO_OUT);
samux 1:80ab0d068708 185 buf_stream_out = NULL;
samux 1:80ab0d068708 186 }
samux 1:80ab0d068708 187 }
samux 1:80ab0d068708 188
samux 1:80ab0d068708 189 SOF_handler = true;
samux 1:80ab0d068708 190 }
samux 1:80ab0d068708 191
samux 1:80ab0d068708 192
samux 1:80ab0d068708 193 // Called in ISR context
samux 1:80ab0d068708 194 // Set configuration. Return false if the configuration is not supported.
samux 1:80ab0d068708 195 bool USBAudio::USBCallback_setConfiguration(uint8_t configuration) {
samux 1:80ab0d068708 196 if (configuration != DEFAULT_CONFIGURATION) {
samux 1:80ab0d068708 197 return false;
samux 1:80ab0d068708 198 }
samux 1:80ab0d068708 199
samux 1:80ab0d068708 200 // Configure isochronous endpoint
Kojto 70:2c525a50f1b6 201 realiseEndpoint(EPISO_OUT, PACKET_SIZE_ISO_IN, ISOCHRONOUS);
Kojto 70:2c525a50f1b6 202 realiseEndpoint(EPISO_IN, PACKET_SIZE_ISO_OUT+this->channel_nb_out*2, ISOCHRONOUS);
samux 1:80ab0d068708 203
samux 1:80ab0d068708 204 // activate readings on this endpoint
Kojto 70:2c525a50f1b6 205 readStart(EPISO_OUT, PACKET_SIZE_ISO_IN);
samux 1:80ab0d068708 206 return true;
samux 1:80ab0d068708 207 }
samux 1:80ab0d068708 208
samux 1:80ab0d068708 209
samux 1:80ab0d068708 210 // Called in ISR context
samux 1:80ab0d068708 211 // Set alternate setting. Return false if the alternate setting is not supported
samux 1:80ab0d068708 212 bool USBAudio::USBCallback_setInterface(uint16_t interface, uint8_t alternate) {
samux 1:80ab0d068708 213 if (interface == 0 && alternate == 0) {
samux 1:80ab0d068708 214 return true;
samux 1:80ab0d068708 215 }
samux 1:80ab0d068708 216 if (interface == 1 && (alternate == 0 || alternate == 1)) {
samux 1:80ab0d068708 217 return true;
samux 1:80ab0d068708 218 }
samux 1:80ab0d068708 219 if (interface == 2 && (alternate == 0 || alternate == 1)) {
samux 1:80ab0d068708 220 return true;
samux 1:80ab0d068708 221 }
samux 1:80ab0d068708 222 return false;
samux 1:80ab0d068708 223 }
samux 1:80ab0d068708 224
samux 1:80ab0d068708 225
samux 1:80ab0d068708 226
samux 1:80ab0d068708 227 // Called in ISR context
samux 1:80ab0d068708 228 // Called by USBDevice on Endpoint0 request
samux 1:80ab0d068708 229 // This is used to handle extensions to standard requests and class specific requests.
samux 1:80ab0d068708 230 // Return true if class handles this request
samux 1:80ab0d068708 231 bool USBAudio::USBCallback_request() {
samux 1:80ab0d068708 232 bool success = false;
samux 1:80ab0d068708 233 CONTROL_TRANSFER * transfer = getTransferPtr();
samux 1:80ab0d068708 234
samux 1:80ab0d068708 235 // Process class-specific requests
samux 1:80ab0d068708 236 if (transfer->setup.bmRequestType.Type == CLASS_TYPE) {
samux 1:80ab0d068708 237
samux 1:80ab0d068708 238 // Feature Unit: Interface = 0, ID = 2
samux 1:80ab0d068708 239 if (transfer->setup.wIndex == 0x0200) {
samux 1:80ab0d068708 240
samux 1:80ab0d068708 241 // Master Channel
samux 1:80ab0d068708 242 if ((transfer->setup.wValue & 0xff) == 0) {
samux 1:80ab0d068708 243
samux 1:80ab0d068708 244 switch (transfer->setup.wValue >> 8) {
samux 1:80ab0d068708 245 case MUTE_CONTROL:
samux 1:80ab0d068708 246 switch (transfer->setup.bRequest) {
samux 1:80ab0d068708 247 case REQUEST_GET_CUR:
samux 1:80ab0d068708 248 transfer->remaining = 1;
samux 1:80ab0d068708 249 transfer->ptr = &mute;
samux 1:80ab0d068708 250 transfer->direction = DEVICE_TO_HOST;
samux 1:80ab0d068708 251 success = true;
samux 1:80ab0d068708 252 break;
samux 1:80ab0d068708 253
samux 1:80ab0d068708 254 case REQUEST_SET_CUR:
samux 1:80ab0d068708 255 transfer->remaining = 1;
samux 1:80ab0d068708 256 transfer->notify = true;
samux 1:80ab0d068708 257 transfer->direction = HOST_TO_DEVICE;
samux 1:80ab0d068708 258 success = true;
samux 1:80ab0d068708 259 break;
samux 1:80ab0d068708 260 default:
samux 1:80ab0d068708 261 break;
samux 1:80ab0d068708 262 }
samux 1:80ab0d068708 263 break;
samux 1:80ab0d068708 264 case VOLUME_CONTROL:
samux 1:80ab0d068708 265 switch (transfer->setup.bRequest) {
samux 1:80ab0d068708 266 case REQUEST_GET_CUR:
samux 1:80ab0d068708 267 transfer->remaining = 2;
samux 1:80ab0d068708 268 transfer->ptr = (uint8_t *)&volCur;
samux 1:80ab0d068708 269 transfer->direction = DEVICE_TO_HOST;
samux 1:80ab0d068708 270 success = true;
samux 1:80ab0d068708 271 break;
samux 1:80ab0d068708 272 case REQUEST_GET_MIN:
samux 1:80ab0d068708 273 transfer->remaining = 2;
samux 1:80ab0d068708 274 transfer->ptr = (uint8_t *)&volMin;
samux 1:80ab0d068708 275 transfer->direction = DEVICE_TO_HOST;
samux 1:80ab0d068708 276 success = true;
samux 1:80ab0d068708 277 break;
samux 1:80ab0d068708 278 case REQUEST_GET_MAX:
samux 1:80ab0d068708 279 transfer->remaining = 2;
samux 1:80ab0d068708 280 transfer->ptr = (uint8_t *)&volMax;
samux 1:80ab0d068708 281 transfer->direction = DEVICE_TO_HOST;
samux 1:80ab0d068708 282 success = true;
samux 1:80ab0d068708 283 break;
samux 1:80ab0d068708 284 case REQUEST_GET_RES:
samux 1:80ab0d068708 285 transfer->remaining = 2;
samux 1:80ab0d068708 286 transfer->ptr = (uint8_t *)&volRes;
samux 1:80ab0d068708 287 transfer->direction = DEVICE_TO_HOST;
samux 1:80ab0d068708 288 success = true;
samux 1:80ab0d068708 289 break;
samux 1:80ab0d068708 290
samux 1:80ab0d068708 291 case REQUEST_SET_CUR:
samux 1:80ab0d068708 292 transfer->remaining = 2;
samux 1:80ab0d068708 293 transfer->notify = true;
samux 1:80ab0d068708 294 transfer->direction = HOST_TO_DEVICE;
samux 1:80ab0d068708 295 success = true;
samux 1:80ab0d068708 296 break;
samux 1:80ab0d068708 297 case REQUEST_SET_MIN:
samux 1:80ab0d068708 298 transfer->remaining = 2;
samux 1:80ab0d068708 299 transfer->notify = true;
samux 1:80ab0d068708 300 transfer->direction = HOST_TO_DEVICE;
samux 1:80ab0d068708 301 success = true;
samux 1:80ab0d068708 302 break;
samux 1:80ab0d068708 303 case REQUEST_SET_MAX:
samux 1:80ab0d068708 304 transfer->remaining = 2;
samux 1:80ab0d068708 305 transfer->notify = true;
samux 1:80ab0d068708 306 transfer->direction = HOST_TO_DEVICE;
samux 1:80ab0d068708 307 success = true;
samux 1:80ab0d068708 308 break;
samux 1:80ab0d068708 309 case REQUEST_SET_RES:
samux 1:80ab0d068708 310 transfer->remaining = 2;
samux 1:80ab0d068708 311 transfer->notify = true;
samux 1:80ab0d068708 312 transfer->direction = HOST_TO_DEVICE;
samux 1:80ab0d068708 313 success = true;
samux 1:80ab0d068708 314 break;
samux 1:80ab0d068708 315 }
samux 1:80ab0d068708 316 break;
samux 1:80ab0d068708 317 default:
samux 1:80ab0d068708 318 break;
samux 1:80ab0d068708 319 }
samux 1:80ab0d068708 320 }
samux 1:80ab0d068708 321 }
samux 1:80ab0d068708 322 }
samux 1:80ab0d068708 323 return success;
samux 1:80ab0d068708 324 }
samux 1:80ab0d068708 325
samux 1:80ab0d068708 326
samux 1:80ab0d068708 327 // Called in ISR context when a data OUT stage has been performed
samux 1:80ab0d068708 328 void USBAudio::USBCallback_requestCompleted(uint8_t * buf, uint32_t length) {
samux 1:80ab0d068708 329 if ((length == 1) || (length == 2)) {
samux 1:80ab0d068708 330 uint16_t data = (length == 1) ? *buf : *((uint16_t *)buf);
samux 1:80ab0d068708 331 CONTROL_TRANSFER * transfer = getTransferPtr();
samux 1:80ab0d068708 332 switch (transfer->setup.wValue >> 8) {
samux 1:80ab0d068708 333 case MUTE_CONTROL:
samux 1:80ab0d068708 334 switch (transfer->setup.bRequest) {
samux 1:80ab0d068708 335 case REQUEST_SET_CUR:
samux 1:80ab0d068708 336 mute = data & 0xff;
Kojto 70:2c525a50f1b6 337 if (updateVol)
Kojto 70:2c525a50f1b6 338 updateVol.call();
samux 1:80ab0d068708 339 break;
samux 1:80ab0d068708 340 default:
samux 1:80ab0d068708 341 break;
samux 1:80ab0d068708 342 }
samux 1:80ab0d068708 343 break;
samux 1:80ab0d068708 344 case VOLUME_CONTROL:
samux 1:80ab0d068708 345 switch (transfer->setup.bRequest) {
samux 1:80ab0d068708 346 case REQUEST_SET_CUR:
samux 1:80ab0d068708 347 volCur = data;
samux 1:80ab0d068708 348 volume = (float)volCur/(float)volMax;
Kojto 70:2c525a50f1b6 349 if (updateVol)
Kojto 70:2c525a50f1b6 350 updateVol.call();
samux 1:80ab0d068708 351 break;
samux 1:80ab0d068708 352 default:
samux 1:80ab0d068708 353 break;
samux 1:80ab0d068708 354 }
samux 1:80ab0d068708 355 break;
samux 1:80ab0d068708 356 default:
samux 1:80ab0d068708 357 break;
samux 1:80ab0d068708 358 }
samux 1:80ab0d068708 359 }
samux 1:80ab0d068708 360 }
samux 1:80ab0d068708 361
samux 1:80ab0d068708 362
samux 1:80ab0d068708 363
samux 1:80ab0d068708 364 #define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \
samux 1:80ab0d068708 365 + (5 * INTERFACE_DESCRIPTOR_LENGTH) \
samux 1:80ab0d068708 366 + (1 * CONTROL_INTERFACE_DESCRIPTOR_LENGTH + 1) \
samux 1:80ab0d068708 367 + (2 * INPUT_TERMINAL_DESCRIPTOR_LENGTH) \
samux 1:80ab0d068708 368 + (1 * FEATURE_UNIT_DESCRIPTOR_LENGTH) \
samux 1:80ab0d068708 369 + (2 * OUTPUT_TERMINAL_DESCRIPTOR_LENGTH) \
samux 1:80ab0d068708 370 + (2 * STREAMING_INTERFACE_DESCRIPTOR_LENGTH) \
samux 1:80ab0d068708 371 + (2 * FORMAT_TYPE_I_DESCRIPTOR_LENGTH) \
samux 1:80ab0d068708 372 + (2 * (ENDPOINT_DESCRIPTOR_LENGTH + 2)) \
samux 1:80ab0d068708 373 + (2 * STREAMING_ENDPOINT_DESCRIPTOR_LENGTH) )
samux 1:80ab0d068708 374
samux 1:80ab0d068708 375 #define TOTAL_CONTROL_INTF_LENGTH (CONTROL_INTERFACE_DESCRIPTOR_LENGTH + 1 + \
samux 1:80ab0d068708 376 2*INPUT_TERMINAL_DESCRIPTOR_LENGTH + \
samux 1:80ab0d068708 377 FEATURE_UNIT_DESCRIPTOR_LENGTH + \
samux 1:80ab0d068708 378 2*OUTPUT_TERMINAL_DESCRIPTOR_LENGTH)
samux 1:80ab0d068708 379
samux 1:80ab0d068708 380 uint8_t * USBAudio::configurationDesc() {
samux 1:80ab0d068708 381 static uint8_t configDescriptor[] = {
samux 1:80ab0d068708 382 // Configuration 1
samux 1:80ab0d068708 383 CONFIGURATION_DESCRIPTOR_LENGTH, // bLength
samux 1:80ab0d068708 384 CONFIGURATION_DESCRIPTOR, // bDescriptorType
samux 1:80ab0d068708 385 LSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (LSB)
samux 1:80ab0d068708 386 MSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (MSB)
samux 1:80ab0d068708 387 0x03, // bNumInterfaces
samux 1:80ab0d068708 388 DEFAULT_CONFIGURATION, // bConfigurationValue
samux 1:80ab0d068708 389 0x00, // iConfiguration
samux 1:80ab0d068708 390 0x80, // bmAttributes
samux 1:80ab0d068708 391 50, // bMaxPower
samux 1:80ab0d068708 392
samux 1:80ab0d068708 393 // Interface 0, Alternate Setting 0, Audio Control
samux 1:80ab0d068708 394 INTERFACE_DESCRIPTOR_LENGTH, // bLength
samux 1:80ab0d068708 395 INTERFACE_DESCRIPTOR, // bDescriptorType
samux 1:80ab0d068708 396 0x00, // bInterfaceNumber
samux 1:80ab0d068708 397 0x00, // bAlternateSetting
samux 1:80ab0d068708 398 0x00, // bNumEndpoints
samux 1:80ab0d068708 399 AUDIO_CLASS, // bInterfaceClass
samux 1:80ab0d068708 400 SUBCLASS_AUDIOCONTROL, // bInterfaceSubClass
samux 1:80ab0d068708 401 0x00, // bInterfaceProtocol
samux 1:80ab0d068708 402 0x00, // iInterface
samux 1:80ab0d068708 403
samux 1:80ab0d068708 404
samux 1:80ab0d068708 405 // Audio Control Interface
samux 1:80ab0d068708 406 CONTROL_INTERFACE_DESCRIPTOR_LENGTH + 1,// bLength
samux 1:80ab0d068708 407 INTERFACE_DESCRIPTOR_TYPE, // bDescriptorType
samux 1:80ab0d068708 408 CONTROL_HEADER, // bDescriptorSubtype
samux 1:80ab0d068708 409 LSB(0x0100), // bcdADC (LSB)
samux 1:80ab0d068708 410 MSB(0x0100), // bcdADC (MSB)
samux 1:80ab0d068708 411 LSB(TOTAL_CONTROL_INTF_LENGTH), // wTotalLength
samux 1:80ab0d068708 412 MSB(TOTAL_CONTROL_INTF_LENGTH), // wTotalLength
samux 1:80ab0d068708 413 0x02, // bInCollection
samux 1:80ab0d068708 414 0x01, // baInterfaceNr
samux 1:80ab0d068708 415 0x02, // baInterfaceNr
samux 1:80ab0d068708 416
samux 1:80ab0d068708 417 // Audio Input Terminal (Speaker)
samux 1:80ab0d068708 418 INPUT_TERMINAL_DESCRIPTOR_LENGTH, // bLength
samux 1:80ab0d068708 419 INTERFACE_DESCRIPTOR_TYPE, // bDescriptorType
samux 1:80ab0d068708 420 CONTROL_INPUT_TERMINAL, // bDescriptorSubtype
samux 1:80ab0d068708 421 0x01, // bTerminalID
samux 1:80ab0d068708 422 LSB(TERMINAL_USB_STREAMING), // wTerminalType
samux 1:80ab0d068708 423 MSB(TERMINAL_USB_STREAMING), // wTerminalType
samux 1:80ab0d068708 424 0x00, // bAssocTerminal
samux 1:80ab0d068708 425 channel_nb_in, // bNrChannels
bogdanm 11:eeb3cbbaa996 426 (uint8_t)(LSB(channel_config_in)), // wChannelConfig
bogdanm 11:eeb3cbbaa996 427 (uint8_t)(MSB(channel_config_in)), // wChannelConfig
samux 1:80ab0d068708 428 0x00, // iChannelNames
samux 1:80ab0d068708 429 0x00, // iTerminal
samux 1:80ab0d068708 430
samux 1:80ab0d068708 431 // Audio Feature Unit (Speaker)
samux 1:80ab0d068708 432 FEATURE_UNIT_DESCRIPTOR_LENGTH, // bLength
samux 1:80ab0d068708 433 INTERFACE_DESCRIPTOR_TYPE, // bDescriptorType
samux 1:80ab0d068708 434 CONTROL_FEATURE_UNIT, // bDescriptorSubtype
samux 1:80ab0d068708 435 0x02, // bUnitID
samux 1:80ab0d068708 436 0x01, // bSourceID
samux 1:80ab0d068708 437 0x01, // bControlSize
samux 1:80ab0d068708 438 CONTROL_MUTE |
samux 1:80ab0d068708 439 CONTROL_VOLUME, // bmaControls(0)
samux 1:80ab0d068708 440 0x00, // bmaControls(1)
samux 1:80ab0d068708 441 0x00, // iTerminal
samux 1:80ab0d068708 442
samux 1:80ab0d068708 443 // Audio Output Terminal (Speaker)
samux 1:80ab0d068708 444 OUTPUT_TERMINAL_DESCRIPTOR_LENGTH, // bLength
samux 1:80ab0d068708 445 INTERFACE_DESCRIPTOR_TYPE, // bDescriptorType
samux 1:80ab0d068708 446 CONTROL_OUTPUT_TERMINAL, // bDescriptorSubtype
samux 1:80ab0d068708 447 0x03, // bTerminalID
samux 1:80ab0d068708 448 LSB(TERMINAL_SPEAKER), // wTerminalType
samux 1:80ab0d068708 449 MSB(TERMINAL_SPEAKER), // wTerminalType
samux 1:80ab0d068708 450 0x00, // bAssocTerminal
samux 1:80ab0d068708 451 0x02, // bSourceID
samux 1:80ab0d068708 452 0x00, // iTerminal
samux 1:80ab0d068708 453
samux 1:80ab0d068708 454
samux 1:80ab0d068708 455 // Audio Input Terminal (Microphone)
samux 1:80ab0d068708 456 INPUT_TERMINAL_DESCRIPTOR_LENGTH, // bLength
samux 1:80ab0d068708 457 INTERFACE_DESCRIPTOR_TYPE, // bDescriptorType
samux 1:80ab0d068708 458 CONTROL_INPUT_TERMINAL, // bDescriptorSubtype
samux 1:80ab0d068708 459 0x04, // bTerminalID
samux 1:80ab0d068708 460 LSB(TERMINAL_MICROPHONE), // wTerminalType
samux 1:80ab0d068708 461 MSB(TERMINAL_MICROPHONE), // wTerminalType
samux 1:80ab0d068708 462 0x00, // bAssocTerminal
samux 1:80ab0d068708 463 channel_nb_out, // bNrChannels
bogdanm 11:eeb3cbbaa996 464 (uint8_t)(LSB(channel_config_out)), // wChannelConfig
bogdanm 11:eeb3cbbaa996 465 (uint8_t)(MSB(channel_config_out)), // wChannelConfig
samux 1:80ab0d068708 466 0x00, // iChannelNames
samux 1:80ab0d068708 467 0x00, // iTerminal
samux 1:80ab0d068708 468
samux 1:80ab0d068708 469 // Audio Output Terminal (Microphone)
samux 1:80ab0d068708 470 OUTPUT_TERMINAL_DESCRIPTOR_LENGTH, // bLength
samux 1:80ab0d068708 471 INTERFACE_DESCRIPTOR_TYPE, // bDescriptorType
samux 1:80ab0d068708 472 CONTROL_OUTPUT_TERMINAL, // bDescriptorSubtype
samux 1:80ab0d068708 473 0x05, // bTerminalID
samux 1:80ab0d068708 474 LSB(TERMINAL_USB_STREAMING), // wTerminalType
samux 1:80ab0d068708 475 MSB(TERMINAL_USB_STREAMING), // wTerminalType
samux 1:80ab0d068708 476 0x00, // bAssocTerminal
samux 1:80ab0d068708 477 0x04, // bSourceID
samux 1:80ab0d068708 478 0x00, // iTerminal
samux 1:80ab0d068708 479
samux 1:80ab0d068708 480
samux 1:80ab0d068708 481
samux 1:80ab0d068708 482
samux 1:80ab0d068708 483
samux 1:80ab0d068708 484
samux 1:80ab0d068708 485 // Interface 1, Alternate Setting 0, Audio Streaming - Zero Bandwith
samux 1:80ab0d068708 486 INTERFACE_DESCRIPTOR_LENGTH, // bLength
samux 1:80ab0d068708 487 INTERFACE_DESCRIPTOR, // bDescriptorType
samux 1:80ab0d068708 488 0x01, // bInterfaceNumber
samux 1:80ab0d068708 489 0x00, // bAlternateSetting
samux 1:80ab0d068708 490 0x00, // bNumEndpoints
samux 1:80ab0d068708 491 AUDIO_CLASS, // bInterfaceClass
samux 1:80ab0d068708 492 SUBCLASS_AUDIOSTREAMING, // bInterfaceSubClass
samux 1:80ab0d068708 493 0x00, // bInterfaceProtocol
samux 1:80ab0d068708 494 0x00, // iInterface
samux 1:80ab0d068708 495
samux 1:80ab0d068708 496 // Interface 1, Alternate Setting 1, Audio Streaming - Operational
samux 1:80ab0d068708 497 INTERFACE_DESCRIPTOR_LENGTH, // bLength
samux 1:80ab0d068708 498 INTERFACE_DESCRIPTOR, // bDescriptorType
samux 1:80ab0d068708 499 0x01, // bInterfaceNumber
samux 1:80ab0d068708 500 0x01, // bAlternateSetting
samux 1:80ab0d068708 501 0x01, // bNumEndpoints
samux 1:80ab0d068708 502 AUDIO_CLASS, // bInterfaceClass
samux 1:80ab0d068708 503 SUBCLASS_AUDIOSTREAMING, // bInterfaceSubClass
samux 1:80ab0d068708 504 0x00, // bInterfaceProtocol
samux 1:80ab0d068708 505 0x00, // iInterface
samux 1:80ab0d068708 506
samux 1:80ab0d068708 507 // Audio Streaming Interface
samux 1:80ab0d068708 508 STREAMING_INTERFACE_DESCRIPTOR_LENGTH, // bLength
samux 1:80ab0d068708 509 INTERFACE_DESCRIPTOR_TYPE, // bDescriptorType
samux 1:80ab0d068708 510 STREAMING_GENERAL, // bDescriptorSubtype
samux 1:80ab0d068708 511 0x01, // bTerminalLink
samux 1:80ab0d068708 512 0x00, // bDelay
samux 1:80ab0d068708 513 LSB(FORMAT_PCM), // wFormatTag
samux 1:80ab0d068708 514 MSB(FORMAT_PCM), // wFormatTag
samux 1:80ab0d068708 515
samux 1:80ab0d068708 516 // Audio Type I Format
samux 1:80ab0d068708 517 FORMAT_TYPE_I_DESCRIPTOR_LENGTH, // bLength
samux 1:80ab0d068708 518 INTERFACE_DESCRIPTOR_TYPE, // bDescriptorType
samux 1:80ab0d068708 519 STREAMING_FORMAT_TYPE, // bDescriptorSubtype
samux 1:80ab0d068708 520 FORMAT_TYPE_I, // bFormatType
samux 1:80ab0d068708 521 channel_nb_in, // bNrChannels
samux 1:80ab0d068708 522 0x02, // bSubFrameSize
samux 1:80ab0d068708 523 16, // bBitResolution
samux 1:80ab0d068708 524 0x01, // bSamFreqType
bogdanm 11:eeb3cbbaa996 525 (uint8_t)(LSB(FREQ_IN)), // tSamFreq
bogdanm 11:eeb3cbbaa996 526 (uint8_t)((FREQ_IN >> 8) & 0xff), // tSamFreq
bogdanm 11:eeb3cbbaa996 527 (uint8_t)((FREQ_IN >> 16) & 0xff), // tSamFreq
samux 1:80ab0d068708 528
samux 1:80ab0d068708 529 // Endpoint - Standard Descriptor
samux 1:80ab0d068708 530 ENDPOINT_DESCRIPTOR_LENGTH + 2, // bLength
samux 1:80ab0d068708 531 ENDPOINT_DESCRIPTOR, // bDescriptorType
samux 1:80ab0d068708 532 PHY_TO_DESC(EPISO_OUT), // bEndpointAddress
samux 1:80ab0d068708 533 E_ISOCHRONOUS, // bmAttributes
bogdanm 11:eeb3cbbaa996 534 (uint8_t)(LSB(PACKET_SIZE_ISO_IN)), // wMaxPacketSize
bogdanm 11:eeb3cbbaa996 535 (uint8_t)(MSB(PACKET_SIZE_ISO_IN)), // wMaxPacketSize
samux 1:80ab0d068708 536 0x01, // bInterval
samux 1:80ab0d068708 537 0x00, // bRefresh
samux 1:80ab0d068708 538 0x00, // bSynchAddress
samux 1:80ab0d068708 539
samux 1:80ab0d068708 540 // Endpoint - Audio Streaming
samux 1:80ab0d068708 541 STREAMING_ENDPOINT_DESCRIPTOR_LENGTH, // bLength
samux 1:80ab0d068708 542 ENDPOINT_DESCRIPTOR_TYPE, // bDescriptorType
samux 1:80ab0d068708 543 ENDPOINT_GENERAL, // bDescriptor
samux 1:80ab0d068708 544 0x00, // bmAttributes
samux 1:80ab0d068708 545 0x00, // bLockDelayUnits
samux 1:80ab0d068708 546 LSB(0x0000), // wLockDelay
samux 1:80ab0d068708 547 MSB(0x0000), // wLockDelay
samux 1:80ab0d068708 548
samux 1:80ab0d068708 549
samux 1:80ab0d068708 550
samux 1:80ab0d068708 551
samux 1:80ab0d068708 552
samux 1:80ab0d068708 553
samux 1:80ab0d068708 554
samux 1:80ab0d068708 555 // Interface 1, Alternate Setting 0, Audio Streaming - Zero Bandwith
samux 1:80ab0d068708 556 INTERFACE_DESCRIPTOR_LENGTH, // bLength
samux 1:80ab0d068708 557 INTERFACE_DESCRIPTOR, // bDescriptorType
samux 1:80ab0d068708 558 0x02, // bInterfaceNumber
samux 1:80ab0d068708 559 0x00, // bAlternateSetting
samux 1:80ab0d068708 560 0x00, // bNumEndpoints
samux 1:80ab0d068708 561 AUDIO_CLASS, // bInterfaceClass
samux 1:80ab0d068708 562 SUBCLASS_AUDIOSTREAMING, // bInterfaceSubClass
samux 1:80ab0d068708 563 0x00, // bInterfaceProtocol
samux 1:80ab0d068708 564 0x00, // iInterface
samux 1:80ab0d068708 565
samux 1:80ab0d068708 566 // Interface 1, Alternate Setting 1, Audio Streaming - Operational
samux 1:80ab0d068708 567 INTERFACE_DESCRIPTOR_LENGTH, // bLength
samux 1:80ab0d068708 568 INTERFACE_DESCRIPTOR, // bDescriptorType
samux 1:80ab0d068708 569 0x02, // bInterfaceNumber
samux 1:80ab0d068708 570 0x01, // bAlternateSetting
samux 1:80ab0d068708 571 0x01, // bNumEndpoints
samux 1:80ab0d068708 572 AUDIO_CLASS, // bInterfaceClass
samux 1:80ab0d068708 573 SUBCLASS_AUDIOSTREAMING, // bInterfaceSubClass
samux 1:80ab0d068708 574 0x00, // bInterfaceProtocol
samux 1:80ab0d068708 575 0x00, // iInterface
samux 1:80ab0d068708 576
samux 1:80ab0d068708 577 // Audio Streaming Interface
samux 1:80ab0d068708 578 STREAMING_INTERFACE_DESCRIPTOR_LENGTH, // bLength
samux 1:80ab0d068708 579 INTERFACE_DESCRIPTOR_TYPE, // bDescriptorType
samux 1:80ab0d068708 580 SUBCLASS_AUDIOCONTROL, // bDescriptorSubtype
samux 1:80ab0d068708 581 0x05, // bTerminalLink (output terminal microphone)
samux 1:80ab0d068708 582 0x01, // bDelay
samux 1:80ab0d068708 583 0x01, // wFormatTag
samux 1:80ab0d068708 584 0x00, // wFormatTag
samux 1:80ab0d068708 585
samux 1:80ab0d068708 586 // Audio Type I Format
samux 1:80ab0d068708 587 FORMAT_TYPE_I_DESCRIPTOR_LENGTH, // bLength
samux 1:80ab0d068708 588 INTERFACE_DESCRIPTOR_TYPE, // bDescriptorType
samux 1:80ab0d068708 589 SUBCLASS_AUDIOSTREAMING, // bDescriptorSubtype
samux 1:80ab0d068708 590 FORMAT_TYPE_I, // bFormatType
samux 1:80ab0d068708 591 channel_nb_out, // bNrChannels
samux 1:80ab0d068708 592 0x02, // bSubFrameSize
samux 1:80ab0d068708 593 0x10, // bBitResolution
samux 1:80ab0d068708 594 0x01, // bSamFreqType
bogdanm 11:eeb3cbbaa996 595 (uint8_t)(LSB(FREQ_OUT)), // tSamFreq
bogdanm 11:eeb3cbbaa996 596 (uint8_t)((FREQ_OUT >> 8) & 0xff), // tSamFreq
bogdanm 11:eeb3cbbaa996 597 (uint8_t)((FREQ_OUT >> 16) & 0xff), // tSamFreq
samux 1:80ab0d068708 598
samux 1:80ab0d068708 599 // Endpoint - Standard Descriptor
samux 1:80ab0d068708 600 ENDPOINT_DESCRIPTOR_LENGTH + 2, // bLength
samux 1:80ab0d068708 601 ENDPOINT_DESCRIPTOR, // bDescriptorType
samux 1:80ab0d068708 602 PHY_TO_DESC(EPISO_IN), // bEndpointAddress
samux 1:80ab0d068708 603 E_ISOCHRONOUS, // bmAttributes
Kojto 70:2c525a50f1b6 604 (uint8_t)(LSB(PACKET_SIZE_ISO_OUT+channel_nb_out*2)), // wMaxPacketSize
Kojto 70:2c525a50f1b6 605 (uint8_t)(MSB(PACKET_SIZE_ISO_OUT+channel_nb_out*2)), // wMaxPacketSize
samux 1:80ab0d068708 606 0x01, // bInterval
samux 1:80ab0d068708 607 0x00, // bRefresh
samux 1:80ab0d068708 608 0x00, // bSynchAddress
samux 1:80ab0d068708 609
samux 1:80ab0d068708 610 // Endpoint - Audio Streaming
samux 1:80ab0d068708 611 STREAMING_ENDPOINT_DESCRIPTOR_LENGTH, // bLength
samux 1:80ab0d068708 612 ENDPOINT_DESCRIPTOR_TYPE, // bDescriptorType
samux 1:80ab0d068708 613 ENDPOINT_GENERAL, // bDescriptor
samux 1:80ab0d068708 614 0x00, // bmAttributes
samux 1:80ab0d068708 615 0x00, // bLockDelayUnits
samux 1:80ab0d068708 616 LSB(0x0000), // wLockDelay
samux 1:80ab0d068708 617 MSB(0x0000), // wLockDelay
samux 1:80ab0d068708 618
samux 1:80ab0d068708 619 // Terminator
samux 1:80ab0d068708 620 0 // bLength
samux 1:80ab0d068708 621 };
samux 1:80ab0d068708 622 return configDescriptor;
samux 1:80ab0d068708 623 }
samux 1:80ab0d068708 624
samux 1:80ab0d068708 625 uint8_t * USBAudio::stringIinterfaceDesc() {
samux 1:80ab0d068708 626 static uint8_t stringIinterfaceDescriptor[] = {
samux 1:80ab0d068708 627 0x0c, //bLength
samux 1:80ab0d068708 628 STRING_DESCRIPTOR, //bDescriptorType 0x03
samux 1:80ab0d068708 629 'A',0,'u',0,'d',0,'i',0,'o',0 //bString iInterface - Audio
samux 1:80ab0d068708 630 };
samux 1:80ab0d068708 631 return stringIinterfaceDescriptor;
samux 1:80ab0d068708 632 }
samux 1:80ab0d068708 633
samux 1:80ab0d068708 634 uint8_t * USBAudio::stringIproductDesc() {
samux 1:80ab0d068708 635 static uint8_t stringIproductDescriptor[] = {
samux 1:80ab0d068708 636 0x16, //bLength
samux 1:80ab0d068708 637 STRING_DESCRIPTOR, //bDescriptorType 0x03
samux 1:80ab0d068708 638 'M',0,'b',0,'e',0,'d',0,' ',0,'A',0,'u',0,'d',0,'i',0,'o',0 //bString iProduct - Mbed Audio
samux 1:80ab0d068708 639 };
samux 1:80ab0d068708 640 return stringIproductDescriptor;
samux 1:80ab0d068708 641 }