max4146x_comp

Dependencies:   MAX14690

Committer:
sdivarci
Date:
Sun Oct 25 20:10:02 2020 +0000
Revision:
0:0061165683ee
sdivarci

Who changed what in which revision?

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