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