nkjnm

Dependencies:   MAX44000 nexpaq_mdk

Fork of LED_Demo by Maxim nexpaq

Committer:
nexpaq
Date:
Sat Sep 17 16:32:05 2016 +0000
Revision:
1:55a6170b404f
checking in for sharing

Who changed what in which revision?

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