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