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_cdc
00030  * \page usb_iad_cdc_cdc USB DUAL CDC Serial Port Example
00031  *
00032  * \section Purpose
00033  *
00034  * The USB DUALCDC Project will help you to get familiar with the
00035  * USB Device Port(UDP)interface . Also it can help you to be familiar 
00036  * with the USB Framework that is used for rapid development of USB-compliant class
00037  * drivers such as USB Communication Device class (CDC), and how to combine
00038  * two USB functions to a single composite device (such as Dual CDC port).
00039  *
00040  * \section Requirements
00041  *
00042  * This package can be used with some of Atmel Xplained board that have UDP
00043  * interface, depending on the functions included.
00044  *
00045  *  \section win_drv_update Windows Driver Update
00046  *
00047  * The composite device is generally supported by Microsoft windows, but some
00048  * patches are needed for muti-interface functions such as CDC & Audio.
00049  *
00050  * \section Description
00051  *
00052  * This demo simulates 2 USB to RS-232 Serial Port Converter.
00053  *
00054  * When the board running this program connected to a host (PC for example), with
00055  * USB cable, host will notice the attachment of a USB device. No device
00056  * driver offered for the device now.
00057  *
00058  * \section Usage
00059  *
00060  *  -# Build the program and download it inside the SAM V71 Xplained Ultra board. 
00061  *     Please refer to the Getting Started with SAM V71 Microcontrollers.pdf
00062  * -# On the computer, open and configure a terminal application
00063  *    (e.g. HyperTerminal on Microsoft Windows) with these settings:
00064  *   - 115200 bauds
00065  *   - 8 bits of data
00066  *   - No parity
00067  *   - 1 stop bit
00068  *   - No flow control
00069  * -# Start the application.
00070  * -# In the terminal window, the following text should appear:
00071  *     \code
00072  *     -- USB Dual CDC Device Project xxx --
00073  *     -- SAMxxxxx-xx
00074  *     -- Compiled: xxx xx xxxx xx:xx:xx --
00075  *     \endcode
00076  * -# When connecting USB cable to windows, the host reports a new USB device 
00077  *  attachment.
00078  * -# You can use the inf file
00079  *    libraries\\usb\\device\\composite\\drv\\CompositeCDCSerial.inf
00080  *    to install the serial  port. Then new
00081  *    "AT91 USB to Serial Converter (COMx)" appears in the
00082  *    hardware device list.
00083  * -# You can run hyperterminal to send data to the port. And it can be seen
00084  *    at the other hyperterminal connected to the USART port of the board or
00085  *    another USB serial port.
00086  *
00087  * \section References
00088  * - usb_iad_cdc_cdc/main.c
00089  * - pio: Pin configurations and peripheral configure.
00090  * - usb: USB Device Framework, USB CDC driver and UDP interface driver
00091  *    - \ref usbd_framework
00092  *        - \ref usbd_api
00093  *    - \ref usbd_composite "composite"
00094  *       - \ref usbd_composite_drv
00095  *    - \ref usbd_cdc "cdc-serial"
00096  *       - \ref usbd_cdc_serial_drv
00097  * - projects:
00098  *    - \ref usb_cdc_serial
00099  *
00100  */
00101 
00102 /**
00103  * \file
00104  *
00105  * This file contains all the specific code for the
00106  * usb_iad_cdc_cdc
00107  *
00108  */
00109 
00110 /*----------------------------------------------------------------------------
00111  *        Headers
00112  *----------------------------------------------------------------------------*/
00113 
00114 #include "board.h"
00115 
00116 #include <USBD_Config.h>
00117 
00118 #include <DUALCDCDDriver.h>
00119 
00120 #include <string.h>
00121 #include <stdbool.h>
00122 #include <stdint.h>
00123 #include <stdio.h>
00124 
00125 /*---------------------------------------------------------------------------
00126  *      Definitions
00127  *---------------------------------------------------------------------------*/
00128 
00129 /** Size in bytes of the packet used for reading data from USB */
00130 #define DATAPACKETSIZE \
00131     CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CDCDSerialDriverDescriptors_DATAIN)
00132 
00133 /** Size in bytes of the buffer used for reading data from the USB & USART */
00134 #define DATABUFFERSIZE (DATAPACKETSIZE+2)
00135 
00136 /** Pins used for USART transfer */
00137 #define PINS_USART      PIN_USART1_TXD, PIN_USART1_RXD
00138 /** Register base for USART operation */
00139 #define BASE_USART      USART1
00140 /** USART ID */
00141 #define ID_USART        ID_USART1
00142 
00143 /*----------------------------------------------------------------------------
00144  *      External variables
00145  *----------------------------------------------------------------------------*/
00146 
00147 extern const USBDDriverDescriptors dualcdcdDriverDescriptors;
00148 
00149 /*---------------------------------------------------------------------------
00150  *      Internal variables
00151  *---------------------------------------------------------------------------*/
00152 
00153 /** Global DMA driver for all transfer */
00154 static sXdmad dmad;
00155 
00156 /** DMA channel for RX */
00157 static uint32_t usartDmaRxChannel;
00158 /** DMA channel for TX */
00159 static uint32_t usartDmaTxChannel;
00160 
00161 /** USART link list for data RX */
00162 static LinkedListDescriporView1 dmaRxLinkList[2];
00163 
00164 /*- CDC */
00165 /** List of pins that must be configured for use by the application. */
00166 static const Pin pinsUsart[] = {PINS_USART};
00167 
00168 /** Double-buffer for storing incoming USART data. */
00169 static uint8_t usartBuffers[2][DATABUFFERSIZE];
00170 
00171 /** Current USART buffer index. */
00172 static uint8_t usartCurrentBuffer = 0;
00173 
00174 /** Buffer for storing incoming USB data for serial port 0. */
00175 static uint8_t usbSerialBuffer0[DATABUFFERSIZE];
00176 /** Buffer for storing incoming USB data for serial port 1. */
00177 static uint8_t usbSerialBuffer1[DATABUFFERSIZE];
00178 
00179 /** Usart opened */
00180 static uint8_t isUsartON = 0;
00181 /** Serial port 0 opened */
00182 static uint8_t isSerialPort0ON = 0;
00183 /** Serial port 1 opened */
00184 static uint8_t isSerialPort1ON = 0;
00185 
00186 
00187 
00188 /*-----------------------------------------------------------------------------
00189  *         Callback re-implementation
00190  *-----------------------------------------------------------------------------*/
00191 /**
00192  * Invoked when the configuration of the device changes. Parse used endpoints.
00193  * \param cfgnum New configuration number.
00194  */
00195 void USBDDriverCallbacks_ConfigurationChanged(uint8_t cfgnum)
00196 {
00197     DUALCDCDDriver_ConfigurationChangeHandler(cfgnum);
00198 }
00199 
00200 /**
00201  * Invoked when a new SETUP request is received from the host. Forwards the
00202  * request to the Mass Storage device driver handler function.
00203  * \param request  Pointer to a USBGenericRequest instance.
00204  */
00205 void USBDCallbacks_RequestReceived(const USBGenericRequest *request)
00206 {
00207     DUALCDCDDriver_RequestHandler(request);
00208 }
00209 
00210 /*----------------------------------------------------------------------------
00211  *         Internal functions
00212  *---------------------------------------------------------------------------*/
00213 
00214 /**
00215  * ISR for xDMA interrupt
00216  */
00217 void XDMAC_Handler(void)
00218 {
00219     XDMAD_Handler(&dmad);
00220 }
00221 
00222 /**
00223  *  \brief Send single buffer data through xDMA
00224  */
00225 static void _UsartDmaTx( uint32_t dwDestAddr, void* pBuffer, uint16_t wSize )
00226 {
00227     sXdmad *pDmad = &dmad;
00228     /* Setup transfer */
00229     sXdmadCfg xdmadCfg;
00230     xdmadCfg.mbr_ubc = wSize ;
00231     xdmadCfg.mbr_sa = (uint32_t) pBuffer;
00232     xdmadCfg.mbr_da = (uint32_t) dwDestAddr;
00233     xdmadCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN 
00234                     | XDMAC_CC_MEMSET_NORMAL_MODE 
00235                     | XDMAC_CC_CSIZE_CHK_1 
00236                     | XDMAC_CC_DWIDTH_BYTE
00237                     | XDMAC_CC_SIF_AHB_IF0 
00238                     | XDMAC_CC_DIF_AHB_IF1 
00239                     | XDMAC_CC_SAM_INCREMENTED_AM 
00240                     | XDMAC_CC_DAM_FIXED_AM
00241                     | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber(
00242                         ID_USART, XDMAD_TRANSFER_TX ));
00243     xdmadCfg.mbr_bc = 0;
00244     XDMAD_ConfigureTransfer( pDmad, usartDmaTxChannel, &xdmadCfg, 0, 0, (
00245                                 XDMAC_CIE_BIE   |
00246                                 XDMAC_CIE_DIE   |
00247                                 XDMAC_CIE_FIE   |
00248                                 XDMAC_CIE_RBIE  |
00249                                 XDMAC_CIE_WBIE  |
00250                                 XDMAC_CIE_ROIE));
00251     XDMAD_StartTransfer( pDmad, usartDmaTxChannel );
00252 }
00253 
00254 /**
00255  *  \brief Prepare link list for USART RX
00256  *  Ringed link list initialized for 2 USART buffer.
00257  */
00258 static void _UsartDmaRxSetup( void )
00259 {
00260     uint8_t i;
00261     Usart *pUs = BASE_USART;
00262     for (i = 0; i < 2; i++) {
00263         dmaRxLinkList[i].mbr_ubc = XDMA_UBC_NVIEW_NDV1 
00264                                 | XDMA_UBC_NDE_FETCH_EN
00265                                 | XDMA_UBC_NSEN_UPDATED 
00266                                 | XDMAC_CUBC_UBLEN(DATAPACKETSIZE);
00267         dmaRxLinkList[i].mbr_sa  = (uint32_t)&pUs->US_RHR;
00268         dmaRxLinkList[i].mbr_da = (uint32_t)usartBuffers[i];
00269         dmaRxLinkList[i].mbr_nda = (uint32_t)&dmaRxLinkList[i];
00270     }
00271 }
00272 
00273 /**
00274  *  \brief Start waiting USART data
00275  *  Start DMA, the 1st DMA buffer is free USART buffer assigned.
00276  */
00277 static void _UsartDmaRx( uint32_t startBuffer )
00278 {
00279     sXdmad *pDmad = &dmad;
00280     sXdmadCfg xdmadUsartRxCfg;
00281     uint32_t xdmaUsartRxCndc;
00282     xdmadUsartRxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN 
00283                             | XDMAC_CC_MBSIZE_SINGLE 
00284                             | XDMAC_CC_DSYNC_PER2MEM 
00285                             | XDMAC_CC_CSIZE_CHK_1 
00286                             | XDMAC_CC_DWIDTH_BYTE
00287                             | XDMAC_CC_SIF_AHB_IF1 
00288                             | XDMAC_CC_DIF_AHB_IF0 
00289                             | XDMAC_CC_SAM_FIXED_AM 
00290                             | XDMAC_CC_DAM_INCREMENTED_AM 
00291                             | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber( 
00292                                 ID_USART, XDMAD_TRANSFER_RX ));
00293     xdmaUsartRxCndc = XDMAC_CNDC_NDVIEW_NDV1 
00294                     | XDMAC_CNDC_NDE_DSCR_FETCH_EN 
00295                     | XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED
00296                     | XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED ;
00297     XDMAD_ConfigureTransfer( pDmad, usartDmaRxChannel, &xdmadUsartRxCfg, 
00298             xdmaUsartRxCndc, (uint32_t)&dmaRxLinkList[startBuffer],XDMAC_CIE_LIE);
00299     XDMAD_StartTransfer(pDmad, usartDmaRxChannel);
00300 }
00301 
00302 /**
00303  * Handles interrupts coming from Timer #0.
00304  */
00305 void TC0_Handler(void)
00306 {
00307     Tc *pTc0 = TC0;
00308     sXdmad *pDmad = &dmad;
00309     uint8_t size;
00310     uint32_t nextBuffer = 1 - usartCurrentBuffer;
00311     uint32_t dmaChannel = usartDmaRxChannel;
00312     uint8_t iController = (dmaChannel >> 8);
00313     uint8_t iChannel = (dmaChannel) & 0xFF;
00314     volatile uint32_t status = pTc0->TC_CHANNEL[0].TC_SR;
00315 
00316     if ((status & TC_SR_CPCS) != 0) {
00317         /* Serial Timer */
00318         if (isUsartON) {
00319             /* Get Received size */
00320             size = XDMAC_GetChDestinationAddr(pDmad->pXdmacs, iChannel)
00321                     - (uint32_t)(usartBuffers[usartCurrentBuffer]);
00322             if (size == 0) {
00323                 pTc0->TC_CHANNEL[0].TC_CCR = TC_CCR_CLKEN | TC_CCR_SWTRG;
00324                 return;
00325             }
00326 
00327             /* Stop DMA */
00328             XDMAD_StopTransfer(pDmad, dmaChannel);
00329             /* Restart DMA in next buffer */
00330             _UsartDmaRx( nextBuffer );
00331 
00332             /* Send current buffer through the USB */
00333             if (isSerialPort0ON) {
00334                 CDCDSerialPort_Write(DUALCDCDDriver_GetSerialPort(0),
00335                                     usartBuffers[usartCurrentBuffer],
00336                                     size, 0, 0);
00337             }
00338             if (isSerialPort1ON) {
00339                 CDCDSerialPort_Write(DUALCDCDDriver_GetSerialPort(1),
00340                                     usartBuffers[usartCurrentBuffer],
00341                                     size, 0, 0);
00342             }
00343             usartCurrentBuffer = nextBuffer;
00344             pTc0->TC_CHANNEL[0].TC_CCR = TC_CCR_CLKEN | TC_CCR_SWTRG;
00345         }
00346     }
00347 }
00348 
00349 /**
00350  * Callback invoked when data has been received on the USB.
00351  * For USB CDC Serial Port 0
00352  */
00353 static void _UsbDataReceived0(uint32_t unused,
00354                             uint8_t status,
00355                             uint32_t received,
00356                             uint32_t remaining)
00357 {
00358     Usart *pUs = BASE_USART;
00359     unused = unused; /*dummy */
00360     /* Check that data has been received successfully */
00361     if (status == USBD_STATUS_SUCCESS) {
00362         /* Send data through USBSerial 1 */
00363         while (CDCDSerialPort_Write(DUALCDCDDriver_GetSerialPort(1),
00364                                  usbSerialBuffer0,
00365                                  received, 0, 0) != USBD_STATUS_SUCCESS);
00366 
00367         /* Send data through USART */
00368         _UsartDmaTx( (uint32_t)&pUs->US_THR, usbSerialBuffer0, received);
00369 
00370         /* Check if bytes have been discarded */
00371         if ((received == DATABUFFERSIZE) && (remaining > 0)) {
00372             TRACE_WARNING(
00373                       "_UsbDataReceived0: %u bytes discarded\n\r",
00374                       (unsigned int)remaining);
00375         }
00376     } else {
00377         TRACE_WARNING( "_UsbDataReceived0: Transfer error\n\r");
00378     }
00379 }
00380 
00381 /**
00382  * Callback invoked when data has been received on the USB.
00383  * For USB CDC Serial Port 1
00384  */
00385 static void _UsbDataReceived1(uint32_t unused,
00386                             uint8_t status,
00387                             uint32_t received,
00388                             uint32_t remaining)
00389 {
00390     Usart *pUs = BASE_USART;
00391     unused = unused; /*dummy */
00392     /* Check that data has been received successfully */
00393     if (status == USBD_STATUS_SUCCESS) {
00394         /* Send data through USBSerial 0 */
00395         while (CDCDSerialPort_Write(DUALCDCDDriver_GetSerialPort(0),
00396                                     usbSerialBuffer1,
00397                                     received, 0, 0) != USBD_STATUS_SUCCESS);
00398         /* Send data through USART */
00399         _UsartDmaTx( (uint32_t)&pUs->US_THR, usbSerialBuffer1, received);
00400 
00401         /* Check if bytes have been discarded */
00402         if ((received == DATABUFFERSIZE) && (remaining > 0)) {
00403             TRACE_WARNING(
00404                       "_UsbDataReceived1: %u bytes discarded\n\r",
00405                       (unsigned int)remaining);
00406         }
00407     } else {
00408         TRACE_WARNING( "_UsbDataReceived1: Transfer error\n\r");
00409     }
00410 }
00411 
00412 /**
00413  * \brief DMA RX callback function
00414  */
00415 static void _UsDmaRxCallback( uint32_t channel, void *pArg)
00416 {
00417     pArg = pArg; /* dummy */
00418     /* Disable timer */
00419     TC_Stop(TC0, 0);
00420     
00421     /* Send data through USBSerial 0 */
00422     if (isSerialPort0ON) {
00423         while (CDCDSerialPort_Write(DUALCDCDDriver_GetSerialPort(0),
00424                                 usartBuffers[usartCurrentBuffer],
00425                                 DATAPACKETSIZE, 0, 0) != USBD_STATUS_SUCCESS);
00426     }
00427     /* Send data through USBSerial 1 */
00428     if (isSerialPort1ON) {
00429         while (CDCDSerialPort_Write(DUALCDCDDriver_GetSerialPort(1),
00430                                 usartBuffers[usartCurrentBuffer],
00431                                 DATAPACKETSIZE, 0, 0) != USBD_STATUS_SUCCESS);
00432     }
00433     /* Restart read on buffer */
00434     usartCurrentBuffer = 1 - usartCurrentBuffer;
00435     _UsartDmaRx(usartCurrentBuffer);
00436     /* Restart timer */
00437     TC_Start(TC0, 0);
00438 }
00439 
00440 /**
00441  * \brief DMA TX callback function
00442  */
00443 static void _UsDmaTxCallback( uint32_t channel, void *pArg)
00444 {
00445     pArg = pArg; /* dummy */
00446     /* Restart USB read */
00447     if (isSerialPort0ON) {
00448         CDCDSerialPort_Read(DUALCDCDDriver_GetSerialPort(0),
00449                             usbSerialBuffer0,
00450                             DATAPACKETSIZE,
00451                             (TransferCallback) _UsbDataReceived0,
00452                             0);
00453     }
00454     if (isSerialPort1ON) {
00455         CDCDSerialPort_Read(DUALCDCDDriver_GetSerialPort(1),
00456                             usbSerialBuffer1,
00457                             DATAPACKETSIZE,
00458                             (TransferCallback) _UsbDataReceived1,
00459                             0);
00460     }
00461 }
00462 
00463 /*----------------------------------------------------------------------------
00464  * Handles interrupts coming from USART
00465  *----------------------------------------------------------------------------*/
00466 void USART1_Handler(void)
00467 {
00468     Usart *pUs = BASE_USART;
00469     uint32_t status;
00470     uint16_t serialState;
00471 
00472     status  = USART_GetStatus(pUs);
00473     status &= USART_GetItMask(pUs);
00474 
00475     /* If USB device is not configured, do nothing */
00476     if (!isUsartON) {
00477         USART_DisableIt(pUs, 0xFFFFFFFF);
00478         return;
00479     }
00480 
00481     /* Errors */
00482     serialState = CDCDSerialPort_GetSerialState(
00483                         DUALCDCDDriver_GetSerialPort(0));
00484 
00485     /* Overrun */
00486     if ((status & US_CSR_OVRE) != 0) {
00487         TRACE_WARNING( "USART1_Handler: Overrun\n\r");
00488         serialState |= CDCSerialState_OVERRUN;
00489     }
00490 
00491     /* Framing error */
00492     if ((status & US_CSR_FRAME) != 0) {
00493         TRACE_WARNING( "USART1_Handler: Framing error\n\r");
00494         serialState |= CDCSerialState_FRAMING;
00495     }
00496     CDCDSerialPort_SetSerialState(
00497             DUALCDCDDriver_GetSerialPort(0), serialState);
00498 }
00499 
00500 /*---------------------------------------------------------------------------
00501  *         Internal functions
00502  *---------------------------------------------------------------------------*/
00503 
00504 /**
00505  * \brief DMA driver configuration
00506  */
00507 static void _ConfigureDma( void )
00508 {
00509     sXdmad *pDmad = &dmad;
00510     /* Driver initialize */
00511     XDMAD_Initialize( &dmad, 0 );
00512     /* IRQ configure */
00513     NVIC_EnableIRQ(XDMAC_IRQn);
00514 
00515     /* Allocate DMA channels for USART */
00516     usartDmaTxChannel = XDMAD_AllocateChannel( pDmad, XDMAD_TRANSFER_MEMORY, ID_USART);
00517     usartDmaRxChannel = XDMAD_AllocateChannel( pDmad, ID_USART, XDMAD_TRANSFER_MEMORY);
00518 
00519     /* Set RX callback */
00520     XDMAD_SetCallback(pDmad, usartDmaRxChannel,(XdmadTransferCallback)_UsDmaRxCallback
00521                     , 0);
00522     /* Set TX callback */
00523     XDMAD_SetCallback(pDmad, usartDmaTxChannel,(XdmadTransferCallback)_UsDmaTxCallback
00524                     , 0);
00525     XDMAD_PrepareChannel( pDmad, usartDmaRxChannel);
00526     XDMAD_PrepareChannel( pDmad, usartDmaTxChannel);
00527 
00528 }
00529 
00530 /**
00531  * Configure USART to work at 115200
00532  */
00533 static void _ConfigureUsart(void)
00534 {
00535     PIO_Configure(pinsUsart, PIO_LISTSIZE(pinsUsart));
00536     PMC_EnablePeripheral(ID_USART);
00537     USART_DisableIt(BASE_USART, 0xFFFFFFFF);
00538     USART_Configure(BASE_USART,
00539                     USART_MODE_ASYNCHRONOUS,
00540                     115200,
00541                     BOARD_MCK);
00542 
00543     USART_SetTransmitterEnabled(BASE_USART, 1);
00544     USART_SetReceiverEnabled(BASE_USART, 1);
00545     NVIC_EnableIRQ(USART1_IRQn);
00546 }
00547 
00548 /**
00549  * Configure TC0 to generate an interrupt every 4ms
00550  */
00551 static void _ConfigureTc0(void)
00552 {
00553     uint32_t div, tcclks;
00554 
00555     /* Enable TC0 peripheral */
00556     PMC_EnablePeripheral(ID_TC0);
00557     /* Configure TC0 for 250Hz frequency and trigger on RC compare */
00558     TC_FindMckDivisor(250, BOARD_MCK, &div, &tcclks, BOARD_MCK);
00559     TC_Configure(TC0, 0, tcclks | TC_CMR_CPCTRG);
00560     TC0->TC_CHANNEL[0].TC_RC = (BOARD_MCK / div) / 250;
00561     /* Configure and enable interrupt on RC compare */
00562     NVIC_EnableIRQ(TC0_IRQn);
00563     TC0->TC_CHANNEL[0].TC_IER = TC_IER_CPCS;
00564     /* Start TC when USB connected & RX enabled */
00565 }
00566 
00567 /**
00568  * Configure USB settings for USB device
00569  */
00570 static void _ConfigureUotghs(void)
00571 {
00572   
00573     /* UTMI parallel mode, High/Full/Low Speed */
00574     /* UUSBCK not used in this configuration (High Speed) */
00575     PMC->PMC_SCDR = PMC_SCDR_USBCLK;
00576     /* USB clock register: USB Clock Input is UTMI PLL */
00577     PMC->PMC_USB = PMC_USB_USBS;
00578     /* Enable peripheral clock for USBHS */
00579     PMC_EnablePeripheral(ID_USBHS);    
00580     USBHS->USBHS_CTRL = USBHS_CTRL_UIMOD_DEVICE;
00581     /* Enable PLL 480 MHz */
00582     PMC->CKGR_UCKR = CKGR_UCKR_UPLLEN | CKGR_UCKR_UPLLCOUNT(0xF);
00583     /* Wait that PLL is considered locked by the PMC */
00584     while( !(PMC->PMC_SR & PMC_SR_LOCKU) );
00585 
00586     /* IRQ */
00587     NVIC_EnableIRQ(USBHS_IRQn) ;
00588 }
00589 /*---------------------------------------------------------------------------
00590  *         Exported function
00591  *---------------------------------------------------------------------------*/
00592 
00593 /*---------------------------------------------------------------------------
00594  *          Main
00595  *---------------------------------------------------------------------------*/
00596 
00597 /**
00598  * Initializes drivers and start the USB Dual CDC device.
00599  */
00600 int main(void)
00601 {
00602     uint8_t usbConnected = 0;
00603     uint8_t serial0ON = 0, serial1ON = 0, usartON = 0;
00604 
00605     /* Disable watchdog */
00606     WDT_Disable( WDT );
00607    
00608     SCB_EnableICache();
00609     SCB_EnableDCache();
00610 
00611     printf("-- USB Dual CDC Device Project %s --\n\r", SOFTPACK_VERSION);
00612     printf("-- %s\n\r", BOARD_NAME);
00613     printf( "-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__ , COMPILER_NAME) ;
00614 
00615     /* If they are present, configure Vbus & Wake-up pins */
00616     PIO_InitializeInterrupts(0);
00617 
00618     /* If there is on board power, switch it off */
00619     _ConfigureUotghs();
00620 
00621     /* Configure DMA */
00622     _ConfigureDma();
00623 
00624     /* Configure timer 0 */
00625     _ConfigureTc0();
00626 
00627     /* ----- CDC Function Initialize */
00628     /* Configure USART */
00629     _ConfigureUsart();
00630     /* Configure DMA for USART */
00631     _UsartDmaRxSetup();
00632 
00633     /* USB DualCDC driver initialization */
00634     DUALCDCDDriver_Initialize(&dualcdcdDriverDescriptors);
00635 
00636     /* connect if needed */
00637     USBD_Connect();
00638 
00639     /* Driver loop */
00640     while (1) {
00641         /* Device is not configured */
00642         if (USBD_GetState() < USBD_STATE_CONFIGURED) {
00643             if (usbConnected) {
00644                 printf("-I- USB Disconnect/Suspend\n\r");
00645                 usbConnected = 0;
00646                 /* Serial port closed */
00647                 isSerialPort0ON = 0;
00648                 isSerialPort1ON = 0;
00649                 isUsartON = 0;
00650             }
00651         } else {
00652             isSerialPort0ON = CDCDSerialPort_GetControlLineState(
00653                                 DUALCDCDDriver_GetSerialPort(0))
00654                              & CDCControlLineState_DTR;
00655             isSerialPort1ON = CDCDSerialPort_GetControlLineState(
00656                                 DUALCDCDDriver_GetSerialPort(1))
00657                              & CDCControlLineState_DTR;
00658             if (usbConnected == 0) {
00659                 printf("-I- USB Connect\n\r");
00660                 usbConnected = 1;
00661             }
00662 
00663             isUsartON = isSerialPort0ON || isSerialPort1ON;
00664             if (!usartON && isUsartON) {
00665                 usartON = 1;
00666                 printf("-I- USART ON\n\r");
00667                 /* Start receiving data on the USART */
00668                 usartCurrentBuffer = 0;
00669                 TC_Start(TC0, 0);
00670                 _UsartDmaRx( usartCurrentBuffer );
00671                 USART_EnableIt( BASE_USART, US_CSR_FRAME | US_CSR_OVRE );
00672             } else if (usartON && !isUsartON) {
00673                 usartON = 0;
00674                 printf("-I- USART OFF\n\r");
00675             }
00676 
00677             if (!serial0ON && isSerialPort0ON) {
00678                 serial0ON = 1;
00679                 printf("-I- SerialPort0 ON\n\r");
00680                 /* Start receiving data on the USB */
00681                 CDCDSerialPort_Read(DUALCDCDDriver_GetSerialPort(0),
00682                                         usbSerialBuffer0,
00683                                         DATAPACKETSIZE,
00684                                         (TransferCallback) _UsbDataReceived0,
00685                                         0);
00686             } else if (serial0ON && !isSerialPort0ON) {
00687                 serial0ON = 0;
00688                 printf("-I- SeriaoPort0 OFF\n\r");
00689             }
00690 
00691             if (!serial1ON && isSerialPort1ON) {
00692                 serial1ON = 1;
00693                 printf("-I- SerialPort1 ON\n\r");
00694                 /* Start receiving data on the USB */
00695                 CDCDSerialPort_Read(DUALCDCDDriver_GetSerialPort(1),
00696                                         usbSerialBuffer1,
00697                                         DATAPACKETSIZE,
00698                                         (TransferCallback) _UsbDataReceived1,
00699                                         0);
00700             } else if (serial1ON && !isSerialPort1ON) {
00701                 serial1ON = 0;
00702                 printf("-I- SeriaoPort1 OFF\n\r");
00703             }
00704         }
00705     }
00706 }
00707 /** \endcond */
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines