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_eem
00030  *  \page usb_eem USB communication device class Example for Ethernet Emulation Model Devices 
00031  *
00032  *  \section Purpose
00033  *
00034  *  The USB communication device class Example will help you to get familiar with the
00035  *  USB communication device class on SAMv7 Microcontrollers. Also
00036  *  it can help you to be familiar with the USB Framework that is used for
00037  *  rapid development of USB-compliant class drivers such as USB communication device
00038  *  class.
00039  *
00040  *  \section Requirements
00041  *
00042  *  This package can be used with SAMV71 Xplained board
00043  *  The device uses the USB communication device class (CDC) drivers to take advantage of the installed PC RS-232
00044  *  software to talk over the USB.
00045  *
00046  *  \section Usage
00047  *
00048  *  -# Build the program and download it inside the SAM V71 Xplained Ultra board. Please
00049  *     refer to the Getting Started with SAM V71 Microcontrollers.pdf
00050  *  -# On the computer, open and configure a terminal application
00051  *     (e.g. HyperTerminal on Microsoft Windows) with these settings:
00052  *    - 115200 bauds
00053  *    - 8 bits of data
00054  *    - No parity
00055  *    - 1 stop bit
00056  *    - No flow control
00057  *  -# Start the application.
00058  *  -# In the terminal window, the following text should appear:
00059  *  \code
00060  *  -- USB Device CDC EEM Project xxx --
00061  *  -- SAMxxxxx-xx
00062  *  -- Compiled: xxx xx xxxx xx:xx:xx --
00063  *  \endcode
00064  *
00065  *  \section References
00066  *  - usb_cdc/main.c
00067  *  - usb: USB Framework, USB communication device class driver
00068  *      - \ref usbd_framework
00069  *      - \ref usbd_api
00070  *      - \ref usbd_cdc
00071  */
00072 
00073 /**
00074  *  \file
00075  *
00076  *  This file contains all the specific code for the
00077  *  usb_eem example.
00078  */
00079 /*----------------------------------------------------------------------------
00080  *         Headers
00081  *----------------------------------------------------------------------------*/
00082 
00083 #include "board.h"
00084 
00085 #include "USBD.h"
00086 #include "CDCDEEMDriver.h"
00087 
00088 #include <stdbool.h>
00089 #include <stdint.h>
00090 #include <string.h>
00091 
00092 /*----------------------------------------------------------------------------
00093  *      Definitions
00094  *----------------------------------------------------------------------------*/
00095 
00096 /** Size in bytes of the packet used for reading data from USB */
00097 #define MAXPACKETSIZE       1536
00098 #if defined   ( __CC_ARM ) &&  defined   ( sram )
00099 #define ETH_TX_BUFFERS       32     /** Must be a power of 2 */
00100 #define ETH_RX_BUFFERS       32     /** Must be a power of 2 */
00101 #else
00102 #define ETH_TX_BUFFERS       64     /** Must be a power of 2 */
00103 #define ETH_RX_BUFFERS       64     /** Must be a power of 2 */
00104 #endif
00105 
00106 #define ETH_BUFF_SIZE        1536
00107 
00108 #define DUMMY_BUFFERS        2
00109 #define DUMMY_BUFF_SIZE      128
00110 
00111 /*----------------------------------------------------------------------------
00112  *      External variables
00113  *----------------------------------------------------------------------------*/
00114 
00115 extern const USBDDriverDescriptors cdcdEEMDriverDescriptors;
00116 
00117 /*----------------------------------------------------------------------------
00118  *      Internal variables
00119  *----------------------------------------------------------------------------*/
00120 
00121 static uint8_t gUsbConnected = 0;
00122 
00123 /** Buffer for storing incoming USB data. */
00124 static uint8_t gUsbRxBuffer[MAXPACKETSIZE];
00125 
00126 /** The PINs for GMAC */
00127 static const Pin gmacPins[]      = { BOARD_GMAC_RUN_PINS };
00128 static const Pin gmacResetPins[] = { BOARD_GMAC_RESET_PIN };
00129 
00130 /** The MAC address used for demo */
00131 static uint8_t gMacAddress[6] = { 0x3a, 0x1f, 0x34, 0x08, 0x54, 0x54 };
00132 
00133 /** The GMAC driver instance */
00134 static sGmacd gGmacd;
00135 
00136 /** The MACB driver instance */
00137 static GMacb gGmacb;
00138 
00139 /** TX descriptors list */
00140 COMPILER_SECTION(".ram_nocache")
00141 COMPILER_ALIGNED(8)
00142 static sGmacTxDescriptor gTxDs[ETH_TX_BUFFERS], gDummyTxDs[DUMMY_BUFFERS];
00143 
00144 /** TX callbacks list */
00145 COMPILER_ALIGNED(8) static fGmacdTransferCallback gTxCbs[ETH_TX_BUFFERS], gDummyTxCbs[DUMMY_BUFFERS];
00146 
00147 /** RX descriptors list */
00148 COMPILER_SECTION(".ram_nocache")
00149 COMPILER_ALIGNED(8)
00150 static sGmacRxDescriptor gRxDs[ETH_RX_BUFFERS], gDummyRxDs[DUMMY_BUFFERS];
00151 
00152 /** Send Buffer */
00153 /* Section 3.6 of AMBA 2.0 spec states that burst should not cross 1K Boundaries.
00154    Receive buffer manager writes are burst of 2 words => 3 lsb bits of the address
00155    shall be set to 0 */
00156 COMPILER_ALIGNED(8)
00157 static uint8_t gTxBuffer[ETH_TX_BUFFERS * ETH_BUFF_SIZE], gTxDummyBuffer[DUMMY_BUFFERS * DUMMY_BUFF_SIZE];
00158 
00159 /** Receive Buffer */
00160 COMPILER_ALIGNED(8)
00161 static uint8_t gRxBuffer[ETH_RX_BUFFERS * ETH_BUFF_SIZE], gRxDummyBuffer[DUMMY_BUFFERS * DUMMY_BUFF_SIZE];
00162 
00163 
00164 /*----------------------------------------------------------------------------
00165  *         Internal Prototypes
00166  *----------------------------------------------------------------------------*/
00167 
00168 /*----------------------------------------------------------------------------
00169  *  Interrupt handlers
00170  *----------------------------------------------------------------------------*/
00171 
00172 /**
00173  * Gmac interrupt handler
00174  */
00175 void GMAC_Handler(void)
00176 {
00177     GMACD_Handler(&gGmacd, GMAC_QUE_0);
00178 }
00179 
00180 /*-----------------------------------------------------------------------------
00181  *         Callback re-implementation
00182  *-----------------------------------------------------------------------------*/
00183 
00184 /**
00185  * Invoked when the configuration of the device changes. Parse used endpoints.
00186  * \param cfgnum New configuration number.
00187  */
00188 void USBDDriverCallbacks_ConfigurationChanged(unsigned char cfgnum)
00189 {
00190     CDCDEEMDriver_ConfigurationChangedHandler(cfgnum);
00191 }
00192 
00193 /**
00194  * Invoked when a new SETUP request is received from the host. Forwards the
00195  * request to the Mass Storage device driver handler function.
00196  * \param request  Pointer to a USBGenericRequest instance.
00197  */
00198 void USBDCallbacks_RequestReceived(const USBGenericRequest *request)
00199 {
00200     CDCDEEMDriver_RequestHandler(request);
00201 }
00202 
00203 /*----------------------------------------------------------------------------
00204  *         Internal functions
00205  *----------------------------------------------------------------------------*/
00206 
00207 /**
00208  * Configure USBHS settings for USB device
00209  */
00210 static void _ConfigureUotghs(void)
00211 {
00212     /* UTMI parallel mode, High/Full/Low Speed */
00213     /* UOTGCK not used in this configuration (High Speed) */
00214     PMC->PMC_SCDR = PMC_SCDR_USBCLK;
00215     /* USB clock register: USB Clock Input is UTMI PLL */
00216     PMC->PMC_USB = PMC_USB_USBS;
00217     /* Enable peripheral clock for USBHS */
00218     PMC_EnablePeripheral(ID_USBHS);
00219     USBHS->USBHS_CTRL = USBHS_CTRL_UIMOD_DEVICE;
00220     /* Enable PLL 480 MHz */
00221     PMC->CKGR_UCKR = CKGR_UCKR_UPLLEN | CKGR_UCKR_UPLLCOUNT(0xF);
00222     /* Wait that PLL is considered locked by the PMC */
00223     while( !(PMC->PMC_SR & PMC_SR_LOCKU) );
00224 }
00225 
00226 /*----------------------------------------------------------------------------
00227  * Callback invoked when data has been received on the USB.
00228  *----------------------------------------------------------------------------*/
00229 static void _UsbDataReceived(void *unused,
00230                              uint8_t status,
00231                              uint32_t received,
00232                              uint32_t remaining)
00233 {
00234     // unused args
00235     (void)unused;
00236     (void)remaining;
00237 
00238     /* Check that data has been received successfully */
00239     if (status == USBD_STATUS_SUCCESS)
00240     {
00241         TRACE_INFO("%u USB_RECV(%u)\n\r", 
00242                 (unsigned int)GetTicks(), (unsigned int)received);
00243 
00244         /* Send packet through GMAC */
00245         if (GMACD_Send(&gGmacd, gUsbRxBuffer, received, NULL, GMAC_QUE_0) 
00246                 != GMACD_OK) {
00247             TRACE_WARNING("_UsbDataReceived: GMAC send overflow\n\r");
00248         }
00249     } else {
00250         TRACE_WARNING("_UsbDataReceived: Transfer error\n\r");
00251     }
00252 
00253     /* receive next packet on USB */
00254     CDCDEEMDriver_Read(gUsbRxBuffer, MAXPACKETSIZE, _UsbDataReceived, 0);
00255 }
00256 
00257 /*----------------------------------------------------------------------------
00258  * Callback invoked when data has been received on the GMAC.
00259  *----------------------------------------------------------------------------*/
00260 static void _EthDataReceived(uint32_t status)
00261 {
00262     uint8_t buffer[MAXPACKETSIZE];
00263     uint32_t frmSize;
00264 
00265     // unused args
00266     (void)status;
00267 
00268     TRACE_INFO("%u ETH_RXCB(%u)\n\r", (unsigned int)GetTicks(), (unsigned int)status);
00269 
00270     /* Handle ethernet data if any */
00271     while (
00272         GMACD_OK == GMACD_Poll(&gGmacd, buffer, sizeof(buffer), &frmSize, GMAC_QUE_0)) {
00273         TRACE_INFO("%u ETH_RECV(%u)\n\r", (unsigned int)GetTicks(), (unsigned int)frmSize);
00274 
00275         /* Send packet through USB */
00276         if (CDCDEEMDriver_Write(buffer, frmSize, NULL, 0) != USBD_STATUS_SUCCESS) {
00277             TRACE_WARNING("_EthDataReceived: USB send overflow\n\r");
00278         }
00279     }
00280 
00281     /* receive next packet on GMAC */
00282     GMACD_SetRxCallback(&gGmacd, _EthDataReceived, GMAC_QUE_0);
00283 }
00284 
00285 /*_____ E X P O R T E D   F U N C T I O N S ________________________________*/
00286 
00287 /*! \brief Main function. Execution starts here.
00288  */
00289 int main(void)
00290 {
00291     sGmacInit Queue0, Queue12;
00292 
00293     /* Disable watchdog */
00294     WDT_Disable( WDT ) ;
00295 
00296     SCB_EnableICache();
00297     SCB_EnableDCache();
00298 
00299     /* Output example information */
00300     printf("-- USB Device CDC EEM Project %s --\n\r", SOFTPACK_VERSION);
00301     printf("-- %s\n\r", BOARD_NAME);
00302     printf( "-- Compiled: %s %s  With %s--\n\r", __DATE__, __TIME__ , COMPILER_NAME) ;
00303 
00304     /* Initialize OTG clocks */
00305     _ConfigureUotghs();
00306 
00307     /* Configure systick for 1 ms. */
00308     TimeTick_Configure();
00309 
00310     /* Initialize GMAC driver structure for queue 0 */
00311     memset(&Queue0, 0, sizeof(Queue0));
00312     Queue0.bIsGem = 1;
00313     Queue0.bDmaBurstLength = 4;
00314     Queue0.pRxBuffer = gRxBuffer;
00315     Queue0.pRxD = gRxDs;
00316     Queue0.wRxBufferSize = ETH_BUFF_SIZE;
00317     Queue0.wRxSize = ETH_RX_BUFFERS;
00318     Queue0.pTxBuffer = gTxBuffer;
00319     Queue0.pTxD = gTxDs;
00320     Queue0.wTxBufferSize = ETH_BUFF_SIZE;
00321     Queue0.wTxSize = ETH_TX_BUFFERS;
00322     Queue0.pTxCb = gTxCbs;
00323 
00324     /* Initialize dummy GMAC driver structure for queues 1 and 2 */
00325     memset(&Queue12, 0, sizeof(Queue12));
00326     Queue12.bIsGem = 1;
00327     Queue12.bDmaBurstLength = 4;
00328     Queue12.pRxBuffer = gRxDummyBuffer;
00329     Queue12.pRxD = gDummyRxDs;
00330     Queue12.wRxBufferSize = DUMMY_BUFF_SIZE;
00331     Queue12.wRxSize = DUMMY_BUFFERS;
00332     Queue12.pTxBuffer = gTxDummyBuffer;
00333     Queue12.pTxD = gDummyTxDs;
00334     Queue12.wTxBufferSize = DUMMY_BUFF_SIZE;
00335     Queue12.wTxSize = DUMMY_BUFFERS;
00336     Queue12.pTxCb = gDummyTxCbs;
00337 
00338     /* Initialize GMAC */
00339     GMACD_Init(&gGmacd, GMAC, ID_GMAC, 1, 0);
00340     GMACD_InitTransfer(&gGmacd, &Queue12,  GMAC_QUE_2);
00341     GMACD_InitTransfer(&gGmacd, &Queue12,  GMAC_QUE_1);
00342     GMACD_InitTransfer(&gGmacd, &Queue0, GMAC_QUE_0);
00343     GMAC_SetAddress(gGmacd.pHw, 0, gMacAddress);
00344 
00345     /* Setup interrupts */
00346     NVIC_ClearPendingIRQ(GMAC_IRQn);
00347     NVIC_EnableIRQ(GMAC_IRQn);
00348     NVIC_ClearPendingIRQ(USBHS_IRQn);
00349     NVIC_EnableIRQ(USBHS_IRQn);
00350 
00351     /* PHY initialize */
00352     GMACB_Init(&gGmacb, &gGmacd, BOARD_GMAC_PHY_ADDR);
00353     GMACB_ResetPhy(&gGmacb);
00354     if (!GMACB_InitPhy(
00355         &gGmacb, BOARD_MCK, gmacResetPins, 1, gmacPins, PIO_LISTSIZE(gmacPins))) {
00356         TRACE_ERROR("PHY Initialize ERROR!\n\r");
00357         return 0;
00358     }
00359     if (!GMACB_AutoNegotiate(&gGmacb)) {
00360         TRACE_ERROR("Auto Negotiate ERROR!\n\r");
00361         return 0;
00362     }
00363 
00364     /* CDC EEM driver initialization */
00365     CDCDEEMDriver_Initialize(&cdcdEEMDriverDescriptors);
00366 
00367     /* Start USB stack to authorize VBus monitoring */
00368     USBD_Connect();
00369 
00370     /* Driver loop */
00371     while (1)
00372     {
00373         /* Device is not configured */
00374         if (USBD_GetState() < USBD_STATE_CONFIGURED) {
00375             gUsbConnected = 0;
00376         } else if (!gUsbConnected) {
00377             gUsbConnected = 1;
00378 
00379             /* Start receiving data on the USB */
00380             CDCDEEMDriver_Read(gUsbRxBuffer, MAXPACKETSIZE, _UsbDataReceived, 0);
00381 
00382             /* Start receiving data on GMAC */
00383             GMACD_SetRxCallback(&gGmacd, _EthDataReceived, GMAC_QUE_0);
00384         }
00385     }
00386 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines