USBAudio example using a microphone

Dependencies:   USBDevice mbed

Files at this revision

API Documentation at this revision

Comitter:
samux
Date:
Tue Dec 20 11:41:31 2011 +0000
Parent:
6:be128039be16
Child:
8:caede7b4c444
Commit message:
create USBAudioOUT class. all is working

Changed in this revision

USBDevice/USBAudio/USBAudio.cpp Show diff for this revision Revisions of this file
USBDevice/USBAudio/USBAudio.h Show diff for this revision Revisions of this file
USBDevice/USBAudio/USBAudio_Types.h Show diff for this revision Revisions of this file
USBDevice/USBAudioOUT/USBAudioOUT.cpp Show annotated file Show diff for this revision Revisions of this file
USBDevice/USBAudioOUT/USBAudioOUT.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/USBDevice/USBAudio/USBAudio.cpp	Tue Dec 20 11:17:33 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,277 +0,0 @@
-/* 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;
-    writeIN = false;
-    interruptIN = false;
-
-    buf_stream = NULL;
-
-    // connect the device
-    USBDevice::connect();
-}
-
-bool USBAudio::write(uint8_t * buf) {
-    writeIN = false;
-    SOF_handler = false;
-    if (interruptIN) {
-        USBDevice::writeNB(EP3IN, buf, PACKET_SIZE_ISO, PACKET_SIZE_ISO);
-    } else {
-        buf_stream = buf;
-    }
-    while (!SOF_handler);
-    if (interruptIN) {
-        while (!writeIN);
-    }
-    buf_stream = NULL;
-    return true;
-}
-
-DigitalOut p1(p18);
-// 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, PACKET_SIZE_ISO, PACKET_SIZE_ISO);
-    }
-    SOF_handler = true;
-}
-
-
-bool USBAudio::EP3_IN_callback() {
-    interruptIN = true;
-    writeIN = 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;
-    }
-    return false;
-}
-
-
-
-#define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \
-                               + (3 * INTERFACE_DESCRIPTOR_LENGTH) \
-                               + (1 * CONTROL_INTERFACE_DESCRIPTOR_LENGTH) \
-                               + (1 * INPUT_TERMINAL_DESCRIPTOR_LENGTH) \
-                               + (1 * OUTPUT_TERMINAL_DESCRIPTOR_LENGTH) \
-                               + (1 * STREAMING_INTERFACE_DESCRIPTOR_LENGTH) \
-                               + (1 * FORMAT_TYPE_I_DESCRIPTOR_LENGTH) \
-                               + (1 * (ENDPOINT_DESCRIPTOR_LENGTH + 2)) \
-                               + (1 * STREAMING_ENDPOINT_DESCRIPTOR_LENGTH) )
-
-#define TOTAL_CONTROL_INTF_LENGTH    (CONTROL_INTERFACE_DESCRIPTOR_LENGTH + \
-                                      1 * INPUT_TERMINAL_DESCRIPTOR_LENGTH     + \
-                                      1 * OUTPUT_TERMINAL_DESCRIPTOR_LENGTH)
-
-uint8_t * USBAudio::configurationDesc() {
-    static uint8_t configDescriptor[] = {
-        // Configuration 1
-        CONFIGURATION_DESCRIPTOR_LENGTH,        // bLength
-        CONFIGURATION_DESCRIPTOR,               // bDescriptorType
-        LSB(TOTAL_DESCRIPTOR_LENGTH),           // wTotalLength (LSB)
-        MSB(TOTAL_DESCRIPTOR_LENGTH),           // 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
-        AUDIO_CLASS,                            // bInterfaceClass
-        SUBCLASS_AUDIOCONTROL,                  // bInterfaceSubClass
-        0x00,                                   // bInterfaceProtocol
-        0x00,                                   // iInterface
-
-
-        // Audio Control Interface
-        CONTROL_INTERFACE_DESCRIPTOR_LENGTH,    // bLength
-        INTERFACE_DESCRIPTOR_TYPE,              // bDescriptorType
-        CONTROL_HEADER,                         // bDescriptorSubtype
-        LSB(0x0100),                            // bcdADC (LSB)
-        MSB(0x0100),                            // bcdADC (MSB)
-        LSB(TOTAL_CONTROL_INTF_LENGTH),         // wTotalLength
-        MSB(TOTAL_CONTROL_INTF_LENGTH),         // wTotalLength
-        0x01,                                   // bInCollection
-        0x01,                                   // baInterfaceNr
-
-        // Audio Input Terminal (Microphone)
-        INPUT_TERMINAL_DESCRIPTOR_LENGTH,       // bLength
-        INTERFACE_DESCRIPTOR_TYPE,              // bDescriptorType
-        CONTROL_INPUT_TERMINAL,                 // bDescriptorSubtype
-        0x01,                                   // bTerminalID
-        LSB(TERMINAL_MICROPHONE),               // wTerminalType
-        MSB(TERMINAL_MICROPHONE),               // wTerminalType
-        0x00,                                   // bAssocTerminal
-        channel_nb,                             // bNrChannels
-        LSB(channel_config),                    // wChannelConfig
-        MSB(channel_config),                    // wChannelConfig
-        0x00,                                   // iChannelNames
-        0x00,                                   // iTerminal
-
-        // Audio Output Terminal (Speaker)
-        OUTPUT_TERMINAL_DESCRIPTOR_LENGTH,      // bLength
-        INTERFACE_DESCRIPTOR_TYPE,              // bDescriptorType
-        CONTROL_OUTPUT_TERMINAL,                // bDescriptorSubtype
-        0x02,                                   // bTerminalID
-        LSB(TERMINAL_USB_STREAMING),            // wTerminalType
-        MSB(TERMINAL_USB_STREAMING),            // wTerminalType
-        0x00,                                   // bAssocTerminal
-        0x01,                                   // bSourceID
-        0x00,                                   // iTerminal
-
-
-
-
-
-
-
-
-        // Interface 1, Alternate Setting 0, Audio Streaming - Zero Bandwith
-        INTERFACE_DESCRIPTOR_LENGTH,            // bLength
-        INTERFACE_DESCRIPTOR,                   // bDescriptorType
-        0x01,                                   // bInterfaceNumber
-        0x00,                                   // bAlternateSetting
-        0x00,                                   // bNumEndpoints
-        AUDIO_CLASS,                            // bInterfaceClass
-        SUBCLASS_AUDIOSTREAMING,                // bInterfaceSubClass
-        0x00,                                   // bInterfaceProtocol
-        0x00,                                   // iInterface
-
-        // Interface 1, Alternate Setting 1, Audio Streaming - Operational
-        INTERFACE_DESCRIPTOR_LENGTH,            // bLength
-        INTERFACE_DESCRIPTOR,                   // bDescriptorType
-        0x01,                                   // bInterfaceNumber
-        0x01,                                   // bAlternateSetting
-        0x01,                                   // bNumEndpoints
-        AUDIO_CLASS,                            // bInterfaceClass
-        SUBCLASS_AUDIOSTREAMING,                // bInterfaceSubClass
-        0x00,                                   // bInterfaceProtocol
-        0x00,                                   // iInterface
-
-        // Audio Streaming Interface
-        STREAMING_INTERFACE_DESCRIPTOR_LENGTH,  // bLength
-        INTERFACE_DESCRIPTOR_TYPE,              // bDescriptorType
-        SUBCLASS_AUDIOCONTROL,                  // bDescriptorSubtype
-        0x02,                                   // bTerminalLink (output terminal microphone)
-        0x01,                                   // bDelay
-        0x01,                                   // wFormatTag
-        0x00,                                   // wFormatTag
-
-        // Audio Type I Format
-        FORMAT_TYPE_I_DESCRIPTOR_LENGTH,        // bLength
-        INTERFACE_DESCRIPTOR_TYPE,              // bDescriptorType
-        SUBCLASS_AUDIOSTREAMING,                // bDescriptorSubtype
-        FORMAT_TYPE_I,                          // bFormatType
-        channel_nb,                             // bNrChannels
-        0x02,                                   // bSubFrameSize
-        0x10,                                   // bBitResolution
-        0x01,                                   // bSamFreqType
-        LSB(FREQ),                              // tSamFreq
-        (FREQ >> 8) & 0xff,                     // tSamFreq
-        (FREQ >> 16) & 0xff,                    // tSamFreq
-
-        // Endpoint - Standard Descriptor
-        ENDPOINT_DESCRIPTOR_LENGTH + 2,         // bLength
-        ENDPOINT_DESCRIPTOR,                    // 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
-        STREAMING_ENDPOINT_DESCRIPTOR_LENGTH,   // bLength
-        ENDPOINT_DESCRIPTOR_TYPE,               // bDescriptorType
-        ENDPOINT_GENERAL,                       // bDescriptor
-        0x00,                                   // bmAttributes
-        0x00,                                   // bLockDelayUnits
-        LSB(0x0000),                            // wLockDelay
-        MSB(0x0000),                            // wLockDelay
-
-
-        // Terminator
-        0
-    };
-    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;
-}
\ No newline at end of file
--- a/USBDevice/USBAudio/USBAudio.h	Tue Dec 20 11:17:33 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,190 +0,0 @@
-/* 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.
-*/
-
-#ifndef USBAudio_H
-#define USBAudio_H
-
-/* These headers are included for child class. */
-#include "USBEndpoints.h"
-#include "USBDescriptor.h"
-#include "USBDevice_Types.h"
-
-#include "USBDevice.h"
-
-
-/**
-* USBAudio example
-*
-* #include "mbed.h"
-* #include "USBAudio.h"
-*
-* Serial pc(USBTX, USBRX);
-*
-* // frequency: 48 kHz
-* #define FREQ 48000
-*
-* // 1 channel: mono
-* #define NB_CHA 1
-*
-* // length of an audio packet: each ms, we receive 48 * 16bits ->48 * 2 bytes. as there is one channel, the length will be 48 * 2 * 1
-* #define AUDIO_LENGTH_PACKET 48 * 2 * 1
-*
-* // USBAudio
-* USBAudio audio(FREQ, NB_CHA);
-*
-* int main() {
-*    int16_t buf[AUDIO_LENGTH_PACKET/2];
-*    
-*    while (1) {
-*        // read an audio packet
-*        audio.read((uint8_t *)buf);
-*
-*
-*        // print packet received
-*        pc.printf("recv: ");
-*        for(int i = 0; i < AUDIO_LENGTH_PACKET/2; i++) {
-*            pc.printf("%d ", buf[i]);
-*        }
-*        pc.printf("\r\n");
-*    }
-* }
-* @endcode
-*/
-class USBAudio: public USBDevice {
-public:
-
-    /**
-    * Constructor
-    *
-    * @param frequency frequency in Hz (default: 48000)
-    * @param channel_nb channel number (1 or 2) (default: 1)
-    * @param vendor_id Your vendor_id
-    * @param product_id Your product_id
-    * @param product_release Your preoduct_release
-    */
-    USBAudio(uint32_t frequency = 48000, uint8_t channel_nb = 1, uint16_t vendor_id = 0x7bb8, uint16_t product_id = 0x1111, uint16_t product_release = 0x0100);
-    
-    
-    /**
-    * Write an audio packet
-    *
-    * @param buf audio packet
-    * @returns true if successful
-    */
-    bool write(uint8_t * buf);
-
-
-protected:
-
-    /*
-    * Called by USBDevice layer. Set configuration of the device.
-    * For instance, you can add all endpoints that you need on this function.
-    *
-    * @param configuration Number of the configuration
-    * @returns true if class handles this request
-    */
-    virtual bool USBCallback_setConfiguration(uint8_t configuration);
-
-    /*
-    * Get string product descriptor
-    *
-    * @returns pointer to the string product descriptor
-    */
-    virtual uint8_t * stringIproductDesc();
-
-    /*
-    * Get string interface descriptor
-    *
-    * @returns pointer to the string interface descriptor
-    */
-    virtual uint8_t * stringIinterfaceDesc();
-
-    /*
-    * Get configuration descriptor
-    *
-    * @returns pointer to the configuration descriptor
-    */
-    virtual uint8_t * configurationDesc();
-
-    /*
-     * Called by USBDevice layer. Set interface/alternate of the device.
-     *
-     * @param interface Number of the interface to be configured
-     * @param alternate Number of the alternate to be configured
-     * @returns true if class handles this request
-     */
-    virtual bool USBCallback_setInterface(uint16_t interface, uint8_t alternate);
-
-
-    /*
-    * Callback called on each Start of Frame event
-    */
-    virtual void SOF(int frameNumber);
-    
-    /*
-    * Callback called when a packet has been sent
-    */
-    virtual bool EP3_IN_callback();
-
-private:
-
-    // stream available ?
-    volatile bool available;
-
-    // FREQ
-    uint32_t FREQ;
-
-    // size of the maximum packet for the isochronous endpoint
-    uint32_t PACKET_SIZE_ISO;
-
-    // mono, stereo,...
-    uint8_t channel_nb;
-    
-    // channel config: master, left, right
-    uint8_t channel_config;
-
-    // mute state
-    uint8_t mute;
-
-    // Volume Current Value
-    uint16_t volCur;
-
-    // Volume Minimum Value
-    uint16_t volMin;
-
-    // Volume Maximum Value
-    uint16_t volMax;
-
-    // Volume Resolution
-    uint16_t volRes;
-
-    // Buffer containing one audio packet
-    uint8_t * buf_stream;
-    
-    // callback to update volume
-    FunctionPointer updateVol;
-    
-    // boolean showing that the SOF handler has been called. Useful for readNB.
-    volatile bool SOF_handler;
-    
-    volatile bool interruptIN;
-    volatile bool writeIN;
-
-};
-
-#endif
--- a/USBDevice/USBAudio/USBAudio_Types.h	Tue Dec 20 11:17:33 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,99 +0,0 @@
-/* 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.
-*/
-
-#ifndef USBAUDIO_TYPES_H
-#define USBAUDIO_TYPES_H
-
-
-#define DEFAULT_CONFIGURATION (1)
-
-// Audio Request Codes
-#define REQUEST_SET_CUR     0x01
-#define REQUEST_GET_CUR     0x81
-#define REQUEST_SET_MIN     0x02
-#define REQUEST_GET_MIN     0x82
-#define REQUEST_SET_MAX     0x03
-#define REQUEST_GET_MAX     0x83
-#define REQUEST_SET_RES     0x04
-#define REQUEST_GET_RES     0x84
-
-#define MUTE_CONTROL        0x01
-#define VOLUME_CONTROL      0x02
-
-
-// Audio Descriptor Sizes
-#define CONTROL_INTERFACE_DESCRIPTOR_LENGTH       0x09
-#define STREAMING_INTERFACE_DESCRIPTOR_LENGTH     0x07
-#define INPUT_TERMINAL_DESCRIPTOR_LENGTH          0x0C
-#define OUTPUT_TERMINAL_DESCRIPTOR_LENGTH         0x09
-#define FEATURE_UNIT_DESCRIPTOR_LENGTH            0x09
-#define STREAMING_ENDPOINT_DESCRIPTOR_LENGTH      0x07
-
-// Audio Format Type Descriptor Sizes
-#define FORMAT_TYPE_I_DESCRIPTOR_LENGTH   0x0b
-
-#define AUDIO_CLASS                       0x01
-#define SUBCLASS_AUDIOCONTROL             0x01
-#define SUBCLASS_AUDIOSTREAMING           0x02
-
-// Audio Descriptor Types
-#define INTERFACE_DESCRIPTOR_TYPE         0x24
-#define ENDPOINT_DESCRIPTOR_TYPE          0x25
-
-// Audio Control Interface Descriptor Subtypes
-#define CONTROL_HEADER                    0x01
-#define CONTROL_INPUT_TERMINAL            0x02
-#define CONTROL_OUTPUT_TERMINAL           0x03
-#define CONTROL_SELECTOR_UNIT             0x05
-#define CONTROL_FEATURE_UNIT              0x06
-
-// USB Terminal Types
-#define TERMINAL_USB_STREAMING            0x0101
-
-// Predefined Audio Channel Configuration Bits
-// Mono
-#define CHANNEL_M                         0x0000
-#define CHANNEL_L                         0x0001  /* Left Front */
-#define CHANNEL_R                         0x0002  /* Right Front */
-
-// Feature Unit Control Bits
-#define CONTROL_MUTE                      0x0001
-#define CONTROL_VOLUME                    0x0002
-
-
-/*  Input Terminal Types */
-#define TERMINAL_MICROPHONE               0x0201
-
-// Output Terminal Types
-#define TERMINAL_SPEAKER                  0x0301
-#define TERMINAL_HEADPHONES               0x0302
-
-// Audio Streaming Interface Descriptor Subtypes
-#define STREAMING_GENERAL                 0x01
-#define STREAMING_FORMAT_TYPE             0x02
-
-// Audio Data Format Type I Codes
-#define FORMAT_PCM                        0x0001
-
-// Audio Format Types
-#define FORMAT_TYPE_I                     0x01
-
-// Audio Endpoint Descriptor Subtypes
-#define ENDPOINT_GENERAL                  0x01
-
-#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBAudioOUT/USBAudioOUT.cpp	Tue Dec 20 11:41:31 2011 +0000
@@ -0,0 +1,272 @@
+/* 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 "USBAudioOUT.h"
+#include "USBBusInterface.h"
+#include "USBAudio_Types.h"
+
+
+USBAudioOUT::USBAudioOUT(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;
+    writeIN = false;
+    interruptIN = false;
+
+    buf_stream = NULL;
+
+    // connect the device
+    USBDevice::connect();
+}
+
+bool USBAudioOUT::write(uint8_t * buf) {
+    writeIN = false;
+    SOF_handler = false;
+    if (interruptIN) {
+        USBDevice::writeNB(EP3IN, buf, PACKET_SIZE_ISO, PACKET_SIZE_ISO);
+    } else {
+        buf_stream = buf;
+    }
+    while (!SOF_handler);
+    if (interruptIN) {
+        while (!writeIN);
+    }
+    buf_stream = NULL;
+    return true;
+}
+
+
+// Called in ISR context on each start of frame
+void USBAudioOUT::SOF(int frameNumber) {
+    if (buf_stream != NULL) {
+        USBDevice::writeNB(EP3IN, (uint8_t *)buf_stream, PACKET_SIZE_ISO, PACKET_SIZE_ISO);
+    }
+    SOF_handler = true;
+}
+
+
+
+bool USBAudioOUT::EP3_IN_callback() {
+    interruptIN = true;
+    writeIN = true;
+    return true;
+}
+
+
+// Called in ISR context
+// Set configuration. Return false if the configuration is not supported.
+bool USBAudioOUT::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 USBAudioOUT::USBCallback_setInterface(uint16_t interface, uint8_t alternate) {
+    if (interface == 0 && alternate == 0) {
+        return true;
+    }
+    if (interface == 1 && (alternate == 0 || alternate == 1)) {
+        return true;
+    }
+    return false;
+}
+
+
+
+#define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \
+                               + (3 * INTERFACE_DESCRIPTOR_LENGTH) \
+                               + (1 * CONTROL_INTERFACE_DESCRIPTOR_LENGTH) \
+                               + (1 * INPUT_TERMINAL_DESCRIPTOR_LENGTH) \
+                               + (1 * OUTPUT_TERMINAL_DESCRIPTOR_LENGTH) \
+                               + (1 * STREAMING_INTERFACE_DESCRIPTOR_LENGTH) \
+                               + (1 * FORMAT_TYPE_I_DESCRIPTOR_LENGTH) \
+                               + (1 * (ENDPOINT_DESCRIPTOR_LENGTH + 2)) \
+                               + (1 * STREAMING_ENDPOINT_DESCRIPTOR_LENGTH) )
+
+#define TOTAL_CONTROL_INTF_LENGTH    (CONTROL_INTERFACE_DESCRIPTOR_LENGTH + \
+                                      1 * INPUT_TERMINAL_DESCRIPTOR_LENGTH     + \
+                                      1 * OUTPUT_TERMINAL_DESCRIPTOR_LENGTH)
+
+uint8_t * USBAudioOUT::configurationDesc() {
+    static uint8_t configDescriptor[] = {
+        // Configuration 1
+        CONFIGURATION_DESCRIPTOR_LENGTH,        // bLength
+        CONFIGURATION_DESCRIPTOR,               // bDescriptorType
+        LSB(TOTAL_DESCRIPTOR_LENGTH),           // wTotalLength (LSB)
+        MSB(TOTAL_DESCRIPTOR_LENGTH),           // 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
+        AUDIO_CLASS,                            // bInterfaceClass
+        SUBCLASS_AUDIOCONTROL,                  // bInterfaceSubClass
+        0x00,                                   // bInterfaceProtocol
+        0x00,                                   // iInterface
+
+
+        // Audio Control Interface
+        CONTROL_INTERFACE_DESCRIPTOR_LENGTH,    // bLength
+        INTERFACE_DESCRIPTOR_TYPE,              // bDescriptorType
+        CONTROL_HEADER,                         // bDescriptorSubtype
+        LSB(0x0100),                            // bcdADC (LSB)
+        MSB(0x0100),                            // bcdADC (MSB)
+        LSB(TOTAL_CONTROL_INTF_LENGTH),         // wTotalLength
+        MSB(TOTAL_CONTROL_INTF_LENGTH),         // wTotalLength
+        0x01,                                   // bInCollection
+        0x01,                                   // baInterfaceNr
+
+        // Audio Input Terminal (Microphone)
+        INPUT_TERMINAL_DESCRIPTOR_LENGTH,       // bLength
+        INTERFACE_DESCRIPTOR_TYPE,              // bDescriptorType
+        CONTROL_INPUT_TERMINAL,                 // bDescriptorSubtype
+        0x01,                                   // bTerminalID
+        LSB(TERMINAL_MICROPHONE),               // wTerminalType
+        MSB(TERMINAL_MICROPHONE),               // wTerminalType
+        0x00,                                   // bAssocTerminal
+        channel_nb,                             // bNrChannels
+        LSB(channel_config),                    // wChannelConfig
+        MSB(channel_config),                    // wChannelConfig
+        0x00,                                   // iChannelNames
+        0x00,                                   // iTerminal
+
+        // Audio Output Terminal (Speaker)
+        OUTPUT_TERMINAL_DESCRIPTOR_LENGTH,      // bLength
+        INTERFACE_DESCRIPTOR_TYPE,              // bDescriptorType
+        CONTROL_OUTPUT_TERMINAL,                // bDescriptorSubtype
+        0x02,                                   // bTerminalID
+        LSB(TERMINAL_USB_STREAMING),            // wTerminalType
+        MSB(TERMINAL_USB_STREAMING),            // wTerminalType
+        0x00,                                   // bAssocTerminal
+        0x01,                                   // bSourceID
+        0x00,                                   // iTerminal
+
+
+
+        // Interface 1, Alternate Setting 0, Audio Streaming - Zero Bandwith
+        INTERFACE_DESCRIPTOR_LENGTH,            // bLength
+        INTERFACE_DESCRIPTOR,                   // bDescriptorType
+        0x01,                                   // bInterfaceNumber
+        0x00,                                   // bAlternateSetting
+        0x00,                                   // bNumEndpoints
+        AUDIO_CLASS,                            // bInterfaceClass
+        SUBCLASS_AUDIOSTREAMING,                // bInterfaceSubClass
+        0x00,                                   // bInterfaceProtocol
+        0x00,                                   // iInterface
+
+        // Interface 1, Alternate Setting 1, Audio Streaming - Operational
+        INTERFACE_DESCRIPTOR_LENGTH,            // bLength
+        INTERFACE_DESCRIPTOR,                   // bDescriptorType
+        0x01,                                   // bInterfaceNumber
+        0x01,                                   // bAlternateSetting
+        0x01,                                   // bNumEndpoints
+        AUDIO_CLASS,                            // bInterfaceClass
+        SUBCLASS_AUDIOSTREAMING,                // bInterfaceSubClass
+        0x00,                                   // bInterfaceProtocol
+        0x00,                                   // iInterface
+
+        // Audio Streaming Interface
+        STREAMING_INTERFACE_DESCRIPTOR_LENGTH,  // bLength
+        INTERFACE_DESCRIPTOR_TYPE,              // bDescriptorType
+        SUBCLASS_AUDIOCONTROL,                  // bDescriptorSubtype
+        0x02,                                   // bTerminalLink (output terminal microphone)
+        0x01,                                   // bDelay
+        0x01,                                   // wFormatTag
+        0x00,                                   // wFormatTag
+
+        // Audio Type I Format
+        FORMAT_TYPE_I_DESCRIPTOR_LENGTH,        // bLength
+        INTERFACE_DESCRIPTOR_TYPE,              // bDescriptorType
+        SUBCLASS_AUDIOSTREAMING,                // bDescriptorSubtype
+        FORMAT_TYPE_I,                          // bFormatType
+        channel_nb,                             // bNrChannels
+        0x02,                                   // bSubFrameSize
+        0x10,                                   // bBitResolution
+        0x01,                                   // bSamFreqType
+        LSB(FREQ),                              // tSamFreq
+        (FREQ >> 8) & 0xff,                     // tSamFreq
+        (FREQ >> 16) & 0xff,                    // tSamFreq
+
+        // Endpoint - Standard Descriptor
+        ENDPOINT_DESCRIPTOR_LENGTH + 2,         // bLength
+        ENDPOINT_DESCRIPTOR,                    // 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
+        STREAMING_ENDPOINT_DESCRIPTOR_LENGTH,   // bLength
+        ENDPOINT_DESCRIPTOR_TYPE,               // bDescriptorType
+        ENDPOINT_GENERAL,                       // bDescriptor
+        0x00,                                   // bmAttributes
+        0x00,                                   // bLockDelayUnits
+        LSB(0x0000),                            // wLockDelay
+        MSB(0x0000),                            // wLockDelay
+
+
+        // Terminator
+        0
+    };
+    return configDescriptor;
+}
+
+uint8_t * USBAudioOUT::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 * USBAudioOUT::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;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBAudioOUT/USBAudioOUT.h	Tue Dec 20 11:41:31 2011 +0000
@@ -0,0 +1,194 @@
+/* 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.
+*/
+
+#ifndef USBAudioOUTOUT_H
+#define USBAudioOUTOUT_H
+
+/* These headers are included for child class. */
+#include "USBEndpoints.h"
+#include "USBDescriptor.h"
+#include "USBDevice_Types.h"
+
+#include "USBDevice.h"
+
+
+/**
+* USBAudioOUT example
+* #include "mbed.h"
+* #include "USBAudioOUT.h"
+*
+* // frequency: 8 kHz
+* #define FREQ 8000
+*
+* // 1 channel: mono
+* #define NB_CHA 1
+*
+* // length of an audio packet: each ms, we receive 48 * 16bits ->48 * 2 bytes. as there is one channel, the length will be 48 * 2 * 1
+* #define AUDIO_LENGTH_PACKET (FREQ/500) * NB_CHA
+*
+* USBAudioOUT audio(FREQ, NB_CHA, 0x1111, 0x78ab);
+*
+* AnalogIn mic(p20);
+*
+* int16_t buf[AUDIO_LENGTH_PACKET/2];
+*
+* int main() {
+*    double mic_mean = 0.0;
+*    double mic_value;
+*
+*    // compute average value of the microphone. We can then center the audio signal sent to the computer
+*    for (int j = 0; j < 1000; j++) {
+*        mic_value = (mic.read_u16() >> 3);
+*        mic_mean = (mic_mean*j + mic_value)/(j+1);
+*    }
+*
+*    while (1) {
+*        for (int i = 0; i < AUDIO_LENGTH_PACKET/2; i++) {
+*            buf[i] = (mic.read_u16() >> 3) - mic_mean;
+*            if (i != AUDIO_LENGTH_PACKET/2) {
+*                wait_us(80);
+*            }
+*        }
+*        audio.write((uint8_t *)buf);
+*    }
+* }
+* @endcode
+*/
+class USBAudioOUT: public USBDevice {
+public:
+
+    /**
+    * Constructor
+    *
+    * @param frequency frequency in Hz (default: 48000)
+    * @param channel_nb channel number (1 or 2) (default: 1)
+    * @param vendor_id Your vendor_id
+    * @param product_id Your product_id
+    * @param product_release Your preoduct_release
+    */
+    USBAudioOUT(uint32_t frequency = 48000, uint8_t channel_nb = 1, uint16_t vendor_id = 0x7bb8, uint16_t product_id = 0x1111, uint16_t product_release = 0x0100);
+    
+    
+    /**
+    * Write an audio packet
+    *
+    * @param buf audio packet
+    * @returns true if successful
+    */
+    bool write(uint8_t * buf);
+
+
+protected:
+
+    /*
+    * Called by USBDevice layer. Set configuration of the device.
+    * For instance, you can add all endpoints that you need on this function.
+    *
+    * @param configuration Number of the configuration
+    * @returns true if class handles this request
+    */
+    virtual bool USBCallback_setConfiguration(uint8_t configuration);
+
+    /*
+    * Get string product descriptor
+    *
+    * @returns pointer to the string product descriptor
+    */
+    virtual uint8_t * stringIproductDesc();
+
+    /*
+    * Get string interface descriptor
+    *
+    * @returns pointer to the string interface descriptor
+    */
+    virtual uint8_t * stringIinterfaceDesc();
+
+    /*
+    * Get configuration descriptor
+    *
+    * @returns pointer to the configuration descriptor
+    */
+    virtual uint8_t * configurationDesc();
+
+    /*
+     * Called by USBDevice layer. Set interface/alternate of the device.
+     *
+     * @param interface Number of the interface to be configured
+     * @param alternate Number of the alternate to be configured
+     * @returns true if class handles this request
+     */
+    virtual bool USBCallback_setInterface(uint16_t interface, uint8_t alternate);
+
+
+    /*
+    * Callback called on each Start of Frame event
+    */
+    virtual void SOF(int frameNumber);
+    
+    /*
+    * Callback called when a packet has been sent
+    */
+    virtual bool EP3_IN_callback();
+
+private:
+
+    // stream available ?
+    volatile bool available;
+
+    // FREQ
+    uint32_t FREQ;
+
+    // size of the maximum packet for the isochronous endpoint
+    uint32_t PACKET_SIZE_ISO;
+
+    // mono, stereo,...
+    uint8_t channel_nb;
+    
+    // channel config: master, left, right
+    uint8_t channel_config;
+
+    // mute state
+    uint8_t mute;
+
+    // Volume Current Value
+    uint16_t volCur;
+
+    // Volume Minimum Value
+    uint16_t volMin;
+
+    // Volume Maximum Value
+    uint16_t volMax;
+
+    // Volume Resolution
+    uint16_t volRes;
+
+    // Buffer containing one audio packet
+    uint8_t * buf_stream;
+    
+    // callback to update volume
+    FunctionPointer updateVol;
+    
+    // boolean showing that the SOF handler has been called. Useful for readNB.
+    volatile bool SOF_handler;
+    
+    volatile bool interruptIN;
+    volatile bool writeIN;
+
+};
+
+#endif
--- a/main.cpp	Tue Dec 20 11:17:33 2011 +0000
+++ b/main.cpp	Tue Dec 20 11:41:31 2011 +0000
@@ -1,9 +1,5 @@
 #include "mbed.h"
