SAMV71 Xplained Ultra Software Package 1.4

main.c

Go to the documentation of this file.
00001 /* ----------------------------------------------------------------------------
00002  *         SAM Software Package License 
00003  * ----------------------------------------------------------------------------
00004  * Copyright (c) 2014, Atmel Corporation
00005  *
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions are met:
00010  *
00011  * - Redistributions of source code must retain the above copyright notice,
00012  * this list of conditions and the disclaimer below.
00013  *
00014  * Atmel's name may not be used to endorse or promote products derived from
00015  * this software without specific prior written permission.
00016  *
00017  * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00019  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
00020  * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00022  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
00023  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00024  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00025  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
00026  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  * ----------------------------------------------------------------------------
00028  */
00029 /** \cond usb_iad_cdc_aud
00030  *  \page usb_iad_cdc_aud USB CDC(Serial)+Audio(Speaker) Example
00031  *
00032  *  \section Purpose
00033  *
00034  *  The Example will help you to get familiar with the USB Framework that is
00035  *  used for rapid development of USB-compliant class drivers such as USB
00036  *  Composite device that integrates a CDC Virtual Serial Port Function and
00037  *  an Audio Speaker Function.
00038  *
00039  *  \section Requirements
00040  *
00041  *  This package can be used with SAM V71 Xplained Ultra board that have UDP
00042  *  and SSC.
00043  *
00044  *  \section win_drv_update Windows Driver Update
00045  *
00046  * The composite device is generally supported by Microsoft windows, but some
00047  * patches are needed for muti-interface functions such as CDC & Audio.
00048  *
00049  *  \section Description
00050  *
00051  * When the board running this program connected to a host (PC for example), with
00052  * USB cable, host will notice the attachment of a USB %device (USB Composite
00053  * Device) with a USB Virtual COM port(AT91 USB to Serial Converter)
00054  * and a USB Audio Device.
00055  *
00056  *  \section Usage
00057  *
00058  *  -# Build the program and download it inside the SAM V71 Xplained Ultra board. 
00059  *     Please refer to the Getting Started with SAM V71 Microcontrollers.pdf
00060  *  -# On the computer, open and configure a terminal application
00061  *     (e.g. HyperTerminal on Microsoft Windows) with these settings:
00062  *    - 115200 bauds
00063  *    - 8 bits of data
00064  *    - No parity
00065  *    - 1 stop bit
00066  *    - No flow control
00067  *  -# Start the application.
00068  *  -# In the terminal window, the following text should appear:
00069  *  \code
00070  *  -- USB CDC + Audio Device Example xxx --
00071  *  -- SAMxxxxx-xx
00072  *  -- Compiled: xxx xx xxxx xx:xx:xx --
00073  *  \endcode
00074  *  -# When connecting USB cable to windows, the LED blinks, and the host
00075  *     reports a new USB %device attachment (if it's the first time you connect
00076  *     an %audio speaker demo board to your host). You can find new
00077  *     "USB Composite Device" and "USB Audio Device" appear in the hardware
00078  *     %device list.
00079  *  -# You can play sound in host side through the USB Audio Device, and it
00080  *     can be heard from the earphone connected to the board.
00081  *
00082  *  \section References
00083  *  - usb_iad_cdc_aud/main.c
00084  *  - pio: Pin configurations and peripheral configure.
00085  *  - dacc: DACC interface driver
00086  *  - adc: ADC interface driver
00087  *  - usb: USB Framework, CDC, Audio function driver and UDP interface driver
00088  *      - \ref usbd_framework
00089  *         - \ref usbd_api
00090  *      - \ref usbd_composite "composite"
00091  *         - \ref usbd_composite_drv
00092  *      - \ref usbd_cdc "cdc-serial"
00093  *         - \ref usbd_cdc_serial_drv
00094  *      - \ref usbd_aud "audio"
00095  *         - \ref usbd_audio_rec_drv
00096  *  - projects: more detailed information for CDC(Serial) and Audio(Speaker)
00097  *      - \ref usb_core
00098  *      - \ref usb_cdc_serial
00099  *      - \ref usb_audio_speaker, \ref usb_audio_headphone
00100  */
00101 
00102 /**
00103  *  \file
00104  *
00105  *  This file contains all the specific code for the
00106  *  usb_iad_cdc_aud example.
00107  */
00108 
00109 /*----------------------------------------------------------------------------
00110  *         Headers
00111  *----------------------------------------------------------------------------*/
00112 
00113 #include "board.h"
00114 
00115 #include <CDCAUDDDriver.h>
00116 #include <CDCDSerial.h>
00117 #include <AUDDFunction.h>
00118 
00119 #include <USBD_Config.h>
00120 
00121 #include <stdio.h>
00122 #include <stdbool.h>
00123 #include <stdint.h>
00124 
00125 /*----------------------------------------------------------------------------
00126  *         Definitions
00127  *----------------------------------------------------------------------------*/
00128 
00129 /*- CDC */
00130 /** Size in bytes of the packet used for reading data from USB */
00131 #define DATAPACKETSIZE \
00132     CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CDCAUDD_Descriptors_DATAIN0)
00133 
00134 /** Size in bytes of the buffer used for reading data from the USB & USART */
00135 #define DATABUFFERSIZE (DATAPACKETSIZE+2)
00136 
00137 /*- Audio */
00138 /**  Number of available audio buffers. */
00139 #define BUFFER_NUMBER       500
00140 /**  Size of one buffer in bytes. */
00141 #define BUFFER_SIZE         (AUDDevice_BYTESPERFRAME)
00142 
00143 /**  Delay in ms for starting the DAC transmission
00144      after a frame has been received. */
00145 #define DAC_DELAY           2
00146 
00147 /** SSC: Number of slots in a frame */
00148 #define SLOT_BY_FRAME           (2)
00149 /** SSC: Number of bits in a slot */
00150 #define BITS_BY_SLOT            (16)
00151 #define I2S_SLAVE_TX_SETTING      ((SSC_TCMR_CKS_TK) |         \
00152                                 (SSC_TCMR_CKO_NONE) |       \
00153                                 (SSC_TCMR_START_TF_EDGE) |  \
00154                                 (SSC_TCMR_STTDLY(1)) |      \
00155                                 (SSC_TCMR_PERIOD(0)))
00156 
00157 #define I2S_SLAVE_TX_FRM_SETTING  ((SSC_TFMR_DATLEN(BITS_BY_SLOT - 1)) |  \
00158                                 (SSC_TFMR_MSBF) |                      \
00159                                 (SSC_TFMR_DATNB(SLOT_BY_FRAME - 1)) |  \
00160                                 (SSC_TFMR_FSOS_NONE))
00161 
00162 
00163 #define I2S_SLAVE_RX_SETTING       ((SSC_RCMR_CKS_TK) |         \
00164                                 (SSC_RCMR_CKO_NONE) |        \
00165                                 (SSC_RCMR_CKI) |             \
00166                                 (SSC_RCMR_START_RF_EDGE) |   \
00167                                 (SSC_RCMR_STTDLY(1)) |       \
00168                                 (SSC_RCMR_PERIOD(0)))
00169 
00170 #define I2S_SLAVE_RX_FRM_SETTING  ((SSC_RFMR_DATLEN(BITS_BY_SLOT - 1)) |  \
00171                                 (SSC_RFMR_MSBF) |                      \
00172                                 (SSC_RFMR_DATNB(SLOT_BY_FRAME - 1)) |  \
00173                                 (SSC_RFMR_FSOS_NONE))
00174 
00175 /** TWI clock */
00176 #define TWI_CLOCK               400000
00177 /** Audio sample rate */
00178 #define SAMPLE_RATE             (48000)
00179 
00180 
00181 /*----------------------------------------------------------------------------
00182  *         External variables
00183  *----------------------------------------------------------------------------*/
00184 
00185 /** Descriptor list for USB Audio SpeakerPhone Driver */
00186 extern const USBDDriverDescriptors cdcauddDriverDescriptors;
00187 
00188 /*----------------------------------------------------------------------------
00189  *         Internal variables
00190  *----------------------------------------------------------------------------*/
00191 
00192 
00193 /*- CDC */
00194 /** Buffer for storing incoming USB data. */
00195 static uint8_t usbSerialBuffer0[DATABUFFERSIZE];
00196 /** Serial port opened */
00197 static volatile uint8_t isSerialPortON = 0;
00198 
00199 /*- Audio */
00200 /**  Data buffers for receiving audio frames from the USB host. */
00201 
00202 COMPILER_ALIGNED(32) static uint8_t buffers[BUFFER_NUMBER][BUFFER_SIZE];
00203 
00204 /**  Number of samples stored in each data buffer. */
00205 static uint32_t bufferSizes[BUFFER_NUMBER];
00206 /**  Next buffer in which USB data can be stored. */
00207 static uint32_t inBufferIndex = 0;
00208 /**  Next buffer which should be sent to the DAC. */
00209 static uint32_t outBufferIndex = 0;
00210 /**  Number of buffers that can be sent to the DAC. */
00211 static volatile uint32_t numBuffersToSend = 0;
00212 
00213 /**  Current state of the DAC transmission. */
00214 static volatile uint32_t isDacActive = 0;
00215 static volatile uint32_t isFirstFrame = 1;
00216 /**  Number of buffers to wait for before the DAC starts to transmit data. */
00217 static volatile uint32_t dacDelay;
00218 
00219 /** Twi instance*/
00220 static Twid twid;
00221 /** Global DMA driver for all transfer */
00222 COMPILER_ALIGNED(32) static sXdmad dmad;
00223 /** DMA channel for TX */
00224 static uint32_t sscDmaTxChannel;
00225 
00226 /** List of pins to configure. */
00227 static const Pin pinsAudio[] = { PIN_TWI_TWD0, 
00228                                 PIN_TWI_TWCK0, 
00229                                 PIN_SSC_TD, 
00230                                 PIN_SSC_TK, 
00231                                 PIN_SSC_TF, 
00232                                 PIN_SSC_RD, 
00233                                 PIN_SSC_RK, 
00234                                 PIN_SSC_RF, 
00235                                 PIN_PCK2};
00236 
00237 /*----------------------------------------------------------------------------
00238  *         Internal functions
00239  *----------------------------------------------------------------------------*/
00240 
00241 /**
00242  * ISR for DMA interrupt
00243  */
00244 void XDMAC_Handler( void )
00245 {
00246     XDMAD_Handler( &dmad );
00247 }
00248 
00249 /**
00250  *  \brief Start DMA sending/waiting data.
00251  */
00252 static void _SscDma(volatile uint32_t *pReg, uint32_t dmaChannel, 
00253                     void* pBuffer, uint16_t wSize)
00254 {
00255     sXdmad *pDmad = &dmad;
00256     sXdmadCfg xdmadCfg;
00257     
00258      SCB_CleanInvalidateDCache();
00259     xdmadCfg.mbr_ubc = wSize ;
00260     xdmadCfg.mbr_sa = (uint32_t) pBuffer;
00261     xdmadCfg.mbr_da = (uint32_t) pReg;
00262     xdmadCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN 
00263                     | XDMAC_CC_MBSIZE_SINGLE
00264                     | XDMAC_CC_DSYNC_MEM2PER
00265                     | XDMAC_CC_CSIZE_CHK_1 
00266                     | XDMAC_CC_DWIDTH_HALFWORD 
00267                     | XDMAC_CC_SIF_AHB_IF0 
00268                     | XDMAC_CC_DIF_AHB_IF1 
00269                     | XDMAC_CC_SAM_INCREMENTED_AM
00270                     | XDMAC_CC_DAM_FIXED_AM 
00271                     | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber( ID_SSC, XDMAD_TRANSFER_TX));
00272     xdmadCfg.mbr_bc = 0;
00273     xdmadCfg.mbr_ds = 0;
00274     xdmadCfg.mbr_sus = 0;
00275     xdmadCfg.mbr_dus = 0;
00276    
00277     XDMAD_ConfigureTransfer( pDmad, dmaChannel, &xdmadCfg, 0, 0,(XDMAC_CIE_BIE   |
00278                                                             XDMAC_CIE_DIE    |
00279                                                             XDMAC_CIE_FIE    |
00280                                                             XDMAC_CIE_RBIE   |
00281                                                             XDMAC_CIE_WBIE   |
00282                                                             XDMAC_CIE_ROIE));
00283     XDMAD_StartTransfer( pDmad, dmaChannel );
00284     SSC_EnableTransmitter(SSC);
00285 }
00286 
00287 /**
00288  *  \brief DMA TX callback
00289  */
00290 static void _SscTxCallback(uint8_t status, void* pArg)
00291 {
00292     sXdmad *pDmad = &dmad;
00293     Xdmac *pXdmac = pDmad->pXdmacs;
00294     pArg = pArg; /*dummy */
00295     if (numBuffersToSend == 0) {
00296         /* End of transmission */
00297         isDacActive = 0;
00298         return;
00299     }
00300     /* Load next buffer */
00301     XDMAC_SetSourceAddr(pXdmac, sscDmaTxChannel,  (uint32_t) buffers[outBufferIndex]);
00302     XDMAC_SetMicroblockControl(pXdmac, sscDmaTxChannel, bufferSizes[outBufferIndex]);
00303     outBufferIndex = (outBufferIndex + 1) % BUFFER_NUMBER;
00304     numBuffersToSend --;
00305     XDMAD_StartTransfer( pDmad, sscDmaTxChannel );
00306 }
00307 
00308 /**
00309  * \brief DMA driver configuration
00310  */
00311 static void _ConfigureDma( void )
00312 {
00313     sXdmad *pDmad = &dmad;
00314     /* Driver initialize */
00315     XDMAD_Initialize( pDmad, 0 );
00316     /* IRQ configure */
00317     NVIC_EnableIRQ(XDMAC_IRQn);
00318 
00319     /* Allocate DMA channels for SSC */
00320     sscDmaTxChannel = XDMAD_AllocateChannel( pDmad, XDMAD_TRANSFER_MEMORY, ID_SSC);
00321     if (sscDmaTxChannel == XDMAD_ALLOC_FAILED ) {
00322         printf("xDMA channel allocation error\n\r");
00323         while(1);
00324     }
00325     /* Set TX callback */
00326     XDMAD_SetCallback(pDmad, sscDmaTxChannel,(XdmadTransferCallback)_SscTxCallback, 0);
00327     XDMAD_PrepareChannel(pDmad, sscDmaTxChannel );
00328 }
00329 
00330 /**
00331  * Enable/Disable audio speaker channels
00332  */
00333 static void AudioPlayEnable(uint8_t enable)
00334 {
00335     if (enable == 1) {
00336         SSC_EnableTransmitter(SSC);
00337     } else if (enable == 0) {
00338         SSC_DisableTransmitter(SSC);
00339     }
00340 }
00341 
00342 /**
00343  * Adjust codec for sync
00344  * \param adjust Sync case: default(0)/faster(>0)/slower(<0)
00345  */
00346 static void _SyncAdjust(int32_t adjust)
00347 {
00348     if (adjust > 0) {
00349         /* Fractional multiply for FLL_K, Fref = 0x8000 (1/2) */
00350         WM8904_Write(&twid, WM8904_SLAVE_ADDRESS, WM8904_REG_FLL_CRTL3, 0xFF00);
00351         /* FLL_GAIN=0, FLL_N=187 */
00352         return;
00353     }
00354     if (adjust < 0) {
00355         /* Fractional multiply for FLL_K, Fref = 0x8000 (1/2) */
00356         WM8904_Write(&twid, WM8904_SLAVE_ADDRESS, WM8904_REG_FLL_CRTL3, 0x5000);
00357         return;
00358     }
00359     /* Default: 32K -> 48K*256, FLL: 32768*187.5/16/8
00360      */
00361     /* FLL_FRATIO=4 (/16), FLL_OUTDIV= 7 (/8) */
00362     /* Fractional multiply for FLL_K, Fref = 0x8000 (1/2) */
00363     WM8904_Write(&twid, WM8904_SLAVE_ADDRESS, WM8904_REG_FLL_CRTL3, 0x8000 + 0x3000);
00364     /* FLL_GAIN=0, FLL_N=187 */
00365     return;
00366 }
00367 /**
00368  * Configure the TC0 and DACC, ADC for audio playback/record.
00369  * \param sampleRate Audio sample rate.
00370  * \param mck        MCK frequency.
00371  */
00372 static void _ConfigureAudioPlay(uint32_t sampleRate, uint32_t mck)
00373 {
00374     /* -- Pins Configuration -- */
00375     PIO_Configure(pinsAudio, PIO_LISTSIZE(pinsAudio));
00376 
00377     /* -- SSC Configuration -- */
00378     sampleRate = sampleRate; /*dummy */
00379     SSC_Configure(SSC,0, mck);
00380     SSC_DisableTransmitter(SSC);
00381     SSC_DisableReceiver(SSC);
00382     SSC_ConfigureTransmitter(SSC, I2S_SLAVE_TX_SETTING,I2S_SLAVE_TX_FRM_SETTING);
00383     SSC_DisableTransmitter(SSC);
00384 
00385     /* Enable TWI peripheral clock */
00386     PMC_EnablePeripheral(ID_TWIHS0);
00387     /* Configure and enable the TWI (required for accessing the DAC) */
00388     TWI_ConfigureMaster(TWIHS0, TWI_CLOCK, mck);
00389     TWID_Initialize(&twid, TWIHS0);
00390     
00391     /* Initialize the audio DAC
00392      */
00393 
00394     WM8904_Write(&twid, WM8904_SLAVE_ADDRESS, WM8904_REG_RESET, 0);
00395     Wait(100);
00396     /* WM8904 as master */
00397     if(WM8904_Read(&twid, WM8904_SLAVE_ADDRESS, 0)!=0x8904) {
00398           printf("WM8904 not found!\n\r");
00399           while(1);
00400     }
00401     WM8904_Init(&twid, WM8904_SLAVE_ADDRESS,PMC_MCKR_CSS_SLOW_CLK);
00402     _SyncAdjust(0);
00403     PMC_ConfigurePCK2(PMC_MCKR_CSS_SLOW_CLK, PMC_MCKR_PRES_CLK_1 );
00404     /* Mute */
00405     AudioPlayEnable(0);
00406 }
00407 
00408 /**
00409  *  Invoked when a frame has been received.
00410  */
00411 static void FrameReceived(uint32_t unused,
00412                         uint8_t status,
00413                         uint32_t transferred,
00414                         uint32_t remaining)
00415 {
00416     unused = unused; /*dummy */
00417     remaining = remaining; /*dummy */
00418     if (status == USBD_STATUS_SUCCESS) {
00419         /* Update input status data */
00420         bufferSizes[inBufferIndex] = transferred / AUDDevice_BYTESPERSAMPLE;
00421         inBufferIndex = (inBufferIndex + 1) % BUFFER_NUMBER;
00422         numBuffersToSend++;
00423 
00424         /* Start DAc transmission if necessary */
00425         if (!isDacActive) {
00426             dacDelay = DAC_DELAY;
00427             isDacActive = 1;
00428         }
00429         /* Wait until a few buffers have been received */
00430         else if (dacDelay > 0) {
00431             dacDelay--;
00432         }
00433         /* Start sending buffers */
00434         else if (isFirstFrame) {
00435             isFirstFrame = 0;
00436             //AudioPlayEnable(1);
00437             _SscDma(&(SSC->SSC_THR), sscDmaTxChannel, buffers[outBufferIndex], bufferSizes[outBufferIndex]);
00438             outBufferIndex = (outBufferIndex + 1) % BUFFER_NUMBER;
00439             numBuffersToSend --;
00440         }
00441     }
00442     else if (status == USBD_STATUS_ABORTED) {
00443         /* Error , ABORT, add NULL buffer */
00444         bufferSizes[inBufferIndex] = 0;
00445         } else {
00446             /* Packet is discarded */
00447         }
00448     /* Receive next packet */
00449     AUDDFunction_Read(buffers[inBufferIndex],
00450                     AUDDevice_BYTESPERFRAME,
00451                     (TransferCallback) FrameReceived,
00452                     0); // No optional argument
00453 }
00454 
00455 /**
00456  * Callback invoked when data has been received on the USB.
00457  */
00458 static void CdcDataReceived(uint32_t unused,
00459                             uint8_t status,
00460                             uint32_t received,
00461                             uint32_t remaining)
00462 {
00463     unused = unused; /*dummy */
00464     remaining = remaining; /*dummy */    
00465     /* Check that data has been received successfully */
00466     if (status == USBD_STATUS_SUCCESS) {
00467         /* Echo back */
00468         CDCDSerial_Write(usbSerialBuffer0, received, 0, 0);
00469         /* Receive next */
00470         CDCDSerial_Read(usbSerialBuffer0,
00471                         DATAPACKETSIZE,
00472                         (TransferCallback) CdcDataReceived,
00473                         0);
00474     } else {
00475         TRACE_WARNING( "CdcDataReceived: Transfer error\n\r");
00476     }
00477 }
00478 
00479 /*-------------------------------------------
00480  *      USB Device Driver callbacks
00481  *-------------------------------------------*/
00482 /**
00483  * Invoked when the configuration of the device changes. Parse used endpoints.
00484  * \param cfgnum New configuration number.
00485  */
00486 void USBDDriverCallbacks_ConfigurationChanged(uint8_t cfgnum)
00487 {
00488     CDCAUDDDriver_ConfigurationChangedHandler(cfgnum);
00489 }
00490 
00491 /**
00492  * Invoked whenever the active setting of an interface is changed by the
00493  * host. Reset streaming interface.
00494  * \param interface Interface number.
00495  * \param setting Newly active setting.
00496  */
00497 void USBDDriverCallbacks_InterfaceSettingChanged(uint8_t interface,
00498                                              uint8_t setting)
00499 {
00500     CDCAUDDDriver_InterfaceSettingChangedHandler(interface, setting);
00501 }
00502 
00503 /**
00504  *  Invoked whenever a SETUP request is received from the host. Forwards the
00505  *  request to the standard handler.
00506  */
00507 void USBDCallbacks_RequestReceived(const USBGenericRequest *request)
00508 {
00509     CDCAUDDDriver_RequestHandler(request);
00510 }
00511 
00512 /*-------------------------------------------
00513  *      USB Function driver callbacks
00514  *-------------------------------------------*/
00515 
00516 /**
00517  * Invoked when the CDC ControlLineState is changed
00518  * \param DTR   New DTR value.
00519  * \param RTS   New RTS value.
00520  */
00521 void CDCDSerial_ControlLineStateChanged(uint8_t DTR,
00522                                     uint8_t RTS)
00523 {
00524     isSerialPortON = DTR;
00525     RTS = RTS; /* dummy */
00526 }
00527 
00528 /**
00529  *  Invoked when an audio channel get muted or unmuted. Mute/unmute the
00530  *  channel at the DAC level.
00531  *  \param mic      Microphone/Speaker stream changed.
00532  *  \param channel  Channel number that changed.
00533  *  \param muted    Indicates the new mute status of the channel.
00534  */
00535 void AUDDFunction_MuteChanged(uint8_t mic,
00536                             uint8_t channel,
00537                             uint8_t muted)
00538 {
00539     //printf("m%d,%d,%d ", mic, channel, muted);
00540     if (mic) return;
00541 
00542     /* Speaker Master channel */
00543     if (channel == AUDD_CH_Master) {
00544         if (muted) {
00545             AudioPlayEnable(0);
00546             TRACE_WARNING("MuteMaster ");
00547         } else {
00548             TRACE_INFO("UnmuteMaster ");
00549             AudioPlayEnable(1);
00550         }
00551     }
00552 }
00553 
00554 /**
00555  *  Invoked when an audio streaming interface setting changed.
00556  *  Audio stream is automatically rosetted.
00557  *  Actually control streaming rate.
00558  *  \param mic         Microphone/Speaker stream changed.
00559  *  \param newSetting  New stream (interface) setting.
00560  */
00561 void AUDDFunction_StreamSettingChanged(uint8_t mic,
00562                                     uint8_t newSetting)
00563 {
00564     /* Speaker stream */
00565     mic = mic; /* dummy */
00566     if (newSetting) {
00567         LED_Set(LED_YELLOW0);
00568         //XDMAD_StopTransfer(&dmad, sscDmaTxChannel);
00569         numBuffersToSend = 0;
00570     }
00571     else LED_Clear(LED_YELLOW0);
00572 }
00573 
00574 /**
00575  * Configure USB settings for USB device
00576  */
00577 static void _ConfigureUsbhs(void)
00578 {
00579     /* UTMI parallel mode, High/Full/Low Speed */
00580     /* UUSBCK not used in this configuration (High Speed) */
00581     PMC->PMC_SCDR = PMC_SCDR_USBCLK;
00582     /* USB clock register: USB Clock Input is UTMI PLL */
00583     PMC->PMC_USB = PMC_USB_USBS;
00584     /* Enable peripheral clock for USBHS */
00585     PMC_EnablePeripheral(ID_USBHS);    
00586     USBHS->USBHS_CTRL = USBHS_CTRL_UIMOD_DEVICE;
00587     /* Enable PLL 480 MHz */
00588     PMC->CKGR_UCKR = CKGR_UCKR_UPLLEN | CKGR_UCKR_UPLLCOUNT(0xF);
00589     /* Wait that PLL is considered locked by the PMC */
00590     while( !(PMC->PMC_SR & PMC_SR_LOCKU) );
00591     /* IRQ */
00592     NVIC_EnableIRQ(USBHS_IRQn) ;
00593 }
00594 /*----------------------------------------------------------------------------
00595  *         Exported functions
00596  *----------------------------------------------------------------------------*/
00597 
00598 /**
00599  *  \brief usb_iad_cdc_aud Application entry point.
00600  *
00601  *  Starts the driver and
00602  *  - waits for an audio input stream to forward to the DAC.
00603  *  - waits for a cdc serial input to forward to cdc output (echo).
00604  */
00605 int main(void)
00606 {
00607     volatile uint8_t usbConn = 0;
00608     volatile uint8_t audioOn = 0;
00609     volatile uint8_t serialOn = 0;
00610     volatile uint32_t num = 0;
00611     int32_t  numDiff = 0, prevDiff = 0;
00612     int8_t   clockAdjust = 0;
00613 
00614     /* Disable watchdog */
00615     WDT_Disable( WDT );
00616 
00617     SCB_EnableICache();
00618     SCB_EnableDCache();
00619 
00620     printf("-- USB CDC + Audio Device Example %s --\n\r", SOFTPACK_VERSION);
00621     printf("-- %s\n\r", BOARD_NAME);
00622     printf( "-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__ , COMPILER_NAME) ;
00623 
00624     TimeTick_Configure();
00625     /* Interrupt priority */
00626     NVIC_SetPriority( USBHS_IRQn, 2 );
00627     
00628     /* If they are present, configure Vbus & Wake-up pins */
00629     PIO_InitializeInterrupts(0);
00630 
00631     /* Initialize all USB power (off) */
00632     _ConfigureUsbhs();
00633 
00634     /* Audio STREAM LED */
00635     LED_Configure(LED_YELLOW0);
00636 
00637     /* Configure Audio */
00638     _ConfigureAudioPlay(AUDDevice_SAMPLERATE, BOARD_MCK);
00639     _ConfigureDma();
00640 
00641     /* USB audio driver initialization */
00642     CDCAUDDDriver_Initialize(&cdcauddDriverDescriptors);
00643     /* connect if needed */
00644     USBD_Connect();
00645 
00646     /* Infinite loop */
00647     while (1) {
00648         if (USBD_GetState() < USBD_STATE_CONFIGURED) {
00649             usbConn = 0;
00650             continue;
00651         }
00652         if (audioOn) {
00653             if(isDacActive == 0) {
00654                 AudioPlayEnable(0);
00655                 printf("audE ");
00656                 isFirstFrame = 1;
00657                 audioOn = 0;
00658             } else {
00659                 if (num != numBuffersToSend) {
00660                     num = numBuffersToSend;
00661                 }
00662                 numDiff = numBuffersToSend - DAC_DELAY;
00663                 if (prevDiff != numDiff) {
00664                     prevDiff = numDiff;
00665                     if (numDiff > 0 && clockAdjust != 1) {
00666                       printf("+");
00667                         /* USB too fast or SSC too slow: faster clock */
00668                         clockAdjust = 1;
00669                         _SyncAdjust(1);
00670                     }
00671                     if (numDiff < 0 && clockAdjust != -1) {
00672                       printf("-");
00673                         /* USB too slow or SSC too fast: slower clock */
00674                         clockAdjust = -1;
00675                         _SyncAdjust(-1);
00676                     }
00677                     if (numDiff == 0 && clockAdjust != 0) {
00678                         clockAdjust = 0;
00679                         _SyncAdjust(0);
00680                     }
00681                 }
00682             }
00683         } else if (isDacActive) {
00684             printf("audS ");
00685             audioOn = 1;
00686         }
00687         if (usbConn == 0) {
00688             usbConn = 1;
00689             /* Start Reading the incoming audio stream */
00690             AUDDFunction_Read(buffers[inBufferIndex],
00691                               AUDDevice_BYTESPERFRAME,
00692                               (TransferCallback) FrameReceived,
00693                               0); // No optional argument
00694         }
00695 
00696         if (!serialOn && isSerialPortON) {
00697             printf("-I- SerialPort ON\n\r");
00698             /* Start receiving data on the USB */
00699             CDCDSerial_Read(usbSerialBuffer0,
00700                             DATAPACKETSIZE,
00701                             (TransferCallback) CdcDataReceived,
00702                             0);
00703             serialOn = 1;
00704         } else if (serialOn && !isSerialPortON) {
00705             printf("-I- SeriaoPort OFF\n\r");
00706             serialOn = 0;
00707         }
00708     }
00709 }
00710 /** \endcond */
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines