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.
Dependencies: ChaNFSSD mbed ChaNFS
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 11:42:56 by
1.7.2