SAMV71 Xplained Ultra Software Package 1.3

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     if (status != XDMAD_OK) return;
00295     pArg = pArg; /*dummy */
00296     if (numBuffersToSend == 0) {
00297         /* End of transmission */
00298         isDacActive = 0;
00299         return;
00300     }
00301     /* Load next buffer */
00302     XDMAC_SetSourceAddr(pXdmac, sscDmaTxChannel,  (uint32_t) buffers[outBufferIndex]);
00303     XDMAC_SetMicroblockControl(pXdmac, sscDmaTxChannel, bufferSizes[outBufferIndex]);
00304     outBufferIndex = (outBufferIndex + 1) % BUFFER_NUMBER;
00305     numBuffersToSend --;
00306     XDMAD_StartTransfer( pDmad, sscDmaTxChannel );
00307 }
00308 
00309 /**
00310  * \brief DMA driver configuration
00311  */
00312 static void _ConfigureDma( void )
00313 {
00314     sXdmad *pDmad = &dmad;
00315     /* Driver initialize */
00316     XDMAD_Initialize( pDmad, 0 );
00317     /* IRQ configure */
00318     NVIC_EnableIRQ(XDMAC_IRQn);
00319 
00320     /* Allocate DMA channels for SSC */
00321     sscDmaTxChannel = XDMAD_AllocateChannel( pDmad, XDMAD_TRANSFER_MEMORY, ID_SSC);
00322     if (sscDmaTxChannel == XDMAD_ALLOC_FAILED ) {
00323         printf("xDMA channel allocation error\n\r");
00324         while(1);
00325     }
00326     /* Set TX callback */
00327     XDMAD_SetCallback(pDmad, sscDmaTxChannel,(XdmadTransferCallback)_SscTxCallback, 0);
00328     XDMAD_PrepareChannel(pDmad, sscDmaTxChannel );
00329 }
00330 
00331 /**
00332  * Enable/Disable audio speaker channels
00333  */
00334 static void AudioPlayEnable(uint8_t enable)
00335 {
00336     if (enable == 1) {
00337         SSC_EnableTransmitter(SSC);
00338     } else if (enable == 0) {
00339         SSC_DisableTransmitter(SSC);
00340     }
00341 }
00342 
00343 /**
00344  * Adjust codec for sync
00345  * \param adjust Sync case: default(0)/faster(>0)/slower(<0)
00346  */
00347 static void _SyncAdjust(int32_t adjust)
00348 {
00349     if (adjust > 0) {
00350         /* Fractional multiply for FLL_K, Fref = 0x8000 (1/2) */
00351         WM8904_Write(&twid, WM8904_SLAVE_ADDRESS, WM8904_REG_FLL_CRTL3, 0xFF00);
00352         /* FLL_GAIN=0, FLL_N=187 */
00353         return;
00354     }
00355     if (adjust < 0) {
00356         /* Fractional multiply for FLL_K, Fref = 0x8000 (1/2) */
00357         WM8904_Write(&twid, WM8904_SLAVE_ADDRESS, WM8904_REG_FLL_CRTL3, 0x5000);
00358         return;
00359     }
00360     /* Default: 32K -> 48K*256, FLL: 32768*187.5/16/8
00361      */
00362     /* FLL_FRATIO=4 (/16), FLL_OUTDIV= 7 (/8) */
00363     /* Fractional multiply for FLL_K, Fref = 0x8000 (1/2) */
00364     WM8904_Write(&twid, WM8904_SLAVE_ADDRESS, WM8904_REG_FLL_CRTL3, 0x8000 + 0x3000);
00365     /* FLL_GAIN=0, FLL_N=187 */
00366     return;
00367 }
00368 /**
00369  * Configure the TC0 and DACC, ADC for audio playback/record.
00370  * \param sampleRate Audio sample rate.
00371  * \param mck        MCK frequency.
00372  */
00373 static void _ConfigureAudioPlay(uint32_t sampleRate, uint32_t mck)
00374 {
00375     /* -- Pins Configuration -- */
00376     PIO_Configure(pinsAudio, PIO_LISTSIZE(pinsAudio));
00377 
00378     /* -- SSC Configuration -- */
00379     sampleRate = sampleRate; /*dummy */
00380     SSC_Configure(SSC,0, mck);
00381     SSC_DisableTransmitter(SSC);
00382     SSC_DisableReceiver(SSC);
00383     SSC_ConfigureTransmitter(SSC, I2S_SLAVE_TX_SETTING,I2S_SLAVE_TX_FRM_SETTING);
00384     SSC_DisableTransmitter(SSC);
00385 
00386     /* Enable TWI peripheral clock */
00387     PMC_EnablePeripheral(ID_TWIHS0);
00388     /* Configure and enable the TWI (required for accessing the DAC) */
00389     TWI_ConfigureMaster(TWIHS0, TWI_CLOCK, mck);
00390     TWID_Initialize(&twid, TWIHS0);
00391     
00392     /* Initialize the audio DAC
00393      */
00394 
00395     WM8904_Write(&twid, WM8904_SLAVE_ADDRESS, WM8904_REG_RESET, 0);
00396     Wait(100);
00397     /* WM8904 as master */
00398     if(WM8904_Read(&twid, WM8904_SLAVE_ADDRESS, 0)!=0x8904) {
00399           printf("WM8904 not found!\n\r");
00400           while(1);
00401     }
00402     WM8904_Init(&twid, WM8904_SLAVE_ADDRESS,PMC_MCKR_CSS_SLOW_CLK);
00403     _SyncAdjust(0);
00404     PMC_ConfigurePCK2(PMC_MCKR_CSS_SLOW_CLK, PMC_MCKR_PRES_CLK_1 );
00405     /* Mute */
00406     AudioPlayEnable(0);
00407 }
00408 
00409 /**
00410  *  Invoked when a frame has been received.
00411  */
00412 static void FrameReceived(uint32_t unused,
00413                         uint8_t status,
00414                         uint32_t transferred,
00415                         uint32_t remaining)
00416 {
00417     unused = unused; /*dummy */
00418     remaining = remaining; /*dummy */
00419     if (status == USBD_STATUS_SUCCESS) {
00420         /* Update input status data */
00421         bufferSizes[inBufferIndex] = transferred / AUDDevice_BYTESPERSAMPLE;
00422         inBufferIndex = (inBufferIndex + 1) % BUFFER_NUMBER;
00423         numBuffersToSend++;
00424 
00425         /* Start DAc transmission if necessary */
00426         if (!isDacActive) {
00427             dacDelay = DAC_DELAY;
00428             isDacActive = 1;
00429         }
00430         /* Wait until a few buffers have been received */
00431         else if (dacDelay > 0) {
00432             dacDelay--;
00433         }
00434         /* Start sending buffers */
00435         else if (isFirstFrame) {
00436             isFirstFrame = 0;
00437             //AudioPlayEnable(1);
00438             _SscDma(&(SSC->SSC_THR), sscDmaTxChannel, buffers[outBufferIndex], bufferSizes[outBufferIndex]);
00439             outBufferIndex = (outBufferIndex + 1) % BUFFER_NUMBER;
00440             numBuffersToSend --;
00441         }
00442     }
00443     else if (status == USBD_STATUS_ABORTED) {
00444         /* Error , ABORT, add NULL buffer */
00445         bufferSizes[inBufferIndex] = 0;
00446         } else {
00447             /* Packet is discarded */
00448         }
00449     /* Receive next packet */
00450     AUDDFunction_Read(buffers[inBufferIndex],
00451                     AUDDevice_BYTESPERFRAME,
00452                     (TransferCallback) FrameReceived,
00453                     0); // No optional argument
00454 }
00455 
00456 /**
00457  * Callback invoked when data has been received on the USB.
00458  */
00459 static void CdcDataReceived(uint32_t unused,
00460                             uint8_t status,
00461                             uint32_t received,
00462                             uint32_t remaining)
00463 {
00464     unused = unused; /*dummy */
00465     remaining = remaining; /*dummy */    
00466     /* Check that data has been received successfully */
00467     if (status == USBD_STATUS_SUCCESS) {
00468         /* Echo back */
00469         CDCDSerial_Write(usbSerialBuffer0, received, 0, 0);
00470         /* Receive next */
00471         CDCDSerial_Read(usbSerialBuffer0,
00472                         DATAPACKETSIZE,
00473                         (TransferCallback) CdcDataReceived,
00474                         0);
00475     } else {
00476         TRACE_WARNING( "CdcDataReceived: Transfer error\n\r");
00477     }
00478 }
00479 
00480 /*-------------------------------------------
00481  *      USB Device Driver callbacks
00482  *-------------------------------------------*/
00483 /**
00484  * Invoked when the configuration of the device changes. Parse used endpoints.
00485  * \param cfgnum New configuration number.
00486  */
00487 void USBDDriverCallbacks_ConfigurationChanged(uint8_t cfgnum)
00488 {
00489     CDCAUDDDriver_ConfigurationChangedHandler(cfgnum);
00490 }
00491 
00492 /**
00493  * Invoked whenever the active setting of an interface is changed by the
00494  * host. Reset streaming interface.
00495  * \param interface Interface number.
00496  * \param setting Newly active setting.
00497  */
00498 void USBDDriverCallbacks_InterfaceSettingChanged(uint8_t interface,
00499                                              uint8_t setting)
00500 {
00501     CDCAUDDDriver_InterfaceSettingChangedHandler(interface, setting);
00502 }
00503 
00504 /**
00505  *  Invoked whenever a SETUP request is received from the host. Forwards the
00506  *  request to the standard handler.
00507  */
00508 void USBDCallbacks_RequestReceived(const USBGenericRequest *request)
00509 {
00510     CDCAUDDDriver_RequestHandler(request);
00511 }
00512 
00513 /*-------------------------------------------
00514  *      USB Function driver callbacks
00515  *-------------------------------------------*/
00516 
00517 /**
00518  * Invoked when the CDC ControlLineState is changed
00519  * \param DTR   New DTR value.
00520  * \param RTS   New RTS value.
00521  */
00522 void CDCDSerial_ControlLineStateChanged(uint8_t DTR,
00523                                     uint8_t RTS)
00524 {
00525     isSerialPortON = DTR;
00526     RTS = RTS; /* dummy */
00527 }
00528 
00529 /**
00530  *  Invoked when an audio channel get muted or unmuted. Mute/unmute the
00531  *  channel at the DAC level.
00532  *  \param mic      Microphone/Speaker stream changed.
00533  *  \param channel  Channel number that changed.
00534  *  \param muted    Indicates the new mute status of the channel.
00535  */
00536 void AUDDFunction_MuteChanged(uint8_t mic,
00537                             uint8_t channel,
00538                             uint8_t muted)
00539 {
00540     //printf("m%d,%d,%d ", mic, channel, muted);
00541     if (mic) return;
00542 
00543     /* Speaker Master channel */
00544     if (channel == AUDD_CH_Master) {
00545         if (muted) {
00546             AudioPlayEnable(0);
00547             TRACE_WARNING("MuteMaster ");
00548         } else {
00549             TRACE_INFO("UnmuteMaster ");
00550             AudioPlayEnable(1);
00551         }
00552     }
00553 }
00554 
00555 /**
00556  *  Invoked when an audio streaming interface setting changed.
00557  *  Audio stream is automatically rosetted.
00558  *  Actually control streaming rate.
00559  *  \param mic         Microphone/Speaker stream changed.
00560  *  \param newSetting  New stream (interface) setting.
00561  */
00562 void AUDDFunction_StreamSettingChanged(uint8_t mic,
00563                                     uint8_t newSetting)
00564 {
00565     /* Speaker stream */
00566     mic = mic; /* dummy */
00567     if (newSetting) {
00568         LED_Set(LED_YELLOW0);
00569         //XDMAD_StopTransfer(&dmad, sscDmaTxChannel);
00570         numBuffersToSend = 0;
00571     }
00572     else LED_Clear(LED_YELLOW0);
00573 }
00574 
00575 /**
00576  * Configure USB settings for USB device
00577  */
00578 static void _ConfigureUsbhs(void)
00579 {
00580     /* UTMI parallel mode, High/Full/Low Speed */
00581     /* UUSBCK not used in this configuration (High Speed) */
00582     PMC->PMC_SCDR = PMC_SCDR_USBCLK;
00583     /* USB clock register: USB Clock Input is UTMI PLL */
00584     PMC->PMC_USB = PMC_USB_USBS;
00585     /* Enable peripheral clock for USBHS */
00586     PMC_EnablePeripheral(ID_USBHS);    
00587     USBHS->USBHS_CTRL = USBHS_CTRL_UIMOD_DEVICE;
00588     /* Enable PLL 480 MHz */
00589     PMC->CKGR_UCKR = CKGR_UCKR_UPLLEN | CKGR_UCKR_UPLLCOUNT(0xF);
00590     /* Wait that PLL is considered locked by the PMC */
00591     while( !(PMC->PMC_SR & PMC_SR_LOCKU) );
00592     /* IRQ */
00593     NVIC_EnableIRQ(USBHS_IRQn) ;
00594 }
00595 /*----------------------------------------------------------------------------
00596  *         Exported functions
00597  *----------------------------------------------------------------------------*/
00598 
00599 /**
00600  *  \brief usb_iad_cdc_aud Application entry point.
00601  *
00602  *  Starts the driver and
00603  *  - waits for an audio input stream to forward to the DAC.
00604  *  - waits for a cdc serial input to forward to cdc output (echo).
00605  */
00606 int main(void)
00607 {
00608     volatile uint8_t usbConn = 0;
00609     volatile uint8_t audioOn = 0;
00610     volatile uint8_t serialOn = 0;
00611     volatile uint32_t num = 0;
00612     int32_t  numDiff = 0, prevDiff = 0;
00613     int8_t   clockAdjust = 0;
00614 
00615     /* Disable watchdog */
00616     WDT_Disable( WDT );
00617 
00618     SCB_EnableICache();
00619     SCB_EnableDCache();
00620 
00621     printf("-- USB CDC + Audio Device Example %s --\n\r", SOFTPACK_VERSION);
00622     printf("-- %s\n\r", BOARD_NAME);
00623     printf( "-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__ , COMPILER_NAME) ;
00624 
00625     TimeTick_Configure();
00626     /* Interrupt priority */
00627     NVIC_SetPriority( USBHS_IRQn, 2 );
00628     
00629     /* If they are present, configure Vbus & Wake-up pins */
00630     PIO_InitializeInterrupts(0);
00631 
00632     /* Initialize all USB power (off) */
00633     _ConfigureUsbhs();
00634 
00635     /* Audio STREAM LED */
00636     LED_Configure(LED_YELLOW0);
00637 
00638     /* Configure Audio */
00639     _ConfigureAudioPlay(AUDDevice_SAMPLERATE, BOARD_MCK);
00640     _ConfigureDma();
00641 
00642     /* USB audio driver initialization */
00643     CDCAUDDDriver_Initialize(&cdcauddDriverDescriptors);
00644     /* connect if needed */
00645     USBD_Connect();
00646 
00647     /* Infinite loop */
00648     while (1) {
00649         if (USBD_GetState() < USBD_STATE_CONFIGURED) {
00650             usbConn = 0;
00651             continue;
00652         }
00653         if (audioOn) {
00654             if(isDacActive == 0) {
00655                 AudioPlayEnable(0);
00656                 printf("audE ");
00657                 isFirstFrame = 1;
00658                 audioOn = 0;
00659             } else {
00660                 if (num != numBuffersToSend) {
00661                     num = numBuffersToSend;
00662                 }
00663                 numDiff = numBuffersToSend - DAC_DELAY;
00664                 if (prevDiff != numDiff) {
00665                     prevDiff = numDiff;
00666                     if (numDiff > 0 && clockAdjust != 1) {
00667                       printf("+");
00668                         /* USB too fast or SSC too slow: faster clock */
00669                         clockAdjust = 1;
00670                         _SyncAdjust(1);
00671                     }
00672                     if (numDiff < 0 && clockAdjust != -1) {
00673                       printf("-");
00674                         /* USB too slow or SSC too fast: slower clock */
00675                         clockAdjust = -1;
00676                         _SyncAdjust(-1);
00677                     }
00678                     if (numDiff == 0 && clockAdjust != 0) {
00679                         clockAdjust = 0;
00680                         _SyncAdjust(0);
00681                     }
00682                 }
00683             }
00684         } else if (isDacActive) {
00685             printf("audS ");
00686             audioOn = 1;
00687         }
00688         if (usbConn == 0) {
00689             usbConn = 1;
00690             /* Start Reading the incoming audio stream */
00691             AUDDFunction_Read(buffers[inBufferIndex],
00692                               AUDDevice_BYTESPERFRAME,
00693                               (TransferCallback) FrameReceived,
00694                               0); // No optional argument
00695         }
00696 
00697         if (!serialOn && isSerialPortON) {
00698             printf("-I- SerialPort ON\n\r");
00699             /* Start receiving data on the USB */
00700             CDCDSerial_Read(usbSerialBuffer0,
00701                             DATAPACKETSIZE,
00702                             (TransferCallback) CdcDataReceived,
00703                             0);
00704             serialOn = 1;
00705         } else if (serialOn && !isSerialPortON) {
00706             printf("-I- SeriaoPort OFF\n\r");
00707             serialOn = 0;
00708         }
00709     }
00710 }
00711 /** \endcond */
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines