Suga koubou / Mbed 2 deprecated USB_CDC_MSD_Hello

Dependencies:   ChaNFSSD mbed ChaNFS

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers USBAudio.cpp Source File

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 }