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