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_msd
00030  * \page usb_iad_cdc_msd USB CDC(Serial)+MSD Example
00031  *
00032  * \section Purpose
00033  *
00034  * The USB CDCMSD Project will help you to get familiar with the
00035  * USB Device Port(UDP)interface and also some of the other interfaces in
00036  * SAMv7 Microcontrollers. Also it can help you to be familiar with the USB
00037  * 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 CDCMSD device (such as CDC + MSD).
00040  *
00041  * \section Requirements
00042  *
00043  * This package can be used with some of Atmel Xplained board that have UDP
00044  * 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  * The demo simulates a USB composite device that integrates USB CDC Serial
00054  * RS232 Converter function and USB Disk function.
00055  *
00056  * When the board running this program connected to a host (PC for example), 
00057  * with USB cable, host will notice the attachment of a USB device. No device
00058  * driver offered for the device now.
00059  *
00060  * \section Usage
00061  *
00062  *  -# Build the program and download it inside the SAM V71 Xplained Ultra board. 
00063  *     Please refer to the Getting Started with SAM V71 Microcontrollers.pdf
00064  * -# On the computer, open and configure a terminal application
00065  *    (e.g. HyperTerminal on Microsoft Windows) with these settings:
00066  *   - 115200 bauds
00067  *   - 8 bits of data
00068  *   - No parity
00069  *   - 1 stop bit
00070  *   - No flow control
00071  * -# Start the application.
00072  * -# In the terminal window, the following text should appear:
00073  *     \code
00074  *     -- USB CDCMSD Device Project xxx --
00075  *     -- SAMxxxxx-xx
00076  *     -- Compiled: xxx xx xxxx xx:xx:xx --
00077  *     \endcode
00078  * -# When connecting USB cable to windows, the LED blinks, and the host
00079  *    reports a new USB device attachment.
00080  * -# For the windows driver installation and the test functions, please
00081  *      refer to "USB CDC serial converter" &
00082  *      "USB Device Mass Storage Project".
00083  * -# You can use the inf file
00084  *    libraries\\usb\\device\\composite\\drv\\CompositeCDCSerial.inf
00085  *    to install the CDC serial  port.
00086  *
00087  * \section References
00088  *
00089  * - usb_iad_cdc_msd/main.c
00090  * - pio: Pin configurations and peripheral configure.
00091  * - memories: Storage Media interface for MSD
00092  * - usb: USB Device Framework, USB CDC driver and UDP interface driver
00093  *    - \ref usbd_framework
00094  *        - \ref usbd_api
00095  *    - \ref usbd_composite "composite"
00096  *       - \ref usbd_composite_drv
00097  *    - \ref usbd_msd "massstorage"
00098  *       - \ref usbd_msd_drv
00099  *    - \ref usbd_cdc "cdc-serial"
00100  *       - \ref usbd_cdc_serial_drv
00101  * - projects:
00102  *    - \ref usb_massstorage
00103  *    - \ref usb_cdc_serial
00104  */
00105 
00106 /**
00107  * \file
00108  *
00109  * \section Purpose
00110  *
00111  * This file contains all the specific code for the
00112  * usb_iad_cdc_msd project
00113  */
00114 
00115 /*---------------------------------------------------------------------------
00116  *         Headers
00117  *---------------------------------------------------------------------------*/
00118 
00119 #include "board.h"
00120 
00121 #include "libstoragemedia.h"
00122 
00123 #include <USBD_Config.h>
00124 #include <CDCMSDDriver.h>
00125 #include <CDCDSerial.h>
00126 #include <MSDFunction.h>
00127 
00128 #include <stdint.h>
00129 #include <stdio.h>
00130 #include <string.h>
00131 #include <stdbool.h>
00132 
00133 /*---------------------------------------------------------------------------
00134  *      Definitions
00135  *---------------------------------------------------------------------------*/
00136 
00137 /** Size in bytes of the packet used for reading data from USB */
00138 #define DATAPACKETSIZE \
00139     CHIP_USB_ENDPOINTS_MAXPACKETSIZE(CDCDSerialDriverDescriptors_DATAIN)
00140 
00141 /** Size in bytes of the buffer used for reading data from the USB & USART */
00142 #define DATABUFFERSIZE (DATAPACKETSIZE+2)
00143 
00144 /** Maximum number of LUNs which can be defined. */
00145 #define MAX_LUNS            1
00146 /** Media index for different disks */
00147 #define DRV_RAMDISK         0    /**< RAM disk */
00148 #define DRV_SDMMC           1    /**< SD card */
00149 
00150 /** Size of one block in bytes. */
00151 #define BLOCK_SIZE          512
00152 
00153 /** Size of the MSD IO buffer in bytes (6K, more the better). */
00154 #define MSD_BUFFER_SIZE     (12*BLOCK_SIZE)
00155 
00156 /** RamDisk size: (WinXP can not format the disk if lower than 20K) */
00157 #define RAMDISK_SIZE        128*1024
00158 
00159 COMPILER_SECTION("ramdisk_region") static uint8_t ramdisk_reserved[RAMDISK_SIZE];
00160 #define RAMDISK_BASE_ADDR ((uint32_t)ramdisk_reserved)
00161 
00162 /** Delay for MSD refresh (*4ms) */
00163 #define MSD_REFRESH_DELAY    250
00164 
00165 /** Delay for waiting DBGU input (*4ms) */
00166 #define INPUT_DELAY          (2*250)
00167 
00168 /*---------------------------------------------------------------------------
00169  *      External variables
00170  *---------------------------------------------------------------------------*/
00171 
00172 /** Descriptor list for the device to bring up */
00173 extern const USBDDriverDescriptors cdcmsddDriverDescriptors;
00174 
00175 /*---------------------------------------------------------------------------
00176  *      Internal variables
00177  *---------------------------------------------------------------------------*/
00178 /** Buffer for storing incoming USB data. */
00179 static uint8_t usbSerialBuffer0[DATABUFFERSIZE];
00180 
00181 /** Serial port opened */
00182 static uint8_t isSerialPortON = 0;
00183 
00184 /*- MSD */
00185 /** Available media. */
00186 sMedia medias[MAX_LUNS];
00187 
00188 /** Device LUNs. */
00189 MSDLun luns[MAX_LUNS];
00190 
00191 /** LUN read/write buffer. */
00192 uint8_t msdBuffer[MSD_BUFFER_SIZE];
00193 
00194 /** Total data write to disk */
00195 uint32_t msdWriteTotal = 0;
00196 /** Delay for data write refresh */
00197 uint32_t msdDelay = MSD_REFRESH_DELAY;
00198 /** Delay TO event */
00199 uint8_t  msdRefresh = 0;
00200 
00201 
00202 /*-----------------------------------------------------------------------------
00203  *         Callback re-implementation
00204  *-----------------------------------------------------------------------------*/
00205 /**
00206  * Invoked when the configuration of the device changes. Parse used endpoints.
00207  * \param cfgnum New configuration number.
00208  */
00209 void USBDDriverCallbacks_ConfigurationChanged(uint8_t cfgnum)
00210 {
00211     CDCMSDDriver_ConfigurationChangedHandler(cfgnum);
00212 }
00213 
00214 /**
00215  * Invoked when a new SETUP request is received from the host. Forwards the
00216  * request to the Mass Storage device driver handler function.
00217  * \param request  Pointer to a USBGenericRequest instance.
00218  */
00219 void USBDCallbacks_RequestReceived(const USBGenericRequest *request)
00220 {
00221     CDCMSDDriver_RequestHandler(request);
00222 }
00223 
00224 /*----------------------------------------------------------------------------
00225  *         Callbacks
00226  *----------------------------------------------------------------------------*/
00227 
00228 /**
00229  * Invoked when the MSD finish a READ/WRITE.
00230  * \param flowDirection 1 - device to host (READ10)
00231  *                      0 - host to device (WRITE10)
00232  * \param dataLength Length of data transferred in bytes.
00233  * \param fifoNullCount Times that FIFO is NULL to wait
00234  * \param fifoFullCount Times that FIFO is filled to wait
00235  */
00236 static void MSDCallbacks_Data(uint8_t flowDirection,
00237                        uint32_t  dataLength,
00238                        uint32_t  fifoNullCount,
00239                        uint32_t  fifoFullCount)
00240 {
00241     fifoNullCount = fifoNullCount; /* dummy */
00242     fifoFullCount = fifoFullCount;  /*dummy */
00243     if (!flowDirection) {
00244         msdWriteTotal += dataLength;
00245     }
00246 }
00247 
00248 /**
00249  * Invoked when the CDC ControlLineState is changed
00250  * \param DTR   New DTR value.
00251  * \param RTS   New RTS value.
00252  */
00253 void CDCDSerial_ControlLineStateChanged(uint8_t DTR,
00254                                     uint8_t RTS)
00255 {
00256     isSerialPortON = DTR;
00257     RTS = RTS; /* dummy */
00258 }
00259 
00260 /**
00261  * Invoked when the CDC LineCoding is requested to changed
00262  * \param pLineCoding   Pointer to new LineCoding settings.
00263  * \return USBRC_SUCCESS if ready to receive the line coding.
00264  */
00265 uint8_t CDCDSerial_LineCodingIsToChange(CDCLineCoding* pLineCoding)
00266 {
00267     pLineCoding = pLineCoding; /*dummy */
00268     return USBD_STATUS_SUCCESS;
00269 }
00270 
00271 /*---------------------------------------------------------------------------
00272  *         Internal functions
00273  *---------------------------------------------------------------------------*/
00274 /**
00275  * Configure USBHS settings for USB device
00276  */
00277 static void _ConfigureUotghs(void)
00278 {
00279   
00280     /* UTMI parallel mode, High/Full/Low Speed */
00281     /* UUSBCK not used in this configuration (High Speed) */
00282     PMC->PMC_SCDR = PMC_SCDR_USBCLK;
00283     /* USB clock register: USB Clock Input is UTMI PLL */
00284     PMC->PMC_USB = PMC_USB_USBS;
00285     /* Enable peripheral clock for USBHS */
00286     PMC_EnablePeripheral(ID_USBHS);    
00287     USBHS->USBHS_CTRL = USBHS_CTRL_UIMOD_DEVICE;
00288     /* Enable PLL 480 MHz */
00289     PMC->CKGR_UCKR = CKGR_UCKR_UPLLEN | CKGR_UCKR_UPLLCOUNT(0xF);
00290     /* Wait that PLL is considered locked by the PMC */
00291     while( !(PMC->PMC_SR & PMC_SR_LOCKU) );
00292 
00293     /* IRQ */
00294     NVIC_EnableIRQ(USBHS_IRQn) ;
00295 }
00296 
00297 /**
00298  * Initialize DDRAM to assign RamDisk block
00299  */
00300 static void RamDiskInit(void)
00301 {
00302     BOARD_ConfigureSdram();
00303 
00304     printf("RamDisk @ %x, size %d\n\r", RAMDISK_BASE_ADDR, RAMDISK_SIZE);
00305 
00306     MEDRamDisk_Initialize(&(medias[DRV_RAMDISK]),
00307                         BLOCK_SIZE,
00308                         (RAMDISK_BASE_ADDR ) / BLOCK_SIZE,
00309                         RAMDISK_SIZE / BLOCK_SIZE,
00310                         1);
00311     LUN_Init(&(luns[DRV_RAMDISK]),
00312             &(medias[DRV_RAMDISK]),
00313             msdBuffer, MSD_BUFFER_SIZE,
00314             0, 0, 0, 0,
00315             MSDCallbacks_Data);
00316 
00317     gNbMedias = 1;
00318 }
00319 
00320 /**
00321  * Initialize MSD Media & LUNs
00322  */
00323 static void _MemoriesInitialize(void)
00324 {
00325     uint32_t i ;
00326 
00327     /* Reset all LUNs */
00328     for (i = 0; i < MAX_LUNS; i ++)
00329         LUN_Init(&luns[i], 0, 0, 0, 0, 0, 0, 0, 0);
00330 
00331     /* TODO: Add LUN Init here */
00332 
00333     /* RAM disk initialize */
00334     RamDiskInit();
00335     /* Nand Flash Init */
00336     /* SD Card Init */
00337 }
00338 
00339 /*---------------------------------------------------------------------------
00340  *         Exported function
00341  *---------------------------------------------------------------------------*/
00342 
00343 /*---------------------------------------------------------------------------
00344  *          Main
00345  *---------------------------------------------------------------------------*/
00346 
00347 /**
00348  * Initializes drivers and start the USB CDCMSD device.
00349  */
00350 int main(void)
00351 {
00352     uint8_t usbConnected = 0, serialON = 0;
00353 
00354     /* Disable watchdog */
00355     WDT_Disable( WDT );
00356 
00357     SCB_EnableICache();
00358     SCB_EnableDCache();
00359 
00360     printf("-- USB CDCMSD Device Project %s --\n\r", SOFTPACK_VERSION);
00361     printf("-- %s\n\r", BOARD_NAME);
00362     printf( "-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__ , COMPILER_NAME) ;
00363 
00364     /* If they are present, configure Vbus & Wake-up pins */
00365     PIO_InitializeInterrupts(0);
00366 
00367     /* If there is on board power, switch it off */
00368     _ConfigureUotghs();
00369 
00370     /* ----- MSD Function Initialize */
00371     /* Configure memories */
00372     _MemoriesInitialize();
00373 
00374     /* USB CDCMSD driver initialization */
00375     CDCMSDDriver_Initialize(&cdcmsddDriverDescriptors, luns, MAX_LUNS);
00376 
00377     /* connect if needed */
00378     USBD_Connect();
00379 
00380     /* Driver loop */
00381     while (1)
00382     {
00383         /* Device is not configured */
00384         if (USBD_GetState() < USBD_STATE_CONFIGURED) {
00385             if (usbConnected) {
00386                 printf("-I- USB Disconnect/Suspend\n\r");
00387                 usbConnected = 0;
00388 
00389                 /* Serial port closed */
00390                 isSerialPortON = 0;
00391             }
00392         } else {
00393             if (usbConnected == 0) {
00394                 printf("-I- USB Connect\n\r");
00395                 usbConnected = 1;
00396             }
00397             if (!serialON && isSerialPortON) {
00398                 printf("-I- SerialPort ON\n\r");
00399                 /* Start receiving data on the USART */
00400                 /* Start receiving data on the USB */
00401                 CDCDSerial_Read(usbSerialBuffer0, DATAPACKETSIZE, 0, 0);
00402                 serialON = 1;
00403             } else if (serialON && !isSerialPortON) {
00404                 printf("-I- SeriaoPort OFF\n\r");
00405                 serialON = 0;
00406             }
00407             MSDFunction_StateMachine();
00408 
00409             if (msdRefresh) {
00410                 msdRefresh = 0;
00411                 if (msdWriteTotal < 50 * 1000) {
00412                     /* Flush Disk Media */
00413                 }
00414                 msdWriteTotal = 0;
00415             }
00416         }
00417     }
00418 }
00419 /** \endcond */
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines