USBAudio example using a microphone

Dependencies:   USBDevice mbed

USBDevice/USBAudio/USBAudio.cpp

Committer:
samux
Date:
2011-12-19
Revision:
3:e6a29c83ac52
Parent:
2:7d8bdeb3753b
Child:
5:b49b6a8ca111

File content as of revision 3:e6a29c83ac52:

/* Copyright (c) 2010-2011 mbed.org, MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#include "stdint.h"
#include "USBAudio.h"
#include "USBBusInterface.h"
#include "USBAudio_Types.h"



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) {

    FREQ = frequency;

    this->channel_nb = channel_nb;

    // stereo -> *2, mono -> *1
    PACKET_SIZE_ISO = (FREQ / 500) * channel_nb;

    // STEREO -> left and right
    channel_config = (channel_nb == 1) ? CHANNEL_M : CHANNEL_L + CHANNEL_R;

    SOF_handler = false;
    readIN = false;
    interruptIN = false;

    buf_stream = NULL;

    // connect the device
    USBDevice::connect();
}

bool USBAudio::write(uint8_t * buf) {
    readIN = false;
    SOF_handler = false;
    if (interruptIN) {
        USBDevice::writeNB(EP3IN, buf, 16, 16);
    } else {
        buf_stream = buf;
    }
    while (!SOF_handler);
    if (interruptIN) {
        while (!readIN);
    }
    buf_stream = NULL;
    return true;
}

// Called in ISR context on each start of frame
void USBAudio::SOF(int frameNumber) {
    if (buf_stream != NULL) {
        USBDevice::writeNB(EP3IN, (uint8_t *)buf_stream, 16, 16);
    }
    SOF_handler = true;
}


bool USBAudio::EP3_IN_callback() {
    interruptIN = true;
    readIN = true;
    return true;
}


// Called in ISR context
// Set configuration. Return false if the configuration is not supported.
bool USBAudio::USBCallback_setConfiguration(uint8_t configuration) {
    if (configuration != DEFAULT_CONFIGURATION) {
        return false;
    }

    // Configure isochronous endpoint
    realiseEndpoint(EP3IN, PACKET_SIZE_ISO, ISOCHRONOUS);
    return true;
}


// Called in ISR context
// Set alternate setting. Return false if the alternate setting is not supported
bool USBAudio::USBCallback_setInterface(uint16_t interface, uint8_t alternate) {
    if (interface == 0 && alternate == 0) {
        return true;
    }
    if (interface == 1 && (alternate == 0 || alternate == 1)) {
        return true;
    } else
        printf("intf: %d, alt: %d\r\n", interface, alternate);
    return false;
}



#define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \
                               + (5 * INTERFACE_DESCRIPTOR_LENGTH) \
                               + (1 * CONTROL_INTERFACE_DESCRIPTOR_LENGTH) \
                               + (2 * INPUT_TERMINAL_DESCRIPTOR_LENGTH) \
                               + (2 * FEATURE_UNIT_DESCRIPTOR_LENGTH) \
                               + (2 * OUTPUT_TERMINAL_DESCRIPTOR_LENGTH) \
                               + (0x07) \
                               + (2 * STREAMING_INTERFACE_DESCRIPTOR_LENGTH) \
                               + (2 * FORMAT_TYPE_I_DESCRIPTOR_LENGTH) \
                               + (2 * (ENDPOINT_DESCRIPTOR_LENGTH + 2)) \
                               + (2 * STREAMING_ENDPOINT_DESCRIPTOR_LENGTH) )

#define TOTAL_CONTROL_INTF_LENGTH    (CONTROL_INTERFACE_DESCRIPTOR_LENGTH + \
                                      2 * INPUT_TERMINAL_DESCRIPTOR_LENGTH     + \
                                      2 * FEATURE_UNIT_DESCRIPTOR_LENGTH    + \
                                      2 * OUTPUT_TERMINAL_DESCRIPTOR_LENGTH + \
                                      0x07)

uint8_t * USBAudio::configurationDesc() {
    static uint8_t configDescriptor[] = {
        // Configuration 1
        CONFIGURATION_DESCRIPTOR_LENGTH,    // bLength
        CONFIGURATION_DESCRIPTOR,           // bDescriptorType
        0x64,   // wTotalLength (LSB)
        0x00,   // wTotalLength (MSB)
        0x02,   // bNumInterfaces
        DEFAULT_CONFIGURATION,  // bConfigurationValue
        0x00,   // iConfiguration
        0x80,   // bmAttributes
        50,     // bMaxPower

        // Interface 0, Alternate Setting 0, Audio Control
        INTERFACE_DESCRIPTOR_LENGTH,    // bLength
        INTERFACE_DESCRIPTOR,           // bDescriptorType
        0x00,   // bInterfaceNumber
        0x00,   // bAlternateSetting
        0x00,   // bNumEndpoints
        0x01,   // bInterfaceClass
        0x01,   // bInterfaceSubClass
        0x00,   // bInterfaceProtocol
        0x00,   // iInterface


        // Audio Control Interface
        0x09,   // bLength
        0x24,   // bDescriptorType
        0x01,   // bDescriptorSubtype
        LSB(0x0100),    // bcdADC (LSB)
        MSB(0x0100),    // bcdADC (MSB)
        0x1e,   // wTotalLength
        0x00,   // wTotalLength
        0x01,   // bInCollection
        0x01,   // baInterfaceNr

        // Audio Input Terminal (Speaker)
        0x0c,   // bLength
        0x24,   // bDescriptorType
        0x02,   // bDescriptorSubtype
        0x01,   // bTerminalID
        0x01,   // wTerminalType
        0x02,   // wTerminalType
        0x00,   // bAssocTerminal
        0x01,   // bNrChannels
        0x00,   // wChannelConfig
        0x00,   // wChannelConfig
        0x00,   // iChannelNames
        0x00,   // iTerminal

        // Audio Output Terminal (Speaker)
        0x09,   // bLength
        0x24,   // bDescriptorType
        0x03,   // bDescriptorSubtype
        0x02,   // bTerminalID
        0x01,   // wTerminalType
        0x01,   // wTerminalType
        0x00,   // bAssocTerminal
        0x01,   // bSourceID
        0x00,   // iTerminal








        // Interface 1, Alternate Setting 0, Audio Streaming - Zero Bandwith
        0x09,   // bLength
        0x04,   // bDescriptorType
        0x01,   // bInterfaceNumber
        0x00,   // bAlternateSetting
        0x00,   // bNumEndpoints
        0x01,   // bInterfaceClass
        0x02,   // bInterfaceSubClass
        0x00,   // bInterfaceProtocol
        0x00,   // iInterface

        // Interface 1, Alternate Setting 1, Audio Streaming - Operational
        0x09,   // bLength
        0x04,   // bDescriptorType
        0x01,   // bInterfaceNumber
        0x01,   // bAlternateSetting
        0x01,   // bNumEndpoints
        0x01,   // bInterfaceClass
        0x02,   // bInterfaceSubClass
        0x00,   // bInterfaceProtocol
        0x00,   // iInterface

        // Audio Streaming Interface
        0x07,   // bLength
        0x24,   // bDescriptorType
        0x01,   // bDescriptorSubtype
        0x02,   // bTerminalLink
        0x01,   // bDelay
        0x01,   // wFormatTag
        0x00,   // wFormatTag

        // Audio Type I Format
        0x0B,   // bLength
        0x24,   // bDescriptorType
        0x02,   // bDescriptorSubtype
        0x01,   // bFormatType
        0x01,   // bNrChannels
        0x02,   // bSubFrameSize
        0x10,   // bBitResolution
        0x01,   // bSamFreqType
        0x40,   // tSamFreq
        0x1F,   // tSamFreq
        0x00,   // tSamFreq

        // Endpoint - Standard Descriptor
        0x09,   // bLength
        0x05,   // bDescriptorType
        PHY_TO_DESC(EPISO_IN),  // bEndpointAddress
        E_ISOCHRONOUS,          // bmAttributes
        LSB(PACKET_SIZE_ISO),   // wMaxPacketSize
        MSB(PACKET_SIZE_ISO),   // wMaxPacketSize
        0x01,   // bInterval
        0x00,   // bRefresh
        0x00,   // bSynchAddress

        // Endpoint - Audio Streaming
        0x07,   // bLength
        0x25,   // bDescriptorType
        0x01,   // bDescriptor
        0x00,   // bmAttributes
        0x00,   // bLockDelayUnits
        LSB(0x0000),    // wLockDelay
        MSB(0x0000),    // wLockDelay




        // Terminator
        0
    };
    //printf("size config: %d\r\n", sizeof(configDescriptor));
    return configDescriptor;
}

uint8_t * USBAudio::stringIinterfaceDesc() {
    static uint8_t stringIinterfaceDescriptor[] = {
        0x0c,                           //bLength
        STRING_DESCRIPTOR,              //bDescriptorType 0x03
        'A',0,'u',0,'d',0,'i',0,'o',0   //bString iInterface - Audio
    };
    return stringIinterfaceDescriptor;
}

uint8_t * USBAudio::stringIproductDesc() {
    static uint8_t stringIproductDescriptor[] = {
        0x16,                                                       //bLength
        STRING_DESCRIPTOR,                                          //bDescriptorType 0x03
        'M',0,'b',0,'e',0,'d',0,' ',0,'A',0,'u',0,'d',0,'i',0,'o',0 //bString iProduct - Mbed Audio
    };
    return stringIproductDescriptor;
}