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 /** \cond usb_audio_speaker
00030  *  \page usb_audio_speaker USB Audio Speaker Example
00031  *
00032  *  \section Purpose
00033  *
00034  *  The USB Audio Speaker Example will help you to get familiar with the
00035  *  USB Device Port(UDP) and SSC on SAMv7 Microcontrollers. Also
00036  *  it can help you to be familiar with the USB Framework that is used for
00037  *  rapid development of USB-compliant class drivers such as USB Audio Device
00038  *  class.
00039  *
00040  *  \section Requirements
00041  *
00042  *  This package can be used with SAMV71 Xplained board that have both
00043  *  UDP and SSC.
00044  *
00045  *  \section Description
00046  *
00047  *  The demo simulates an USB Desktop Speaker.
00048  *
00049  *  When an Xplained board running this program connected to a host (PC for
00050  *  example), with USB cable, the Xplained board appears as a desktop speaker
00051  *  for the host. Then the host can play sound through host software. The audio
00052  *  stream from the host is then sent to the Xplained board, and eventually sent
00053  *  to audio DAC connected to the amplifier.
00054  *
00055  *  \section Usage
00056  *
00057  *  -# Build the program and download it inside the SAM V71 Xplained Ultra board.
00058  *     Please refer to the Getting Started with SAM V71 Microcontrollers.pdf
00059  *  -# On the computer, open and configure a terminal application
00060  *     (e.g. HyperTerminal on Microsoft Windows) with these settings:
00061  *    - 115200 bauds
00062  *    - 8 bits of data
00063  *    - No parity
00064  *    - 1 stop bit
00065  *    - No flow control
00066  *  -# Start the application.
00067  *  -# In the terminal window, the following text should appear:
00068  *  \code
00069  *  -- USB Device Audio Speaker Example xxx --
00070  *  -- SAMxxxxx-xx
00071  *  -- Compiled: xxx xx xxxx xx:xx:xx --
00072  *  \endcode
00073  *  -# When connecting USB cable to windowss, the host
00074  *     reports a new USB device attachment (if it's the first time you connect
00075  *     an audio speaker demo board to your host). You can find new
00076  *     "USB Composite Device" and "USB Audio Device" appear in the hardware
00077  *     device list.
00078  *  -# You can play sound in host side through the USB Audio Device, and it
00079  *     can be heard from the earphone connected to the Xplained board.
00080  *
00081  *  \section References
00082  *  - usb_audio_speaker/main.c
00083  *  - ssc: SSC interface driver
00084  *  - usb: USB Framework, Audio Device Class driver and UDP interface driver
00085  *      - \ref usbd_framework
00086  *         - \ref usbd_api
00087  *      - \ref usbd_audio_speaker
00088  */
00089 
00090 /**
00091  *  \file
00092  *
00093  *  This file contains all the specific code for the
00094  *  usb_audio_speaker example.
00095  */
00096 
00097 /*----------------------------------------------------------------------------
00098  *         Headers
00099  *----------------------------------------------------------------------------*/
00100 
00101 #include "board.h"
00102 
00103 #include "USBD_LEDs.h"
00104 #include "USBD_Config.h"
00105 
00106 #include "AUDDSpeakerDriver.h"
00107 
00108 #include <stdio.h>
00109 #include <stdbool.h>
00110 #include <stdint.h>
00111 #include <string.h>
00112 
00113 /*----------------------------------------------------------------------------
00114  *         Definitions
00115  *----------------------------------------------------------------------------*/
00116 
00117 /**  Number of available audio buffers. */
00118 #define BUFFER_NUMBER       500
00119 /**  Size of one buffer in bytes. */
00120 #define BUFFER_SIZE     (AUDDevice_BYTESPERFRAME)
00121 
00122 /**  Delay in ms for starting the DAC transmission
00123      after a frame has been received. */
00124 #define DAC_DELAY           2
00125 
00126 /** SSC: Number of slots in a frame */
00127 #define SLOT_BY_FRAME           (2)
00128 /** SSC: Number of bits in a slot */
00129 #define BITS_BY_SLOT            (16)
00130 #define I2S_SLAVE_TX_SETTING       ((SSC_TCMR_CKS_TK) |             \
00131                                     (SSC_TCMR_CKO_NONE) |            \
00132                                     (SSC_TCMR_START_TF_EDGE) |       \
00133                                     (SSC_TCMR_STTDLY(1)) |           \
00134                                     (SSC_TCMR_PERIOD(0)))
00135 
00136 #define I2S_SLAVE_TX_FRM_SETTING  ((SSC_TFMR_DATLEN(BITS_BY_SLOT - 1)) |  \
00137                                    (SSC_TFMR_MSBF) |                      \
00138                                    (SSC_TFMR_DATNB(SLOT_BY_FRAME - 1)) |  \
00139                                    (SSC_TFMR_FSOS_NONE))
00140 
00141 
00142 #define I2S_SLAVE_RX_SETTING       ((SSC_RCMR_CKS_TK) |       \
00143                                     (SSC_RCMR_CKO_NONE) |      \
00144                                     (SSC_RCMR_CKI) |           \
00145                                     (SSC_RCMR_START_RF_EDGE) | \
00146                                     (SSC_RCMR_STTDLY(1)) |     \
00147                                     (SSC_RCMR_PERIOD(0)))
00148 
00149 #define I2S_SLAVE_RX_FRM_SETTING   ((SSC_RFMR_DATLEN(BITS_BY_SLOT - 1)) | \
00150                                     (SSC_RFMR_MSBF) |                      \
00151                                     (SSC_RFMR_DATNB(SLOT_BY_FRAME - 1)) |  \
00152                                     (SSC_RFMR_FSOS_NONE))
00153 
00154 /** TWI clock */
00155 #define TWI_CLOCK               400000
00156 /** Audio sample rate */
00157 #define SAMPLE_RATE             (48000)
00158 
00159 /*----------------------------------------------------------------------------
00160  *         External variables
00161  *----------------------------------------------------------------------------*/
00162 
00163 /** Descriptor list for USB Audio Speaker Device Driver */
00164 extern const USBDDriverDescriptors auddSpeakerDriverDescriptors;
00165 
00166 /*----------------------------------------------------------------------------
00167  *         Internal variables
00168  *----------------------------------------------------------------------------*/
00169 
00170 /**  Data buffers for receiving audio frames from the USB host. */
00171 
00172 COMPILER_ALIGNED(32) static uint8_t buffers[BUFFER_NUMBER][BUFFER_SIZE];
00173 
00174 /**  Number of samples stored in each data buffer. */
00175 static volatile uint32_t bufferSizes[BUFFER_NUMBER];
00176 /**  Next buffer in which USB data can be stored. */
00177 static volatile uint32_t inBufferIndex = 0;
00178 /**  Next buffer which should be sent to the DAC. */
00179 static uint32_t outBufferIndex = 0;
00180 /**  Number of buffers that can be sent to the DAC. */
00181 static volatile uint32_t numBuffersToSend = 0;
00182 
00183 /**  Current state of the DAC transmission. */
00184 static volatile uint32_t isDacActive = 0;
00185 static volatile uint32_t isFirstFrame = 1;
00186 /**  Number of buffers to wait for before the DAC starts to transmit data. */
00187 static volatile uint32_t dacDelay;
00188 
00189 /** Twi instance*/
00190 static Twid twid;
00191 /** Global DMA driver for all transfer */
00192 static sXdmad dmad;
00193 /** DMA channel for TX */
00194 static uint32_t sscDmaTxChannel;
00195 
00196 /** List of pins to configure. */
00197 static const Pin pinsAudio[] = { PIN_TWI_TWD0,
00198                                  PIN_TWI_TWCK0,
00199                                  PIN_SSC_TD,
00200                                  PIN_SSC_TK,
00201                                  PIN_SSC_TF,
00202                                  PIN_SSC_RD,
00203                                  PIN_SSC_RK,
00204                                  PIN_SSC_RF,
00205                                  PIN_PCK2
00206                                };
00207 
00208 /*----------------------------------------------------------------------------
00209  *         Internal functions
00210  *----------------------------------------------------------------------------*/
00211 /**
00212  * Interrupt handler for the XDMAC.
00213  */
00214 void XDMAC_Handler(void)
00215 {
00216     XDMAD_Handler(&dmad);
00217 }
00218 
00219 /**
00220  *  \brief Start DMA sending/waiting data.
00221  */
00222 static void _SscDma(volatile uint32_t *pReg, uint32_t dmaChannel,
00223                     void *pBuffer, uint16_t wSize)
00224 {
00225     sXdmad *pDmad = &dmad;
00226     sXdmadCfg xdmadCfg;
00227 
00228     xdmadCfg.mbr_ubc = wSize;
00229     xdmadCfg.mbr_sa = (uint32_t) pBuffer;
00230     xdmadCfg.mbr_da = (uint32_t) pReg;
00231     xdmadCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN
00232                        | XDMAC_CC_MBSIZE_SINGLE
00233                        | XDMAC_CC_DSYNC_MEM2PER
00234                        | XDMAC_CC_CSIZE_CHK_1
00235                        | XDMAC_CC_DWIDTH_HALFWORD
00236                        | XDMAC_CC_SIF_AHB_IF1
00237                        | XDMAC_CC_DIF_AHB_IF1
00238                        | XDMAC_CC_SAM_INCREMENTED_AM
00239                        | XDMAC_CC_DAM_FIXED_AM
00240                        | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber(
00241                                             ID_SSC, XDMAD_TRANSFER_TX));
00242     xdmadCfg.mbr_bc = 0;
00243     xdmadCfg.mbr_ds = 0;
00244     xdmadCfg.mbr_sus = 0;
00245     xdmadCfg.mbr_dus = 0;
00246 
00247     XDMAD_ConfigureTransfer(pDmad, dmaChannel, &xdmadCfg, 0, 0, (XDMAC_CIE_BIE   |
00248                              XDMAC_CIE_DIE   |
00249                              XDMAC_CIE_FIE   |
00250                              XDMAC_CIE_RBIE  |
00251                              XDMAC_CIE_WBIE  |
00252                              XDMAC_CIE_ROIE));
00253 
00254     SCB_CleanDCache_by_Addr((uint32_t *)pBuffer, wSize);
00255     memory_sync();
00256 
00257     XDMAD_StartTransfer(pDmad, dmaChannel);
00258 
00259 }
00260 
00261 /**
00262  *  \brief DMA TX callback
00263  */
00264 static void _SscTxCallback(uint32_t channel, void *pArg)
00265 {
00266     sXdmad *pDmad = &dmad;
00267     Xdmac *pXdmac = pDmad->pXdmacs;
00268     channel = channel;
00269     pArg = pArg; /*dummy */
00270 
00271     if (numBuffersToSend == 0) {
00272         /* End of transmission */
00273         isDacActive = 0;
00274         return;
00275     }
00276 
00277     /* Load next buffer */
00278 
00279     XDMAC_SetSourceAddr(pXdmac, sscDmaTxChannel,
00280                         (uint32_t) buffers[outBufferIndex]);
00281     XDMAC_SetMicroblockControl(pXdmac, sscDmaTxChannel,
00282                                bufferSizes[outBufferIndex]);
00283     SCB_CleanDCache_by_Addr((uint32_t *) buffers[outBufferIndex],
00284                             bufferSizes[outBufferIndex]);
00285     outBufferIndex = (outBufferIndex + 1) % BUFFER_NUMBER;
00286     numBuffersToSend --;
00287     memory_sync();
00288     XDMAD_StartTransfer(pDmad, sscDmaTxChannel);
00289 }
00290 
00291 /**
00292  * \brief DMA driver configuration
00293  */
00294 static void _ConfigureDma(void)
00295 {
00296     sXdmad *pDmad = &dmad;
00297     /* Driver initialize */
00298     XDMAD_Initialize(pDmad, 0);
00299     /* IRQ configure */
00300     NVIC_ClearPendingIRQ(XDMAC_IRQn);
00301     NVIC_SetPriority(XDMAC_IRQn, 1);
00302     NVIC_EnableIRQ(XDMAC_IRQn);
00303 
00304     /* Allocate DMA channels for SSC */
00305     sscDmaTxChannel = XDMAD_AllocateChannel(pDmad, XDMAD_TRANSFER_MEMORY, ID_SSC);
00306 
00307     if (sscDmaTxChannel == XDMAD_ALLOC_FAILED) {
00308         printf("xDMA channel allocation error\n\r");
00309 
00310         while (1);
00311     }
00312 
00313     /* Set TX callback */
00314     XDMAD_SetCallback(pDmad, sscDmaTxChannel, (XdmadTransferCallback)_SscTxCallback,
00315                       0);
00316     XDMAD_PrepareChannel(pDmad, sscDmaTxChannel);
00317 }
00318 
00319 /**
00320  * Enable/Disable audio channels
00321  */
00322 static void AudioPlayEnable(uint8_t enable)
00323 {
00324     if (enable == 1)
00325         SSC_EnableTransmitter(SSC);
00326     else if (enable == 0)
00327         SSC_DisableTransmitter(SSC);
00328 }
00329 
00330 /**
00331  * Adjust codec for sync
00332  * \param adjust Sync case: default(0)/faster(>0)/slower(<0)
00333  */
00334 static void _SyncAdjust(int32_t adjust)
00335 {
00336     if (adjust > 0) {
00337         /* Fractional multiply for FLL_K, Fref = 0x8000 (1/2) */
00338         WM8904_Write(&twid, WM8904_SLAVE_ADDRESS, WM8904_REG_FLL_CRTL3, 0xFF00);
00339         /* FLL_GAIN=0, FLL_N=187 */
00340         return;
00341     }
00342 
00343     if (adjust < 0) {
00344         /* Fractional multiply for FLL_K, Fref = 0x8000 (1/2) */
00345         WM8904_Write(&twid, WM8904_SLAVE_ADDRESS, WM8904_REG_FLL_CRTL3, 0x5000);
00346         /* FLL_GAIN=0, FLL_N=187 */
00347         return;
00348     }
00349 
00350     /* Default: 32K -> 48K*256, FLL: 32768*187.5/16/8
00351      */
00352     /* FLL_FRATIO=4 (/16), FLL_OUTDIV= 7 (/8) */
00353     /* Fractional multiply for FLL_K, Fref = 0x8000 (1/2) */
00354     WM8904_Write(&twid, WM8904_SLAVE_ADDRESS, WM8904_REG_FLL_CRTL3,
00355                  0x8000 + 0x3000);
00356     /* FLL_GAIN=0, FLL_N=187 */
00357     return;
00358 }
00359 
00360 /**
00361  * Configure the TWI and DACC for audio output.
00362  * \param sampleRate Audio sample rate.
00363  * \param mck        MCK frequency.
00364  */
00365 static void _ConfigureAudioPlay(uint32_t sampleRate, uint32_t mck)
00366 {
00367     /* -- Pins Configuration -- */
00368     PIO_Configure(pinsAudio, PIO_LISTSIZE(pinsAudio));
00369 
00370     /* -- SSC Configuration -- */
00371     sampleRate = sampleRate; /*dummy */
00372     SSC_Configure(SSC, 0, mck);
00373     SSC_DisableTransmitter(SSC);
00374     SSC_ConfigureTransmitter(SSC, I2S_SLAVE_TX_SETTING, I2S_SLAVE_TX_FRM_SETTING);
00375     SSC_ConfigureReceiver(SSC, I2S_SLAVE_RX_SETTING, I2S_SLAVE_RX_FRM_SETTING);
00376 
00377     /* Enable TWI peripheral clock */
00378     PMC_EnablePeripheral(ID_TWIHS0);
00379     /* Configure and enable the TWI (required for accessing the DAC) */
00380     TWI_ConfigureMaster(TWIHS0, TWI_CLOCK, mck);
00381     TWID_Initialize(&twid, TWIHS0);
00382 
00383     /* Initialize the audio DAC
00384      */
00385 
00386     WM8904_Write(&twid, WM8904_SLAVE_ADDRESS, WM8904_REG_RESET, 0);
00387     Wait(100);
00388 
00389     /* WM8904 as master */
00390     if (WM8904_Read(&twid, WM8904_SLAVE_ADDRESS, 0) != 0x8904) {
00391         printf("WM8904 not found!\n\r");
00392 
00393         while (1);
00394     }
00395 
00396     WM8904_Init(&twid, WM8904_SLAVE_ADDRESS, PMC_MCKR_CSS_SLOW_CLK);
00397     _SyncAdjust(0);
00398     PMC_ConfigurePCK2(PMC_MCKR_CSS_SLOW_CLK, PMC_MCKR_PRES_CLK_1);
00399     /* Mute */
00400     AudioPlayEnable(0);
00401 }
00402 
00403 /**
00404  *  Invoked when a frame has been received.
00405  */
00406 static void FrameReceived(uint32_t unused,
00407                           uint8_t status,
00408                           uint32_t transferred,
00409                           uint32_t remaining)
00410 {
00411     unused = unused; /*dummy */
00412     remaining = remaining; /*dummy */
00413 
00414     if (status == USBD_STATUS_SUCCESS) {
00415         bufferSizes[inBufferIndex] = transferred / AUDDevice_BYTESPERSAMPLE;
00416         inBufferIndex = (inBufferIndex + 1) % BUFFER_NUMBER;
00417         numBuffersToSend++;
00418 
00419         /* Start DAc transmission if necessary */
00420         if (!isDacActive) {
00421             dacDelay = DAC_DELAY;
00422             isDacActive = 1;
00423         } else if (dacDelay > 0) {
00424             /* Wait until a few buffers have been received */
00425             dacDelay--;
00426         } else if (isFirstFrame) {
00427             /* Start sending buffers */
00428             isFirstFrame = 0;
00429             AudioPlayEnable(1);
00430             _SscDma(&(SSC->SSC_THR), sscDmaTxChannel,
00431                     buffers[outBufferIndex], bufferSizes[outBufferIndex]);
00432             outBufferIndex = (outBufferIndex + 1) % BUFFER_NUMBER;
00433             numBuffersToSend --;
00434         }
00435     } else if (status == USBD_STATUS_ABORTED) {
00436         /* Error , ABORT, add NULL buffer */
00437         bufferSizes[inBufferIndex] = 0;
00438     } else {
00439         /* Packet is discarded */
00440     }
00441 
00442     /* Receive next packet */
00443     AUDDSpeakerDriver_Read(buffers[inBufferIndex],
00444                            AUDDevice_BYTESPERFRAME,
00445                            (TransferCallback) FrameReceived,
00446                            0); // No optional argument
00447 }
00448 
00449 /*----------------------------------------------------------------------------
00450  *         Callbacks re-implementation
00451  *----------------------------------------------------------------------------*/
00452 /**
00453  * Invoked when the configuration of the device changes. Parse used endpoints.
00454  * \param cfgnum New configuration number.
00455  */
00456 void USBDDriverCallbacks_ConfigurationChanged(unsigned char cfgnum)
00457 {
00458     AUDDSpeakerDriver_ConfigurationChangeHandler(cfgnum);
00459 }
00460 
00461 /**
00462  * Invoked whenever the active setting of an interface is changed by the
00463  * host. Reset streaming interface.
00464  * \param interface Interface number.
00465  * \param setting Newly active setting.
00466  */
00467 void USBDDriverCallbacks_InterfaceSettingChanged(unsigned char interface,
00468         unsigned char setting)
00469 {
00470     AUDDSpeakerDriver_InterfaceSettingChangedHandler(interface, setting);
00471 }
00472 
00473 /**
00474  *  Invoked whenever a SETUP request is received from the host. Forwards the
00475  *  request to the standard handler.
00476  */
00477 void USBDCallbacks_RequestReceived(const USBGenericRequest *request)
00478 {
00479     AUDDSpeakerDriver_RequestHandler(request);
00480 }
00481 
00482 /**
00483  *  Invoked when an audio channel get muted or unmuted. Mutes/unmutes the
00484  *  channel at the DAC level.
00485  *  \param channel  Channel number that changed.
00486  *  \param muted    Indicates the new mute status of the channel.
00487  */
00488 void AUDDSpeakerDriver_MuteChanged(uint8_t channel, uint8_t muted)
00489 {
00490     /* Speaker Master channel */
00491     if (channel == AUDDSpeakerDriver_MASTERCHANNEL) {
00492         if (muted) {
00493             AudioPlayEnable(0);
00494             TRACE_WARNING("MuteMaster ");
00495         } else {
00496             TRACE_INFO("UnmuteMaster ");
00497             AudioPlayEnable(1);
00498         }
00499     }
00500 }
00501 
00502 /**
00503  *  Invoked when an audio streaming interface setting changed. Actually control
00504  *  streaming rate.
00505  *  \param newSetting  New stream (interface) setting.
00506  */
00507 void AUDDSpeakerDriver_StreamSettingChanged(uint8_t newSetting)
00508 {
00509     if (newSetting) {
00510         LED_Set(USBD_LEDOTHER);
00511         numBuffersToSend = 0;
00512     } else
00513         LED_Clear(USBD_LEDOTHER);
00514 }
00515 
00516 /**
00517  * Configure clock settings for USB device
00518  */
00519 static void _ConfigureUsbhs(void)
00520 {
00521     /* UTMI parallel mode, High/Full/Low Speed */
00522     /* UUSBCK not used in this configuration (High Speed) */
00523     PMC->PMC_SCDR = PMC_SCDR_USBCLK;
00524     /* USB clock register: USB Clock Input is UTMI PLL */
00525     PMC->PMC_USB = PMC_USB_USBS;
00526     /* Enable peripheral clock for USBHS */
00527     PMC_EnablePeripheral(ID_USBHS);
00528     USBHS->USBHS_CTRL = USBHS_CTRL_UIMOD_DEVICE;
00529     /* Enable PLL 480 MHz */
00530     PMC->CKGR_UCKR = CKGR_UCKR_UPLLEN | CKGR_UCKR_UPLLCOUNT(0xF);
00531 
00532     /* Wait that PLL is considered locked by the PMC */
00533     while (!(PMC->PMC_SR & PMC_SR_LOCKU));
00534 
00535     /* IRQ */
00536     NVIC_EnableIRQ(USBHS_IRQn);
00537 }
00538 
00539 /*----------------------------------------------------------------------------
00540  *         Exported functions
00541  *----------------------------------------------------------------------------*/
00542 /**
00543  *  \brief usb_audio_speaker Application entry point.
00544  *
00545  *  Starts the driver and waits for an audio input stream to forward to the DAC.
00546  */
00547 int main(void)
00548 {
00549     volatile uint8_t usbConn = 0;
00550     volatile uint8_t audioOn = 0;
00551     int32_t  numDiff = 0, prevDiff = 0;
00552     int8_t   clockAdjust = 0;
00553 
00554     /* Disable watchdog */
00555     WDT_Disable(WDT);
00556 
00557     printf("-- USB Device Audio Speaker Example %s --\n\r", SOFTPACK_VERSION);
00558     printf("-- %s\n\r", BOARD_NAME);
00559     printf("-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__ ,
00560             COMPILER_NAME);
00561 
00562     SCB_EnableICache();
00563     SCB_EnableDCache();
00564 
00565     /* LED */
00566     LED_Configure(LED_YELLOW0);
00567 
00568     TimeTick_Configure();
00569     /* Interrupt priority */
00570     NVIC_SetPriority(USBHS_IRQn, 2);
00571 
00572     /* Initialize all USB power (off) */
00573     _ConfigureUsbhs();
00574     /* Configure Audio */
00575     _ConfigureAudioPlay(AUDDevice_SAMPLERATE, BOARD_MCK);
00576 
00577     /* Configure DMA */
00578     _ConfigureDma();
00579 
00580     /* USB audio driver initialization */
00581     AUDDSpeakerDriver_Initialize(&auddSpeakerDriverDescriptors);
00582 
00583     // Start USB stack to authorize VBus monitoring
00584     USBD_Connect();
00585 
00586     /* Infinite loop */
00587     while (1) {
00588         if (USBD_GetState() < USBD_STATE_CONFIGURED) {
00589             usbConn = 0;
00590             continue;
00591         }
00592 
00593         if (audioOn) {
00594             if (isDacActive == 0) {
00595                 AudioPlayEnable(0);
00596                 printf("audE ");
00597                 isFirstFrame = 1;
00598                 audioOn = 0;
00599             } else {
00600                 numDiff = numBuffersToSend - DAC_DELAY;
00601 
00602                 if (prevDiff != numDiff) {
00603                     prevDiff = numDiff;
00604 
00605                     if (numDiff > 1 && clockAdjust != 1) {
00606                         printf("+");
00607                         /* USB too fast or SSC too slow: faster clock */
00608                         clockAdjust = 1;
00609                         _SyncAdjust(1);
00610                     }
00611 
00612                     if (numDiff < -1 && clockAdjust != -1) {
00613                         printf("-");
00614                         /* USB too slow or SSC too fast: slower clock */
00615                         clockAdjust = -1;
00616                         _SyncAdjust(-1);
00617                     }
00618 
00619                     if (numDiff == 0 && clockAdjust != 0) {
00620                         clockAdjust = 0;
00621                         _SyncAdjust(0);
00622                     }
00623                 }
00624             }
00625         } else if (isDacActive) {
00626             printf("audS ");
00627             audioOn = 1;
00628         }
00629 
00630         if (usbConn == 0) {
00631             usbConn = 1;
00632             /* Start Reading the incoming audio stream */
00633             AUDDSpeakerDriver_Read(buffers[inBufferIndex],
00634                                    AUDDevice_BYTESPERFRAME,
00635                                    (TransferCallback) FrameReceived,
00636                                    0); // No optional argument
00637         }
00638     }
00639 }
00640 /** \endcond */
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines