KL46Z-lab2

Dependencies:   SLCD- mbed TSI MMA8451Q USBDevice MAG3110

Committer:
Lokkus
Date:
Thu Feb 21 07:41:00 2019 +0000
Revision:
0:29277ae50860
KL46Z-lab2

Who changed what in which revision?

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