USB CDC (serial) and USB MSC (strage) Composite Device. http://mbed.org/users/okini3939/notebook/USB_Device/

Dependencies:   ChaNFSSD mbed ChaNFS

Committer:
okini3939
Date:
Fri Dec 23 16:37:58 2011 +0000
Revision:
2:5db90410bb90
Parent:
0:9b1d17d54055

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
okini3939 0:9b1d17d54055 1 /* Copyright (c) 2010-2011 mbed.org, MIT License
okini3939 0:9b1d17d54055 2 *
okini3939 0:9b1d17d54055 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
okini3939 0:9b1d17d54055 4 * and associated documentation files (the "Software"), to deal in the Software without
okini3939 0:9b1d17d54055 5 * restriction, including without limitation the rights to use, copy, modify, merge, publish,
okini3939 0:9b1d17d54055 6 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
okini3939 0:9b1d17d54055 7 * Software is furnished to do so, subject to the following conditions:
okini3939 0:9b1d17d54055 8 *
okini3939 0:9b1d17d54055 9 * The above copyright notice and this permission notice shall be included in all copies or
okini3939 0:9b1d17d54055 10 * substantial portions of the Software.
okini3939 0:9b1d17d54055 11 *
okini3939 0:9b1d17d54055 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
okini3939 0:9b1d17d54055 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
okini3939 0:9b1d17d54055 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
okini3939 0:9b1d17d54055 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
okini3939 0:9b1d17d54055 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
okini3939 0:9b1d17d54055 17 */
okini3939 0:9b1d17d54055 18
okini3939 0:9b1d17d54055 19 #include "stdint.h"
okini3939 0:9b1d17d54055 20 #include "USBAudio.h"
okini3939 0:9b1d17d54055 21 #include "USBBusInterface.h"
okini3939 0:9b1d17d54055 22 #include "USBAudio_Types.h"
okini3939 0:9b1d17d54055 23
okini3939 0:9b1d17d54055 24
okini3939 0:9b1d17d54055 25
okini3939 0:9b1d17d54055 26 USBAudio::USBAudio(uint32_t frequency, uint8_t channel_nb, uint16_t vendor_id, uint16_t product_id, uint16_t product_release): USBDevice(vendor_id, product_id, product_release) {
okini3939 0:9b1d17d54055 27 mute = 0;
okini3939 0:9b1d17d54055 28 volCur = 0x0080;
okini3939 0:9b1d17d54055 29 volMin = 0x0000;
okini3939 0:9b1d17d54055 30 volMax = 0x0100;
okini3939 0:9b1d17d54055 31 volRes = 0x0004;
okini3939 0:9b1d17d54055 32 available = false;
okini3939 0:9b1d17d54055 33
okini3939 0:9b1d17d54055 34 FREQ = frequency;
okini3939 0:9b1d17d54055 35
okini3939 0:9b1d17d54055 36 this->channel_nb = channel_nb;
okini3939 0:9b1d17d54055 37
okini3939 0:9b1d17d54055 38 // stereo -> *2, mono -> *1
okini3939 0:9b1d17d54055 39 PACKET_SIZE_ISO = (FREQ / 500) * channel_nb;
okini3939 0:9b1d17d54055 40
okini3939 0:9b1d17d54055 41 // STEREO -> left and right
okini3939 0:9b1d17d54055 42 channel_config = (channel_nb == 1) ? CHANNEL_M : CHANNEL_L + CHANNEL_R;
okini3939 0:9b1d17d54055 43
okini3939 0:9b1d17d54055 44 SOF_handler = false;
okini3939 0:9b1d17d54055 45
okini3939 0:9b1d17d54055 46 buf_stream = NULL;
okini3939 0:9b1d17d54055 47
okini3939 0:9b1d17d54055 48 // connect the device
okini3939 0:9b1d17d54055 49 USBDevice::connect();
okini3939 0:9b1d17d54055 50 }
okini3939 0:9b1d17d54055 51
okini3939 0:9b1d17d54055 52 bool USBAudio::read(uint8_t * buf) {
okini3939 0:9b1d17d54055 53 buf_stream = buf;
okini3939 0:9b1d17d54055 54 while (!available);
okini3939 0:9b1d17d54055 55 available = false;
okini3939 0:9b1d17d54055 56 buf_stream = NULL;
okini3939 0:9b1d17d54055 57 return true;
okini3939 0:9b1d17d54055 58 }
okini3939 0:9b1d17d54055 59
okini3939 0:9b1d17d54055 60 bool USBAudio::readNB(uint8_t * buf) {
okini3939 0:9b1d17d54055 61 buf_stream = buf;
okini3939 0:9b1d17d54055 62 SOF_handler = false;
okini3939 0:9b1d17d54055 63 while (!SOF_handler);
okini3939 0:9b1d17d54055 64 if (available) {
okini3939 0:9b1d17d54055 65 available = false;
okini3939 0:9b1d17d54055 66 buf_stream = NULL;
okini3939 0:9b1d17d54055 67 return true;
okini3939 0:9b1d17d54055 68 }
okini3939 0:9b1d17d54055 69 buf_stream = NULL;
okini3939 0:9b1d17d54055 70 return false;
okini3939 0:9b1d17d54055 71 }
okini3939 0:9b1d17d54055 72
okini3939 0:9b1d17d54055 73
okini3939 0:9b1d17d54055 74 float USBAudio::getVolume() {
okini3939 0:9b1d17d54055 75 return (mute) ? 0.0 : (float)volCur/(float)volMax;
okini3939 0:9b1d17d54055 76 }
okini3939 0:9b1d17d54055 77
okini3939 0:9b1d17d54055 78
okini3939 0:9b1d17d54055 79 // Called in ISR context on each start of frame
okini3939 0:9b1d17d54055 80 void USBAudio::SOF(int frameNumber) {
okini3939 0:9b1d17d54055 81 uint16_t size = 0;
okini3939 0:9b1d17d54055 82
okini3939 0:9b1d17d54055 83 // read the isochronous endpoint
okini3939 0:9b1d17d54055 84 if (buf_stream != NULL) {
okini3939 0:9b1d17d54055 85 USBDevice::readEP_NB(EP3OUT, buf_stream, &size, PACKET_SIZE_ISO);
okini3939 0:9b1d17d54055 86 }
okini3939 0:9b1d17d54055 87
okini3939 0:9b1d17d54055 88 // if we read something, modify the flag "available"
okini3939 0:9b1d17d54055 89 available = (size) ? true : false;
okini3939 0:9b1d17d54055 90
okini3939 0:9b1d17d54055 91 // activate readings on the isochronous
okini3939 0:9b1d17d54055 92 readStart(EP3OUT, PACKET_SIZE_ISO);
okini3939 0:9b1d17d54055 93
okini3939 0:9b1d17d54055 94 SOF_handler = true;
okini3939 0:9b1d17d54055 95 }
okini3939 0:9b1d17d54055 96
okini3939 0:9b1d17d54055 97
okini3939 0:9b1d17d54055 98 // Called in ISR context
okini3939 0:9b1d17d54055 99 // Set configuration. Return false if the configuration is not supported.
okini3939 0:9b1d17d54055 100 bool USBAudio::USBCallback_setConfiguration(uint8_t configuration) {
okini3939 0:9b1d17d54055 101 if (configuration != DEFAULT_CONFIGURATION) {
okini3939 0:9b1d17d54055 102 return false;
okini3939 0:9b1d17d54055 103 }
okini3939 0:9b1d17d54055 104
okini3939 0:9b1d17d54055 105 // Configure isochronous endpoint
okini3939 0:9b1d17d54055 106 realiseEndpoint(EP3OUT, PACKET_SIZE_ISO, ISOCHRONOUS);
okini3939 0:9b1d17d54055 107
okini3939 0:9b1d17d54055 108 // activate readings on this endpoint
okini3939 0:9b1d17d54055 109 readStart(EP3OUT, PACKET_SIZE_ISO);
okini3939 0:9b1d17d54055 110 return true;
okini3939 0:9b1d17d54055 111 }
okini3939 0:9b1d17d54055 112
okini3939 0:9b1d17d54055 113
okini3939 0:9b1d17d54055 114 // Called in ISR context
okini3939 0:9b1d17d54055 115 // Set alternate setting. Return false if the alternate setting is not supported
okini3939 0:9b1d17d54055 116 bool USBAudio::USBCallback_setInterface(uint16_t interface, uint8_t alternate) {
okini3939 0:9b1d17d54055 117 if (interface == 0 && alternate == 0) {
okini3939 0:9b1d17d54055 118 return true;
okini3939 0:9b1d17d54055 119 }
okini3939 0:9b1d17d54055 120 if (interface == 1 && (alternate == 0 || alternate == 1)) {
okini3939 0:9b1d17d54055 121 return true;
okini3939 0:9b1d17d54055 122 }
okini3939 0:9b1d17d54055 123 return false;
okini3939 0:9b1d17d54055 124 }
okini3939 0:9b1d17d54055 125
okini3939 0:9b1d17d54055 126
okini3939 0:9b1d17d54055 127
okini3939 0:9b1d17d54055 128 // Called in ISR context
okini3939 0:9b1d17d54055 129 // Called by USBDevice on Endpoint0 request
okini3939 0:9b1d17d54055 130 // This is used to handle extensions to standard requests and class specific requests.
okini3939 0:9b1d17d54055 131 // Return true if class handles this request
okini3939 0:9b1d17d54055 132 bool USBAudio::USBCallback_request() {
okini3939 0:9b1d17d54055 133 bool success = false;
okini3939 0:9b1d17d54055 134 CONTROL_TRANSFER * transfer = getTransferPtr();
okini3939 0:9b1d17d54055 135
okini3939 0:9b1d17d54055 136 // Process class-specific requests
okini3939 0:9b1d17d54055 137 if (transfer->setup.bmRequestType.Type == CLASS_TYPE) {
okini3939 0:9b1d17d54055 138
okini3939 0:9b1d17d54055 139 // Feature Unit: Interface = 0, ID = 2
okini3939 0:9b1d17d54055 140 if (transfer->setup.wIndex == 0x0200) {
okini3939 0:9b1d17d54055 141
okini3939 0:9b1d17d54055 142 // Master Channel
okini3939 0:9b1d17d54055 143 if ((transfer->setup.wValue & 0xff) == 0) {
okini3939 0:9b1d17d54055 144
okini3939 0:9b1d17d54055 145 switch (transfer->setup.wValue >> 8) {
okini3939 0:9b1d17d54055 146 case MUTE_CONTROL:
okini3939 0:9b1d17d54055 147 switch (transfer->setup.bRequest) {
okini3939 0:9b1d17d54055 148 case REQUEST_GET_CUR:
okini3939 0:9b1d17d54055 149 transfer->remaining = 1;
okini3939 0:9b1d17d54055 150 transfer->ptr = &mute;
okini3939 0:9b1d17d54055 151 transfer->direction = DEVICE_TO_HOST;
okini3939 0:9b1d17d54055 152 success = true;
okini3939 0:9b1d17d54055 153 break;
okini3939 0:9b1d17d54055 154
okini3939 0:9b1d17d54055 155 case REQUEST_SET_CUR:
okini3939 0:9b1d17d54055 156 transfer->remaining = 1;
okini3939 0:9b1d17d54055 157 transfer->notify = true;
okini3939 0:9b1d17d54055 158 transfer->direction = HOST_TO_DEVICE;
okini3939 0:9b1d17d54055 159 success = true;
okini3939 0:9b1d17d54055 160 break;
okini3939 0:9b1d17d54055 161 default:
okini3939 0:9b1d17d54055 162 break;
okini3939 0:9b1d17d54055 163 }
okini3939 0:9b1d17d54055 164 break;
okini3939 0:9b1d17d54055 165 case VOLUME_CONTROL:
okini3939 0:9b1d17d54055 166 switch (transfer->setup.bRequest) {
okini3939 0:9b1d17d54055 167 case REQUEST_GET_CUR:
okini3939 0:9b1d17d54055 168 transfer->remaining = 2;
okini3939 0:9b1d17d54055 169 transfer->ptr = (uint8_t *)&volCur;
okini3939 0:9b1d17d54055 170 transfer->direction = DEVICE_TO_HOST;
okini3939 0:9b1d17d54055 171 success = true;
okini3939 0:9b1d17d54055 172 break;
okini3939 0:9b1d17d54055 173 case REQUEST_GET_MIN:
okini3939 0:9b1d17d54055 174 transfer->remaining = 2;
okini3939 0:9b1d17d54055 175 transfer->ptr = (uint8_t *)&volMin;
okini3939 0:9b1d17d54055 176 transfer->direction = DEVICE_TO_HOST;
okini3939 0:9b1d17d54055 177 success = true;
okini3939 0:9b1d17d54055 178 break;
okini3939 0:9b1d17d54055 179 case REQUEST_GET_MAX:
okini3939 0:9b1d17d54055 180 transfer->remaining = 2;
okini3939 0:9b1d17d54055 181 transfer->ptr = (uint8_t *)&volMax;
okini3939 0:9b1d17d54055 182 transfer->direction = DEVICE_TO_HOST;
okini3939 0:9b1d17d54055 183 success = true;
okini3939 0:9b1d17d54055 184 break;
okini3939 0:9b1d17d54055 185 case REQUEST_GET_RES:
okini3939 0:9b1d17d54055 186 transfer->remaining = 2;
okini3939 0:9b1d17d54055 187 transfer->ptr = (uint8_t *)&volRes;
okini3939 0:9b1d17d54055 188 transfer->direction = DEVICE_TO_HOST;
okini3939 0:9b1d17d54055 189 success = true;
okini3939 0:9b1d17d54055 190 break;
okini3939 0:9b1d17d54055 191
okini3939 0:9b1d17d54055 192 case REQUEST_SET_CUR:
okini3939 0:9b1d17d54055 193 transfer->remaining = 2;
okini3939 0:9b1d17d54055 194 transfer->notify = true;
okini3939 0:9b1d17d54055 195 transfer->direction = HOST_TO_DEVICE;
okini3939 0:9b1d17d54055 196 success = true;
okini3939 0:9b1d17d54055 197 break;
okini3939 0:9b1d17d54055 198 case REQUEST_SET_MIN:
okini3939 0:9b1d17d54055 199 transfer->remaining = 2;
okini3939 0:9b1d17d54055 200 transfer->notify = true;
okini3939 0:9b1d17d54055 201 transfer->direction = HOST_TO_DEVICE;
okini3939 0:9b1d17d54055 202 success = true;
okini3939 0:9b1d17d54055 203 break;
okini3939 0:9b1d17d54055 204 case REQUEST_SET_MAX:
okini3939 0:9b1d17d54055 205 transfer->remaining = 2;
okini3939 0:9b1d17d54055 206 transfer->notify = true;
okini3939 0:9b1d17d54055 207 transfer->direction = HOST_TO_DEVICE;
okini3939 0:9b1d17d54055 208 success = true;
okini3939 0:9b1d17d54055 209 break;
okini3939 0:9b1d17d54055 210 case REQUEST_SET_RES:
okini3939 0:9b1d17d54055 211 transfer->remaining = 2;
okini3939 0:9b1d17d54055 212 transfer->notify = true;
okini3939 0:9b1d17d54055 213 transfer->direction = HOST_TO_DEVICE;
okini3939 0:9b1d17d54055 214 success = true;
okini3939 0:9b1d17d54055 215 break;
okini3939 0:9b1d17d54055 216 }
okini3939 0:9b1d17d54055 217 break;
okini3939 0:9b1d17d54055 218 default:
okini3939 0:9b1d17d54055 219 break;
okini3939 0:9b1d17d54055 220 }
okini3939 0:9b1d17d54055 221 }
okini3939 0:9b1d17d54055 222 }
okini3939 0:9b1d17d54055 223 }
okini3939 0:9b1d17d54055 224 return success;
okini3939 0:9b1d17d54055 225 }
okini3939 0:9b1d17d54055 226
okini3939 0:9b1d17d54055 227
okini3939 0:9b1d17d54055 228 // Called in ISR context when a data OUT stage has been performed
okini3939 0:9b1d17d54055 229 void USBAudio::USBCallback_requestCompleted(uint8_t * buf, uint16_t length) {
okini3939 0:9b1d17d54055 230 uint16_t data = *((uint16_t *)buf);
okini3939 0:9b1d17d54055 231 CONTROL_TRANSFER * transfer = getTransferPtr();
okini3939 0:9b1d17d54055 232 switch (transfer->setup.wValue >> 8) {
okini3939 0:9b1d17d54055 233 case MUTE_CONTROL:
okini3939 0:9b1d17d54055 234 switch (transfer->setup.bRequest) {
okini3939 0:9b1d17d54055 235 case REQUEST_SET_CUR:
okini3939 0:9b1d17d54055 236 mute = data & 0xff;
okini3939 0:9b1d17d54055 237 updateVol.call();
okini3939 0:9b1d17d54055 238 break;
okini3939 0:9b1d17d54055 239 default:
okini3939 0:9b1d17d54055 240 break;
okini3939 0:9b1d17d54055 241 }
okini3939 0:9b1d17d54055 242 break;
okini3939 0:9b1d17d54055 243 case VOLUME_CONTROL:
okini3939 0:9b1d17d54055 244 switch (transfer->setup.bRequest) {
okini3939 0:9b1d17d54055 245 case REQUEST_SET_CUR:
okini3939 0:9b1d17d54055 246 volCur = data;
okini3939 0:9b1d17d54055 247 updateVol.call();
okini3939 0:9b1d17d54055 248 break;
okini3939 0:9b1d17d54055 249 default:
okini3939 0:9b1d17d54055 250 break;
okini3939 0:9b1d17d54055 251 }
okini3939 0:9b1d17d54055 252 break;
okini3939 0:9b1d17d54055 253 default:
okini3939 0:9b1d17d54055 254 break;
okini3939 0:9b1d17d54055 255 }
okini3939 0:9b1d17d54055 256 }
okini3939 0:9b1d17d54055 257
okini3939 0:9b1d17d54055 258
okini3939 0:9b1d17d54055 259
okini3939 0:9b1d17d54055 260 #define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \
okini3939 0:9b1d17d54055 261 + (3 * INTERFACE_DESCRIPTOR_LENGTH) \
okini3939 0:9b1d17d54055 262 + (1 * CONTROL_INTERFACE_DESCRIPTOR_LENGTH) \
okini3939 0:9b1d17d54055 263 + (1 * INPUT_TERMINAL_DESCRIPTOR_LENGTH) \
okini3939 0:9b1d17d54055 264 + (1 * FEATURE_UNIT_DESCRIPTOR_LENGTH) \
okini3939 0:9b1d17d54055 265 + (1 * OUTPUT_TERMINAL_DESCRIPTOR_LENGTH) \
okini3939 0:9b1d17d54055 266 + (1 * STREAMING_INTERFACE_DESCRIPTOR_LENGTH) \
okini3939 0:9b1d17d54055 267 + (1 * FORMAT_TYPE_I_DESCRIPTOR_LENGTH) \
okini3939 0:9b1d17d54055 268 + (1 * (ENDPOINT_DESCRIPTOR_LENGTH + 2)) \
okini3939 0:9b1d17d54055 269 + (1 * STREAMING_ENDPOINT_DESCRIPTOR_LENGTH) )
okini3939 0:9b1d17d54055 270
okini3939 0:9b1d17d54055 271 #define TOTAL_CONTROL_INTF_LENGTH (CONTROL_INTERFACE_DESCRIPTOR_LENGTH + \
okini3939 0:9b1d17d54055 272 INPUT_TERMINAL_DESCRIPTOR_LENGTH + \
okini3939 0:9b1d17d54055 273 FEATURE_UNIT_DESCRIPTOR_LENGTH + \
okini3939 0:9b1d17d54055 274 OUTPUT_TERMINAL_DESCRIPTOR_LENGTH)
okini3939 0:9b1d17d54055 275
okini3939 0:9b1d17d54055 276 uint8_t * USBAudio::configurationDesc() {
okini3939 0:9b1d17d54055 277 static uint8_t configDescriptor[] = {
okini3939 0:9b1d17d54055 278 // Configuration 1
okini3939 0:9b1d17d54055 279 CONFIGURATION_DESCRIPTOR_LENGTH, // bLength
okini3939 0:9b1d17d54055 280 CONFIGURATION_DESCRIPTOR, // bDescriptorType
okini3939 0:9b1d17d54055 281 LSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (LSB)
okini3939 0:9b1d17d54055 282 MSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (MSB)
okini3939 0:9b1d17d54055 283 0x02, // bNumInterfaces
okini3939 0:9b1d17d54055 284 DEFAULT_CONFIGURATION, // bConfigurationValue
okini3939 0:9b1d17d54055 285 0x00, // iConfiguration
okini3939 0:9b1d17d54055 286 0x80, // bmAttributes
okini3939 0:9b1d17d54055 287 50, // bMaxPower
okini3939 0:9b1d17d54055 288
okini3939 0:9b1d17d54055 289 // Interface 0, Alternate Setting 0, Audio Control
okini3939 0:9b1d17d54055 290 INTERFACE_DESCRIPTOR_LENGTH, // bLength
okini3939 0:9b1d17d54055 291 INTERFACE_DESCRIPTOR, // bDescriptorType
okini3939 0:9b1d17d54055 292 0x00, // bInterfaceNumber
okini3939 0:9b1d17d54055 293 0x00, // bAlternateSetting
okini3939 0:9b1d17d54055 294 0x00, // bNumEndpoints
okini3939 0:9b1d17d54055 295 AUDIO_CLASS, // bInterfaceClass
okini3939 0:9b1d17d54055 296 SUBCLASS_AUDIOCONTROL, // bInterfaceSubClass
okini3939 0:9b1d17d54055 297 0x00, // bInterfaceProtocol
okini3939 0:9b1d17d54055 298 0x00, // iInterface
okini3939 0:9b1d17d54055 299
okini3939 0:9b1d17d54055 300
okini3939 0:9b1d17d54055 301 // Audio Control Interface
okini3939 0:9b1d17d54055 302 CONTROL_INTERFACE_DESCRIPTOR_LENGTH, // bLength
okini3939 0:9b1d17d54055 303 INTERFACE_DESCRIPTOR_TYPE, // bDescriptorType
okini3939 0:9b1d17d54055 304 CONTROL_HEADER, // bDescriptorSubtype
okini3939 0:9b1d17d54055 305 LSB(0x0100), // bcdADC (LSB)
okini3939 0:9b1d17d54055 306 MSB(0x0100), // bcdADC (MSB)
okini3939 0:9b1d17d54055 307 LSB(TOTAL_CONTROL_INTF_LENGTH), // wTotalLength
okini3939 0:9b1d17d54055 308 MSB(TOTAL_CONTROL_INTF_LENGTH), // wTotalLength
okini3939 0:9b1d17d54055 309 0x01, // bInCollection
okini3939 0:9b1d17d54055 310 0x01, // baInterfaceNr
okini3939 0:9b1d17d54055 311
okini3939 0:9b1d17d54055 312 // Audio Input Terminal
okini3939 0:9b1d17d54055 313 INPUT_TERMINAL_DESCRIPTOR_LENGTH, // bLength
okini3939 0:9b1d17d54055 314 INTERFACE_DESCRIPTOR_TYPE, // bDescriptorType
okini3939 0:9b1d17d54055 315 CONTROL_INPUT_TERMINAL, // bDescriptorSubtype
okini3939 0:9b1d17d54055 316 0x01, // bTerminalID
okini3939 0:9b1d17d54055 317 LSB(TERMINAL_USB_STREAMING), // wTerminalType
okini3939 0:9b1d17d54055 318 MSB(TERMINAL_USB_STREAMING), // wTerminalType
okini3939 0:9b1d17d54055 319 0x00, // bAssocTerminal
okini3939 0:9b1d17d54055 320 channel_nb, // bNrChannels
okini3939 0:9b1d17d54055 321 LSB(channel_config), // wChannelConfig
okini3939 0:9b1d17d54055 322 MSB(channel_config), // wChannelConfig
okini3939 0:9b1d17d54055 323 0x00, // iChannelNames
okini3939 0:9b1d17d54055 324 0x00, // iTerminal
okini3939 0:9b1d17d54055 325
okini3939 0:9b1d17d54055 326 // Audio Feature Unit
okini3939 0:9b1d17d54055 327 FEATURE_UNIT_DESCRIPTOR_LENGTH, // bLength
okini3939 0:9b1d17d54055 328 INTERFACE_DESCRIPTOR_TYPE, // bDescriptorType
okini3939 0:9b1d17d54055 329 CONTROL_FEATURE_UNIT, // bDescriptorSubtype
okini3939 0:9b1d17d54055 330 0x02, // bUnitID
okini3939 0:9b1d17d54055 331 0x01, // bSourceID
okini3939 0:9b1d17d54055 332 0x01, // bControlSize
okini3939 0:9b1d17d54055 333 CONTROL_MUTE |
okini3939 0:9b1d17d54055 334 CONTROL_VOLUME, // bmaControls(0)
okini3939 0:9b1d17d54055 335 0x00, // bmaControls(1)
okini3939 0:9b1d17d54055 336 0x00, // iTerminal
okini3939 0:9b1d17d54055 337
okini3939 0:9b1d17d54055 338 // Audio Output Terminal
okini3939 0:9b1d17d54055 339 OUTPUT_TERMINAL_DESCRIPTOR_LENGTH, // bLength
okini3939 0:9b1d17d54055 340 INTERFACE_DESCRIPTOR_TYPE, // bDescriptorType
okini3939 0:9b1d17d54055 341 CONTROL_OUTPUT_TERMINAL, // bDescriptorSubtype
okini3939 0:9b1d17d54055 342 0x03, // bTerminalID
okini3939 0:9b1d17d54055 343 LSB(TERMINAL_SPEAKER), // wTerminalType
okini3939 0:9b1d17d54055 344 MSB(TERMINAL_SPEAKER), // wTerminalType
okini3939 0:9b1d17d54055 345 0x00, // bAssocTerminal
okini3939 0:9b1d17d54055 346 0x02, // bSourceID
okini3939 0:9b1d17d54055 347 0x00, // iTerminal
okini3939 0:9b1d17d54055 348
okini3939 0:9b1d17d54055 349
okini3939 0:9b1d17d54055 350 // Interface 1, Alternate Setting 0, Audio Streaming - Zero Bandwith
okini3939 0:9b1d17d54055 351 INTERFACE_DESCRIPTOR_LENGTH, // bLength
okini3939 0:9b1d17d54055 352 INTERFACE_DESCRIPTOR, // bDescriptorType
okini3939 0:9b1d17d54055 353 0x01, // bInterfaceNumber
okini3939 0:9b1d17d54055 354 0x00, // bAlternateSetting
okini3939 0:9b1d17d54055 355 0x00, // bNumEndpoints
okini3939 0:9b1d17d54055 356 AUDIO_CLASS, // bInterfaceClass
okini3939 0:9b1d17d54055 357 SUBCLASS_AUDIOSTREAMING, // bInterfaceSubClass
okini3939 0:9b1d17d54055 358 0x00, // bInterfaceProtocol
okini3939 0:9b1d17d54055 359 0x00, // iInterface
okini3939 0:9b1d17d54055 360
okini3939 0:9b1d17d54055 361 // Interface 1, Alternate Setting 1, Audio Streaming - Operational
okini3939 0:9b1d17d54055 362 INTERFACE_DESCRIPTOR_LENGTH, // bLength
okini3939 0:9b1d17d54055 363 INTERFACE_DESCRIPTOR, // bDescriptorType
okini3939 0:9b1d17d54055 364 0x01, // bInterfaceNumber
okini3939 0:9b1d17d54055 365 0x01, // bAlternateSetting
okini3939 0:9b1d17d54055 366 0x01, // bNumEndpoints
okini3939 0:9b1d17d54055 367 AUDIO_CLASS, // bInterfaceClass
okini3939 0:9b1d17d54055 368 SUBCLASS_AUDIOSTREAMING, // bInterfaceSubClass
okini3939 0:9b1d17d54055 369 0x00, // bInterfaceProtocol
okini3939 0:9b1d17d54055 370 0x00, // iInterface
okini3939 0:9b1d17d54055 371
okini3939 0:9b1d17d54055 372 // Audio Streaming Interface
okini3939 0:9b1d17d54055 373 STREAMING_INTERFACE_DESCRIPTOR_LENGTH, // bLength
okini3939 0:9b1d17d54055 374 INTERFACE_DESCRIPTOR_TYPE, // bDescriptorType
okini3939 0:9b1d17d54055 375 STREAMING_GENERAL, // bDescriptorSubtype
okini3939 0:9b1d17d54055 376 0x01, // bTerminalLink
okini3939 0:9b1d17d54055 377 0x00, // bDelay
okini3939 0:9b1d17d54055 378 LSB(FORMAT_PCM), // wFormatTag
okini3939 0:9b1d17d54055 379 MSB(FORMAT_PCM), // wFormatTag
okini3939 0:9b1d17d54055 380
okini3939 0:9b1d17d54055 381 // Audio Type I Format
okini3939 0:9b1d17d54055 382 FORMAT_TYPE_I_DESCRIPTOR_LENGTH, // bLength
okini3939 0:9b1d17d54055 383 INTERFACE_DESCRIPTOR_TYPE, // bDescriptorType
okini3939 0:9b1d17d54055 384 STREAMING_FORMAT_TYPE, // bDescriptorSubtype
okini3939 0:9b1d17d54055 385 FORMAT_TYPE_I, // bFormatType
okini3939 0:9b1d17d54055 386 channel_nb, // bNrChannels
okini3939 0:9b1d17d54055 387 0x02, // bSubFrameSize
okini3939 0:9b1d17d54055 388 16, // bBitResolution
okini3939 0:9b1d17d54055 389 0x01, // bSamFreqType
okini3939 0:9b1d17d54055 390 LSB(FREQ), // tSamFreq
okini3939 0:9b1d17d54055 391 (FREQ >> 8) & 0xff, // tSamFreq
okini3939 0:9b1d17d54055 392 (FREQ >> 16) & 0xff, // tSamFreq
okini3939 0:9b1d17d54055 393
okini3939 0:9b1d17d54055 394 // Endpoint - Standard Descriptor
okini3939 0:9b1d17d54055 395 ENDPOINT_DESCRIPTOR_LENGTH + 2, // bLength
okini3939 0:9b1d17d54055 396 ENDPOINT_DESCRIPTOR, // bDescriptorType
okini3939 0:9b1d17d54055 397 PHY_TO_DESC(EPISO_OUT), // bEndpointAddress
okini3939 0:9b1d17d54055 398 E_ISOCHRONOUS, // bmAttributes
okini3939 0:9b1d17d54055 399 LSB(PACKET_SIZE_ISO), // wMaxPacketSize
okini3939 0:9b1d17d54055 400 MSB(PACKET_SIZE_ISO), // wMaxPacketSize
okini3939 0:9b1d17d54055 401 0x01, // bInterval
okini3939 0:9b1d17d54055 402 0x00, // bRefresh
okini3939 0:9b1d17d54055 403 0x00, // bSynchAddress
okini3939 0:9b1d17d54055 404
okini3939 0:9b1d17d54055 405 // Endpoint - Audio Streaming
okini3939 0:9b1d17d54055 406 STREAMING_ENDPOINT_DESCRIPTOR_LENGTH, // bLength
okini3939 0:9b1d17d54055 407 ENDPOINT_DESCRIPTOR_TYPE, // bDescriptorType
okini3939 0:9b1d17d54055 408 ENDPOINT_GENERAL, // bDescriptor
okini3939 0:9b1d17d54055 409 0x00, // bmAttributes
okini3939 0:9b1d17d54055 410 0x00, // bLockDelayUnits
okini3939 0:9b1d17d54055 411 LSB(0x0000), // wLockDelay
okini3939 0:9b1d17d54055 412 MSB(0x0000), // wLockDelay
okini3939 0:9b1d17d54055 413
okini3939 0:9b1d17d54055 414 // Terminator
okini3939 0:9b1d17d54055 415 0 // bLength
okini3939 0:9b1d17d54055 416 };
okini3939 0:9b1d17d54055 417 return configDescriptor;
okini3939 0:9b1d17d54055 418 }
okini3939 0:9b1d17d54055 419
okini3939 0:9b1d17d54055 420 uint8_t * USBAudio::stringIinterfaceDesc() {
okini3939 0:9b1d17d54055 421 static uint8_t stringIinterfaceDescriptor[] = {
okini3939 0:9b1d17d54055 422 0x0c, //bLength
okini3939 0:9b1d17d54055 423 STRING_DESCRIPTOR, //bDescriptorType 0x03
okini3939 0:9b1d17d54055 424 'A',0,'u',0,'d',0,'i',0,'o',0 //bString iInterface - Audio
okini3939 0:9b1d17d54055 425 };
okini3939 0:9b1d17d54055 426 return stringIinterfaceDescriptor;
okini3939 0:9b1d17d54055 427 }
okini3939 0:9b1d17d54055 428
okini3939 0:9b1d17d54055 429 uint8_t * USBAudio::stringIproductDesc() {
okini3939 0:9b1d17d54055 430 static uint8_t stringIproductDescriptor[] = {
okini3939 0:9b1d17d54055 431 0x16, //bLength
okini3939 0:9b1d17d54055 432 STRING_DESCRIPTOR, //bDescriptorType 0x03
okini3939 0:9b1d17d54055 433 'M',0,'b',0,'e',0,'d',0,' ',0,'A',0,'u',0,'d',0,'i',0,'o',0 //bString iProduct - Mbed Audio
okini3939 0:9b1d17d54055 434 };
okini3939 0:9b1d17d54055 435 return stringIproductDescriptor;
okini3939 0:9b1d17d54055 436 }