SAMV71 Xplained Ultra Software Package 1.5

main.c

Go to the documentation of this file.
00001 /* ---------------------------------------------------------------------------- */
00002 /*                  Atmel Microcontroller Software Support                      */
00003 /*                       SAM Software Package License                           */
00004 /* ---------------------------------------------------------------------------- */
00005 /* Copyright (c) 2015, Atmel Corporation                                        */
00006 /*                                                                              */
00007 /* All rights reserved.                                                         */
00008 /*                                                                              */
00009 /* Redistribution and use in source and binary forms, with or without           */
00010 /* modification, are permitted provided that the following condition is met:    */
00011 /*                                                                              */
00012 /* - Redistributions of source code must retain the above copyright notice,     */
00013 /* this list of conditions and the disclaimer below.                            */
00014 /*                                                                              */
00015 /* Atmel's name may not be used to endorse or promote products derived from     */
00016 /* this software without specific prior written permission.                     */
00017 /*                                                                              */
00018 /* DISCLAIMER:  THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR   */
00019 /* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */
00020 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE   */
00021 /* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,      */
00022 /* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
00023 /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,  */
00024 /* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    */
00025 /* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING         */
00026 /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, */
00027 /* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                           */
00028 /* ---------------------------------------------------------------------------- */
00029 
00030 /** \cond usb_audio_looprec
00031  *  \page usb_audio_looprec USB Audio Loopback-Recorder Example
00032  *
00033  *  \section Purpose
00034  *
00035  *  The USB Audio Loopback-Recorder Example will help you to get
00036  *  familiar with the USB Device Port(UDP) and DACC on SAMV7/E7 micro-controllers.
00037  *  Also it can help you to be familiar with the USB Framework that is used for
00038  *  rapid development of USB-compliant class drivers such as USB Audio Device
00039  *  class.
00040  *
00041  *  \section Requirements
00042  *
00043  *  This package can be used with SAMV71 Xplained Ultra board or SAME70 Xplained board
00044  *  those have both UDP.
00045  *
00046  *  \section Description
00047  *
00048  *  The demo simulates an USB Desktop Speaker with Microphone which actually
00049  *  does not "speak out" but loop back the sound as microphone input.
00050  *
00051  *  When an Xplained board running this program connected to a host (PC for
00052  *  example), with USB cable, the Xplained board appears as a desktop speaker
00053  *  for the host. Then the host can play sound through host software. The audio
00054  *  stream from the host is then sent to the Xplained board. At the same time,
00055  *  the audio stream received is also sent back to host from Xplained board for
00056  *  recording.
00057  *
00058  *  \section Usage
00059  *
00060  *  -# Build the program and download it inside the board.
00061  *     Please refer to the Getting Started with SAM V71/E70 Microcontrollers.pdf
00062  *  -# On the computer, open and configure a terminal application
00063  *     (e.g. HyperTerminal on Microsoft Windows) with these settings:
00064  *    - 115200 bauds
00065  *    - 8 bits of data
00066  *    - No parity
00067  *    - 1 stop bit
00068  *    - No flow control
00069  *  -# Start the application.
00070  *  -# In the terminal window, the following text should appear:
00071  *  \code
00072  *  -- USB Device Audio LoopREC Example xxx --
00073  *  -- SAMxxxxx-xx
00074  *  -- Compiled: xxx xx xxxx xx:xx:xx --
00075  *  \endcode
00076  *  -# When connecting USB cable to windows, the host reports a new USB device
00077  * attachment (if it's the first time you connect an audio speaker demo board to
00078  * your host).
00079  * You can find new "USB Composite Device" and "USB Audio Device" appear in the
00080  * hardware device list.
00081  *  -# You can play sound in host side through the USB Audio Device.
00082  *     When playing sound, you can also record through the USB Audio Device on
00083  *     the host.
00084  *
00085  *  \section References
00086  *  - usb_audio_looprec/main.c
00087  *  - ssc: SSC interface driver
00088  *  - usb: USB Framework, Audio Device Class driver and UDP interface driver
00089  *      - \ref usbd_framework
00090  *         - \ref usbd_api
00091  *      - \ref usbd_audio_rec_drv
00092  *
00093  */
00094 
00095 /**
00096  *  \file
00097  *
00098  *  This file contains all the specific code for the
00099  *  usb_audio_looprec example.
00100  */
00101 
00102 /*----------------------------------------------------------------------------
00103  *         Headers
00104  *----------------------------------------------------------------------------*/
00105 
00106 #include "board.h"
00107 
00108 #include "USBD_LEDs.h"
00109 #include "USBD_Config.h"
00110 
00111 #include "AUDDSpeakerPhoneDriver.h"
00112 
00113 #include <stdio.h>
00114 #include <stdbool.h>
00115 #include <stdint.h>
00116 
00117 /*----------------------------------------------------------------------------
00118  *         Definitions
00119  *----------------------------------------------------------------------------*/
00120 
00121 /**  Number of available audio buffers. */
00122 #define BUFFER_NUMBER       8
00123 /**  Size of one buffer in bytes. */
00124 #define BUFFER_SIZE         (AUDDevice_BYTESPERFRAME \
00125                              + AUDDevice_BYTESPERSUBFRAME)
00126 
00127 /*----------------------------------------------------------------------------
00128  *         External variables
00129  *----------------------------------------------------------------------------*/
00130 
00131 /** Descriptor list for USB Audio SpeakerPhone Driver */
00132 extern const USBDDriverDescriptors auddSpeakerPhoneDriverDescriptors;
00133 
00134 /*----------------------------------------------------------------------------
00135  *         Internal variables
00136  *----------------------------------------------------------------------------*/
00137 
00138 /**  Data buffers for receiving audio frames from the USB host. */
00139 COMPILER_ALIGNED(32) static uint8_t buffers[BUFFER_NUMBER][BUFFER_SIZE];
00140 /**  Number of samples stored in each data buffer. */
00141 //static uint32_t bufferSizes[BUFFER_NUMBER];
00142 /**  Next buffer in which USB data can be stored. */
00143 static uint32_t inBufferIndex = 0;
00144 /**  Number of buffers that can be sent to the DAC. */
00145 static volatile uint32_t numBuffersToSend = 0;
00146 
00147 /**  Current state of the playback stream interface. */
00148 static volatile uint8_t isPlyActive = 0;
00149 /**  Current state of the record stream interface. */
00150 static volatile uint8_t isRecActive = 0;
00151 
00152 
00153 /*----------------------------------------------------------------------------
00154  *         Internal functions
00155  *----------------------------------------------------------------------------*/
00156 
00157 /**
00158  *  Invoked when a frame has been received.
00159  */
00160 static void FrameReceived(uint32_t unused,
00161                           uint8_t status,
00162                           uint32_t transferred,
00163                           uint32_t remaining)
00164 {
00165     unused = unused; /* dummy */
00166     transferred = transferred;
00167     remaining = remaining; /* dummy */
00168 
00169     if (status == USBD_STATUS_SUCCESS) {
00170         /* Loopback! add this buffer to write list */
00171         if (!isRecActive) {}
00172         else {
00173             AUDDSpeakerPhoneDriver_Write(buffers[inBufferIndex],
00174                                          AUDDevice_BYTESPERFRAME);
00175         }
00176 
00177         /* Update input status data */
00178         //bufferSizes[inBufferIndex] = transferred / AUDDevice_BYTESPERSAMPLE;
00179         inBufferIndex = (inBufferIndex + 1) % BUFFER_NUMBER;
00180         numBuffersToSend++;
00181 
00182     } else if (status == USBD_STATUS_ABORTED) {
00183         /* Error , ABORT, add NULL buffer */
00184         //bufferSizes[inBufferIndex] = 0;
00185         inBufferIndex = (inBufferIndex + 1) % BUFFER_NUMBER;
00186         numBuffersToSend++;
00187     } else {
00188         /* Packet is discarded */
00189     }
00190 
00191     /* Receive next packet */
00192     AUDDSpeakerPhoneDriver_Read(buffers[inBufferIndex],
00193                                 AUDDevice_BYTESPERFRAME,
00194                                 (TransferCallback) FrameReceived,
00195                                 0); // No optional argument
00196 }
00197 
00198 /*----------------------------------------------------------------------------
00199  *         Callbacks re-implementation
00200  *----------------------------------------------------------------------------*/
00201 /**
00202  * Invoked when the configuration of the device changes. Parse used endpoints.
00203  * \param cfgnum New configuration number.
00204  */
00205 void USBDDriverCallbacks_ConfigurationChanged(unsigned char cfgnum)
00206 {
00207     AUDDSpeakerPhoneDriver_ConfigurationChangeHandler(cfgnum);
00208 }
00209 
00210 /**
00211  * Invoked whenever the active setting of an interface is changed by the
00212  * host. Reset streaming interface.
00213  * \param interface Interface number.
00214  * \param setting Newly active setting.
00215  */
00216 void USBDDriverCallbacks_InterfaceSettingChanged(unsigned char interface,
00217         unsigned char setting)
00218 {
00219     AUDDSpeakerPhoneDriver_InterfaceSettingChangedHandler(interface, setting);
00220 }
00221 
00222 /**
00223  *  Invoked whenever a SETUP request is received from the host. Forwards the
00224  *  request to the standard handler.
00225  */
00226 void USBDCallbacks_RequestReceived(const USBGenericRequest *request)
00227 {
00228     AUDDSpeakerPhoneDriver_RequestHandler(request);
00229 }
00230 
00231 /**
00232  *  Invoked when an audio channel get muted or unmuted. Mutes/unmutes the
00233  *  channel at the DAC level.
00234  *  \param mic      Microphone/Speaker stream changed.
00235  *  \param channel  Channel number that changed.
00236  *  \param muted    Indicates the new mute status of the channel.
00237  */
00238 void AUDDSpeakerPhoneDriver_MuteChanged(uint8_t mic,
00239                                         uint8_t channel,
00240                                         uint8_t muted)
00241 {
00242     /* Speaker Master channel */
00243     if (!mic && channel == AUDDSpeakerPhoneDriver_MASTERCHANNEL) {
00244       if (muted){
00245             TRACE_WARNING("MuteMaster ");
00246       } else {
00247             TRACE_INFO("UnmuteMaster ");
00248       }
00249       }
00250 }
00251 
00252 /**
00253  *  Invoked when an audio streaming interface setting changed.
00254  *  Audio stream is automatically reset.
00255  *  Actually control streaming rate.
00256  *  \param mic         Microphone/Speaker stream changed.
00257  *  \param newSetting  New stream (interface) setting.
00258  */
00259 void AUDDSpeakerPhoneDriver_StreamSettingChanged(uint8_t mic,
00260         uint8_t newSetting)
00261 {
00262     /* Speaker stream */
00263     if (!mic)
00264         isPlyActive = (newSetting > 0);
00265     else
00266         isRecActive = (newSetting > 0);
00267 }
00268 
00269 /**
00270  * Configure OTG settings for USB device
00271  */
00272 static void _ConfigureUotghs(void)
00273 {
00274     /* UTMI parallel mode, High/Full/Low Speed */
00275     /* UOTGCK not used in this configuration (High Speed) */
00276     PMC->PMC_SCDR = PMC_SCDR_USBCLK;
00277     /* USB clock register: USB Clock Input is UTMI PLL */
00278     PMC->PMC_USB = PMC_USB_USBS;
00279     /* Enable peripheral clock for USBHS */
00280     PMC_EnablePeripheral(ID_USBHS);
00281     USBHS->USBHS_CTRL = USBHS_CTRL_UIMOD_DEVICE;
00282     /* Enable PLL 480 MHz */
00283     PMC->CKGR_UCKR = CKGR_UCKR_UPLLEN | CKGR_UCKR_UPLLCOUNT(0xF);
00284 
00285     /* Wait that PLL is considered locked by the PMC */
00286     while (!(PMC->PMC_SR & PMC_SR_LOCKU));
00287 
00288     /* IRQ */
00289     NVIC_EnableIRQ(USBHS_IRQn);
00290 }
00291 /*----------------------------------------------------------------------------
00292  *         Exported functions
00293  *----------------------------------------------------------------------------*/
00294 
00295 /**
00296  *  \brief usb_audio_looprec Application entry point.
00297  *
00298  *  Starts the driver and waits for an audio input stream to forward to the DAC.
00299  */
00300 int main(void)
00301 {
00302     volatile uint8_t plyOn = 0, recOn = 0;
00303 
00304     /* Disable watchdog */
00305     WDT_Disable(WDT);
00306 
00307     SCB_EnableICache();
00308     SCB_EnableDCache();
00309 
00310     printf("-- USB Device Audio LoopREC Example %s --\n\r", SOFTPACK_VERSION);
00311     printf("-- %s\n\r", BOARD_NAME);
00312     printf("-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__ ,
00313             COMPILER_NAME);
00314 
00315     /* If they are present, configure Vbus & Wake-up pins */
00316     PIO_InitializeInterrupts(0);
00317 
00318     /* Interrupt priority */
00319     NVIC_SetPriority(USBHS_IRQn, 2);
00320 
00321     /* Audio STREAM LED */
00322     LED_Configure(USBD_LEDOTHER);
00323 
00324     /* Initialize OTG clocks */
00325     _ConfigureUotghs();
00326 
00327     /* USB audio driver initialization */
00328     AUDDSpeakerPhoneDriver_Initialize(&auddSpeakerPhoneDriverDescriptors);
00329 
00330     // Start USB stack to authorize VBus monitoring
00331     USBD_Connect();
00332 
00333     /* Infinite loop */
00334     while (1) {
00335         if (USBD_GetState() < USBD_STATE_CONFIGURED) {
00336             continue;
00337         }
00338 
00339         if (plyOn) {
00340             if (isPlyActive == 0) {
00341                 printf("plyE ");
00342                 plyOn = 0;
00343             }
00344         } else if (isPlyActive) {
00345             /* Try to Start Reading the incoming audio stream */
00346             AUDDSpeakerPhoneDriver_Read(buffers[inBufferIndex],
00347                                         AUDDevice_BYTESPERFRAME,
00348                                         (TransferCallback) FrameReceived,
00349                                         0); // No optional argument
00350             printf("plyS ");
00351             plyOn = 1;
00352         }
00353 
00354         if (recOn) {
00355             if (isRecActive == 0) {
00356                 printf("recE ");
00357                 recOn = 0;
00358             }
00359         } else if (isRecActive) {
00360             printf("recS ");
00361             recOn = 1;
00362         }
00363     }
00364 }
00365 /** \endcond */
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines