Sensor reporting over USB CDC

Dependencies:   MAG3110 MMA8451Q SLCD- TSI USBDevice mbed

Committer:
wue
Date:
Wed Apr 16 12:20:12 2014 +0000
Revision:
0:7b58cdacf811
Sensor reporting over USB CDC

Who changed what in which revision?

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