Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
USBAudio.cpp
00001 /* Copyright (c) 2010-2011 mbed.org, MIT License 00002 * 00003 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 00004 * and associated documentation files (the "Software"), to deal in the Software without 00005 * restriction, including without limitation the rights to use, copy, modify, merge, publish, 00006 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the 00007 * Software is furnished to do so, subject to the following conditions: 00008 * 00009 * The above copyright notice and this permission notice shall be included in all copies or 00010 * substantial portions of the Software. 00011 * 00012 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 00013 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00014 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 00015 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00016 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00017 */ 00018 00019 #include "stdint.h" 00020 #include "USBAudio.h" 00021 #include "USBBusInterface.h" 00022 #include "USBAudio_Types.h" 00023 00024 00025 00026 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) { 00027 mute = 0; 00028 volCur = 0x0080; 00029 volMin = 0x0000; 00030 volMax = 0x0100; 00031 volRes = 0x0004; 00032 available = false; 00033 00034 FREQ = frequency; 00035 00036 this->channel_nb = channel_nb; 00037 00038 // stereo -> *2, mono -> *1 00039 PACKET_SIZE_ISO = (FREQ / 500) * channel_nb; 00040 00041 // STEREO -> left and right 00042 channel_config = (channel_nb == 1) ? CHANNEL_M : CHANNEL_L + CHANNEL_R; 00043 00044 SOF_handler = false; 00045 00046 buf_stream = NULL; 00047 00048 // connect the device 00049 USBDevice::connect(); 00050 } 00051 00052 bool USBAudio::read(uint8_t * buf) { 00053 buf_stream = buf; 00054 while (!available); 00055 available = false; 00056 buf_stream = NULL; 00057 return true; 00058 } 00059 00060 bool USBAudio::readNB(uint8_t * buf) { 00061 buf_stream = buf; 00062 SOF_handler = false; 00063 while (!SOF_handler); 00064 if (available) { 00065 available = false; 00066 buf_stream = NULL; 00067 return true; 00068 } 00069 buf_stream = NULL; 00070 return false; 00071 } 00072 00073 00074 float USBAudio::getVolume() { 00075 return (mute) ? 0.0 : (float)volCur/(float)volMax; 00076 } 00077 00078 00079 // Called in ISR context on each start of frame 00080 void USBAudio::SOF(int frameNumber) { 00081 uint16_t size = 0; 00082 00083 // read the isochronous endpoint 00084 if (buf_stream != NULL) { 00085 USBDevice::readEP_NB(EP3OUT, buf_stream, &size, PACKET_SIZE_ISO); 00086 } 00087 00088 // if we read something, modify the flag "available" 00089 available = (size) ? true : false; 00090 00091 // activate readings on the isochronous 00092 readStart(EP3OUT, PACKET_SIZE_ISO); 00093 00094 SOF_handler = true; 00095 } 00096 00097 00098 // Called in ISR context 00099 // Set configuration. Return false if the configuration is not supported. 00100 bool USBAudio::USBCallback_setConfiguration(uint8_t configuration) { 00101 if (configuration != DEFAULT_CONFIGURATION) { 00102 return false; 00103 } 00104 00105 // Configure isochronous endpoint 00106 realiseEndpoint(EP3OUT, PACKET_SIZE_ISO, ISOCHRONOUS); 00107 00108 // activate readings on this endpoint 00109 readStart(EP3OUT, PACKET_SIZE_ISO); 00110 return true; 00111 } 00112 00113 00114 // Called in ISR context 00115 // Set alternate setting. Return false if the alternate setting is not supported 00116 bool USBAudio::USBCallback_setInterface(uint16_t interface, uint8_t alternate) { 00117 if (interface == 0 && alternate == 0) { 00118 return true; 00119 } 00120 if (interface == 1 && (alternate == 0 || alternate == 1)) { 00121 return true; 00122 } 00123 return false; 00124 } 00125 00126 00127 00128 // Called in ISR context 00129 // Called by USBDevice on Endpoint0 request 00130 // This is used to handle extensions to standard requests and class specific requests. 00131 // Return true if class handles this request 00132 bool USBAudio::USBCallback_request() { 00133 bool success = false; 00134 CONTROL_TRANSFER * transfer = getTransferPtr(); 00135 00136 // Process class-specific requests 00137 if (transfer->setup.bmRequestType.Type == CLASS_TYPE) { 00138 00139 // Feature Unit: Interface = 0, ID = 2 00140 if (transfer->setup.wIndex == 0x0200) { 00141 00142 // Master Channel 00143 if ((transfer->setup.wValue & 0xff) == 0) { 00144 00145 switch (transfer->setup.wValue >> 8) { 00146 case MUTE_CONTROL: 00147 switch (transfer->setup.bRequest) { 00148 case REQUEST_GET_CUR: 00149 transfer->remaining = 1; 00150 transfer->ptr = &mute; 00151 transfer->direction = DEVICE_TO_HOST; 00152 success = true; 00153 break; 00154 00155 case REQUEST_SET_CUR: 00156 transfer->remaining = 1; 00157 transfer->notify = true; 00158 transfer->direction = HOST_TO_DEVICE; 00159 success = true; 00160 break; 00161 default: 00162 break; 00163 } 00164 break; 00165 case VOLUME_CONTROL: 00166 switch (transfer->setup.bRequest) { 00167 case REQUEST_GET_CUR: 00168 transfer->remaining = 2; 00169 transfer->ptr = (uint8_t *)&volCur; 00170 transfer->direction = DEVICE_TO_HOST; 00171 success = true; 00172 break; 00173 case REQUEST_GET_MIN: 00174 transfer->remaining = 2; 00175 transfer->ptr = (uint8_t *)&volMin; 00176 transfer->direction = DEVICE_TO_HOST; 00177 success = true; 00178 break; 00179 case REQUEST_GET_MAX: 00180 transfer->remaining = 2; 00181 transfer->ptr = (uint8_t *)&volMax; 00182 transfer->direction = DEVICE_TO_HOST; 00183 success = true; 00184 break; 00185 case REQUEST_GET_RES: 00186 transfer->remaining = 2; 00187 transfer->ptr = (uint8_t *)&volRes; 00188 transfer->direction = DEVICE_TO_HOST; 00189 success = true; 00190 break; 00191 00192 case REQUEST_SET_CUR: 00193 transfer->remaining = 2; 00194 transfer->notify = true; 00195 transfer->direction = HOST_TO_DEVICE; 00196 success = true; 00197 break; 00198 case REQUEST_SET_MIN: 00199 transfer->remaining = 2; 00200 transfer->notify = true; 00201 transfer->direction = HOST_TO_DEVICE; 00202 success = true; 00203 break; 00204 case REQUEST_SET_MAX: 00205 transfer->remaining = 2; 00206 transfer->notify = true; 00207 transfer->direction = HOST_TO_DEVICE; 00208 success = true; 00209 break; 00210 case REQUEST_SET_RES: 00211 transfer->remaining = 2; 00212 transfer->notify = true; 00213 transfer->direction = HOST_TO_DEVICE; 00214 success = true; 00215 break; 00216 } 00217 break; 00218 default: 00219 break; 00220 } 00221 } 00222 } 00223 } 00224 return success; 00225 } 00226 00227 00228 // Called in ISR context when a data OUT stage has been performed 00229 void USBAudio::USBCallback_requestCompleted(uint8_t * buf, uint16_t length) { 00230 uint16_t data = *((uint16_t *)buf); 00231 CONTROL_TRANSFER * transfer = getTransferPtr(); 00232 switch (transfer->setup.wValue >> 8) { 00233 case MUTE_CONTROL: 00234 switch (transfer->setup.bRequest) { 00235 case REQUEST_SET_CUR: 00236 mute = data & 0xff; 00237 updateVol.call(); 00238 break; 00239 default: 00240 break; 00241 } 00242 break; 00243 case VOLUME_CONTROL: 00244 switch (transfer->setup.bRequest) { 00245 case REQUEST_SET_CUR: 00246 volCur = data; 00247 updateVol.call(); 00248 break; 00249 default: 00250 break; 00251 } 00252 break; 00253 default: 00254 break; 00255 } 00256 } 00257 00258 00259 00260 #define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \ 00261 + (3 * INTERFACE_DESCRIPTOR_LENGTH) \ 00262 + (1 * CONTROL_INTERFACE_DESCRIPTOR_LENGTH) \ 00263 + (1 * INPUT_TERMINAL_DESCRIPTOR_LENGTH) \ 00264 + (1 * FEATURE_UNIT_DESCRIPTOR_LENGTH) \ 00265 + (1 * OUTPUT_TERMINAL_DESCRIPTOR_LENGTH) \ 00266 + (1 * STREAMING_INTERFACE_DESCRIPTOR_LENGTH) \ 00267 + (1 * FORMAT_TYPE_I_DESCRIPTOR_LENGTH) \ 00268 + (1 * (ENDPOINT_DESCRIPTOR_LENGTH + 2)) \ 00269 + (1 * STREAMING_ENDPOINT_DESCRIPTOR_LENGTH) ) 00270 00271 #define TOTAL_CONTROL_INTF_LENGTH (CONTROL_INTERFACE_DESCRIPTOR_LENGTH + \ 00272 INPUT_TERMINAL_DESCRIPTOR_LENGTH + \ 00273 FEATURE_UNIT_DESCRIPTOR_LENGTH + \ 00274 OUTPUT_TERMINAL_DESCRIPTOR_LENGTH) 00275 00276 uint8_t * USBAudio::configurationDesc() { 00277 static uint8_t configDescriptor[] = { 00278 // Configuration 1 00279 CONFIGURATION_DESCRIPTOR_LENGTH, // bLength 00280 CONFIGURATION_DESCRIPTOR, // bDescriptorType 00281 LSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (LSB) 00282 MSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (MSB) 00283 0x02, // bNumInterfaces 00284 DEFAULT_CONFIGURATION, // bConfigurationValue 00285 0x00, // iConfiguration 00286 0x80, // bmAttributes 00287 50, // bMaxPower 00288 00289 // Interface 0, Alternate Setting 0, Audio Control 00290 INTERFACE_DESCRIPTOR_LENGTH, // bLength 00291 INTERFACE_DESCRIPTOR, // bDescriptorType 00292 0x00, // bInterfaceNumber 00293 0x00, // bAlternateSetting 00294 0x00, // bNumEndpoints 00295 AUDIO_CLASS, // bInterfaceClass 00296 SUBCLASS_AUDIOCONTROL, // bInterfaceSubClass 00297 0x00, // bInterfaceProtocol 00298 0x00, // iInterface 00299 00300 00301 // Audio Control Interface 00302 CONTROL_INTERFACE_DESCRIPTOR_LENGTH, // bLength 00303 INTERFACE_DESCRIPTOR_TYPE, // bDescriptorType 00304 CONTROL_HEADER, // bDescriptorSubtype 00305 LSB(0x0100), // bcdADC (LSB) 00306 MSB(0x0100), // bcdADC (MSB) 00307 LSB(TOTAL_CONTROL_INTF_LENGTH), // wTotalLength 00308 MSB(TOTAL_CONTROL_INTF_LENGTH), // wTotalLength 00309 0x01, // bInCollection 00310 0x01, // baInterfaceNr 00311 00312 // Audio Input Terminal 00313 INPUT_TERMINAL_DESCRIPTOR_LENGTH, // bLength 00314 INTERFACE_DESCRIPTOR_TYPE, // bDescriptorType 00315 CONTROL_INPUT_TERMINAL, // bDescriptorSubtype 00316 0x01, // bTerminalID 00317 LSB(TERMINAL_USB_STREAMING), // wTerminalType 00318 MSB(TERMINAL_USB_STREAMING), // wTerminalType 00319 0x00, // bAssocTerminal 00320 channel_nb, // bNrChannels 00321 LSB(channel_config), // wChannelConfig 00322 MSB(channel_config), // wChannelConfig 00323 0x00, // iChannelNames 00324 0x00, // iTerminal 00325 00326 // Audio Feature Unit 00327 FEATURE_UNIT_DESCRIPTOR_LENGTH, // bLength 00328 INTERFACE_DESCRIPTOR_TYPE, // bDescriptorType 00329 CONTROL_FEATURE_UNIT, // bDescriptorSubtype 00330 0x02, // bUnitID 00331 0x01, // bSourceID 00332 0x01, // bControlSize 00333 CONTROL_MUTE | 00334 CONTROL_VOLUME, // bmaControls(0) 00335 0x00, // bmaControls(1) 00336 0x00, // iTerminal 00337 00338 // Audio Output Terminal 00339 OUTPUT_TERMINAL_DESCRIPTOR_LENGTH, // bLength 00340 INTERFACE_DESCRIPTOR_TYPE, // bDescriptorType 00341 CONTROL_OUTPUT_TERMINAL, // bDescriptorSubtype 00342 0x03, // bTerminalID 00343 LSB(TERMINAL_SPEAKER), // wTerminalType 00344 MSB(TERMINAL_SPEAKER), // wTerminalType 00345 0x00, // bAssocTerminal 00346 0x02, // bSourceID 00347 0x00, // iTerminal 00348 00349 00350 // Interface 1, Alternate Setting 0, Audio Streaming - Zero Bandwith 00351 INTERFACE_DESCRIPTOR_LENGTH, // bLength 00352 INTERFACE_DESCRIPTOR, // bDescriptorType 00353 0x01, // bInterfaceNumber 00354 0x00, // bAlternateSetting 00355 0x00, // bNumEndpoints 00356 AUDIO_CLASS, // bInterfaceClass 00357 SUBCLASS_AUDIOSTREAMING, // bInterfaceSubClass 00358 0x00, // bInterfaceProtocol 00359 0x00, // iInterface 00360 00361 // Interface 1, Alternate Setting 1, Audio Streaming - Operational 00362 INTERFACE_DESCRIPTOR_LENGTH, // bLength 00363 INTERFACE_DESCRIPTOR, // bDescriptorType 00364 0x01, // bInterfaceNumber 00365 0x01, // bAlternateSetting 00366 0x01, // bNumEndpoints 00367 AUDIO_CLASS, // bInterfaceClass 00368 SUBCLASS_AUDIOSTREAMING, // bInterfaceSubClass 00369 0x00, // bInterfaceProtocol 00370 0x00, // iInterface 00371 00372 // Audio Streaming Interface 00373 STREAMING_INTERFACE_DESCRIPTOR_LENGTH, // bLength 00374 INTERFACE_DESCRIPTOR_TYPE, // bDescriptorType 00375 STREAMING_GENERAL, // bDescriptorSubtype 00376 0x01, // bTerminalLink 00377 0x00, // bDelay 00378 LSB(FORMAT_PCM), // wFormatTag 00379 MSB(FORMAT_PCM), // wFormatTag 00380 00381 // Audio Type I Format 00382 FORMAT_TYPE_I_DESCRIPTOR_LENGTH, // bLength 00383 INTERFACE_DESCRIPTOR_TYPE, // bDescriptorType 00384 STREAMING_FORMAT_TYPE, // bDescriptorSubtype 00385 FORMAT_TYPE_I, // bFormatType 00386 channel_nb, // bNrChannels 00387 0x02, // bSubFrameSize 00388 16, // bBitResolution 00389 0x01, // bSamFreqType 00390 LSB(FREQ), // tSamFreq 00391 (FREQ >> 8) & 0xff, // tSamFreq 00392 (FREQ >> 16) & 0xff, // tSamFreq 00393 00394 // Endpoint - Standard Descriptor 00395 ENDPOINT_DESCRIPTOR_LENGTH + 2, // bLength 00396 ENDPOINT_DESCRIPTOR, // bDescriptorType 00397 PHY_TO_DESC(EPISO_OUT), // bEndpointAddress 00398 E_ISOCHRONOUS, // bmAttributes 00399 LSB(PACKET_SIZE_ISO), // wMaxPacketSize 00400 MSB(PACKET_SIZE_ISO), // wMaxPacketSize 00401 0x01, // bInterval 00402 0x00, // bRefresh 00403 0x00, // bSynchAddress 00404 00405 // Endpoint - Audio Streaming 00406 STREAMING_ENDPOINT_DESCRIPTOR_LENGTH, // bLength 00407 ENDPOINT_DESCRIPTOR_TYPE, // bDescriptorType 00408 ENDPOINT_GENERAL, // bDescriptor 00409 0x00, // bmAttributes 00410 0x00, // bLockDelayUnits 00411 LSB(0x0000), // wLockDelay 00412 MSB(0x0000), // wLockDelay 00413 00414 // Terminator 00415 0 // bLength 00416 }; 00417 return configDescriptor; 00418 } 00419 00420 uint8_t * USBAudio::stringIinterfaceDesc() { 00421 static uint8_t stringIinterfaceDescriptor[] = { 00422 0x0c, //bLength 00423 STRING_DESCRIPTOR, //bDescriptorType 0x03 00424 'A',0,'u',0,'d',0,'i',0,'o',0 //bString iInterface - Audio 00425 }; 00426 return stringIinterfaceDescriptor; 00427 } 00428 00429 uint8_t * USBAudio::stringIproductDesc() { 00430 static uint8_t stringIproductDescriptor[] = { 00431 0x16, //bLength 00432 STRING_DESCRIPTOR, //bDescriptorType 0x03 00433 'M',0,'b',0,'e',0,'d',0,' ',0,'A',0,'u',0,'d',0,'i',0,'o',0 //bString iProduct - Mbed Audio 00434 }; 00435 return stringIproductDescriptor; 00436 }
Generated on Wed Jul 13 2022 10:21:28 by
1.7.2