-#include "USBAudio.h"
-
-extern "C" void HardFault_Handler() {
-    error("Hard Fault!\n");
-}
+#include "USBAudioOUT.h"
 
 // frequency: 8 kHz
 #define FREQ 8000
@@ -14,15 +10,13 @@
 // length of an audio packet: each ms, we receive 48 * 16bits ->48 * 2 bytes. as there is one channel, the length will be 48 * 2 * 1
 #define AUDIO_LENGTH_PACKET (FREQ/500) * NB_CHA
 
-USBAudio audio(FREQ, NB_CHA, 0x1111, 0x78ab);
+USBAudioOUT audio(FREQ, NB_CHA, 0x1111, 0x78ab);
 
 AnalogIn mic(p20);
-DigitalOut p(p19);
 
 int16_t buf[AUDIO_LENGTH_PACKET/2];
 
 int main() {
-
     double mic_mean = 0.0;
     double mic_value;
 
@@ -33,14 +27,12 @@
     }
 
     while (1) {
-        p = 1;
         for (int i = 0; i < AUDIO_LENGTH_PACKET/2; i++) {
             buf[i] = (mic.read_u16() >> 3) - mic_mean;
             if (i != AUDIO_LENGTH_PACKET/2) {
                 wait_us(80);
             }
         }
-        p = 0;
         audio.write((uint8_t *)buf);
     }
 }