Samuel Mokrani
/
USBAudio_micro
USBAudio example using a microphone
Revision 7:6b0012b8fd01, committed 2011-12-20
- 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
--- 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); } }