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_massstorage
00031  * \page usb_massstorage USB Device Mass Storage Example
00032  *
00033  * \section Purpose
00034  *
00035  * The USB Mass storage Example will help you to get familiar with the
00036  * USB Device Port(UDP) 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 Mass
00039  * Storage class (MSD).
00040  *
00041  * \section Requirements
00042  *
00043  * This package can be used with SAMV71 Xplained Ultra board or SAME70 Xplained board
00044  * This package can be used with all Atmel Xplained board that have USB interface
00045  *
00046  * \section Description
00047  *
00048  * The demo simulates a SD/MMC USB disk.
00049  *
00050  * When the board running this program connected to a host (PC for example), with
00051  * USB cable, the board appears as a USB Disk for the host. Then the host can
00052  * format/read/write on the disk.
00053  *
00054  * \section Usage
00055  *
00056  *  -# Build the program and download it inside the board.
00057  *     Please refer to the Getting Started with SAM V71/E70 Microcontrollers.pdf
00058  * -# On the computer, open and configure a terminal application
00059  *    (e.g. HyperTerminal on Microsoft Windows) with these settings:
00060  *   - 115200 baud rate
00061  *   - 8 bits of data
00062  *   - No parity
00063  *   - 1 stop bit
00064  *   - No flow control
00065  * -# Start the application.
00066  * -# In the terminal window, the following text should appear:
00067  *     \code
00068  *     -- USB Device Mass Storage Example xxx --
00069  *     -- SAMxxxxx-xx
00070  *     -- Compiled: xxx xx xxxx xx:xx:xx --
00071  *     \endcode
00072  * -# When connecting USB cable to windows, the host
00073  *    reports a new USB %device attachment and Disk installation.
00074  *  . Then new "USB Mass Storage Device" and
00075  *    "ATMEL Mass Storage MSD USB Device" and "Generic volume" appear in
00076  *    hardware %device list.
00077  * -# You can find the new disk on host, and to create/write file to it.
00078  *
00079  * \section References
00080  * - usb_massstorage/main.c
00081  * - pio.h
00082  * - pio_it.h
00083  * - memories: Storage Media interface for MSD
00084  * - usb: USB Framework, USB MSD driver and UDP interface driver
00085  *    - \ref usbd_framework
00086  *       - \ref usbd_api
00087  *    - \ref usbd_msd
00088  *       - \ref usbd_msd_drv
00089  */
00090 
00091 /**
00092  * \file
00093  *
00094  * This file contains all the specific code for the
00095  * usb_massstorage.
00096  */
00097 
00098 /*----------------------------------------------------------------------------
00099  *        Headers
00100  *----------------------------------------------------------------------------*/
00101 
00102 #include "board.h"
00103 
00104 #include "libstoragemedia.h"
00105 #include "libsdmmc.h"
00106 
00107 #include "MSDDriver.h"
00108 #include "MSDLun.h"
00109 
00110 #include <stdbool.h>
00111 #include <stdint.h>
00112 #include <stdio.h>
00113 
00114 /*----------------------------------------------------------------------------
00115  *        Compiling Options
00116  *----------------------------------------------------------------------------*/
00117 
00118 /* No transfer speed dump */
00119 #define DBG_SPEED_OFF
00120 #define USBHS_PRI                       3
00121 #define HSMCI_PRI                       2
00122 #define XDMAC_PRI                       1
00123 /*----------------------------------------------------------------------------
00124  *        Local definitions
00125  *----------------------------------------------------------------------------*/
00126 
00127 /** Maximum number of LUNs which can be defined. */
00128 #define MAX_LUNS            2
00129 
00130 /** Media index for different disks */
00131 
00132 #define DRV_RAMDISK         0    /**< RAM disk */
00133 #define DRV_SDMMC           1    /**< SD card */
00134 #define DRV_NAND            2    /**< Nand flash */
00135 
00136 /** RamDisk size (in bytes) */
00137 /** RamDisk size: 20K (WinXP can not format the disk if lower than 20K) */
00138 #define RAMDISK_SIZE        128*1024
00139 
00140 COMPILER_SECTION("ramdisk_region") static uint8_t
00141 ramdisk_reserved[RAMDISK_SIZE];
00142 #define RAMDISK_BASE_ADDR ((uint32_t)ramdisk_reserved)
00143 
00144 /** Size of one block in bytes. */
00145 #define BLOCK_SIZE          512
00146 
00147 /** Size of the MSD IO buffer in bytes (150K, more the better). */
00148 #define MSD_BUFFER_SIZE     (128 * BLOCK_SIZE)
00149 
00150 
00151 /*----------------------------------------------------------------------------
00152  *        Global variables
00153  *----------------------------------------------------------------------------*/
00154 
00155 /** MSD Driver Descriptors List */
00156 extern const USBDDriverDescriptors msdDriverDescriptors;
00157 
00158 /** SD card pins instance. */
00159 static const Pin pinsSd[] = {BOARD_MCI_PINS_SLOTA, BOARD_MCI_PIN_CK};
00160 
00161 /** SD card detection pin instance. */
00162 static const Pin pinsCd[] = {BOARD_MCI_PIN_CD};
00163 
00164 /** Available media. */
00165 sMedia medias[MAX_LUNS];
00166 
00167 /*----------------------------------------------------------------------------
00168  *        Local variables
00169  *----------------------------------------------------------------------------*/
00170 /** DMA driver instance */
00171 static sXdmad dmaDrv;
00172 
00173 /** Device LUNs. */
00174 static MSDLun luns[MAX_LUNS];
00175 
00176 /** SDCard driver instance. */
00177 COMPILER_ALIGNED(32) static sSdCard sdDrv[BOARD_NUM_MCI];
00178 
00179 /** MCI driver instance. */
00180 /** SDCard driver instance. */
00181 COMPILER_ALIGNED(32) static sMcid mciDrv[BOARD_NUM_MCI];
00182 
00183 /** LUN read/write buffer. */
00184 COMPILER_ALIGNED(32) static uint8_t mSdBuffer[MSD_BUFFER_SIZE];
00185 COMPILER_ALIGNED(32) static uint8_t mRamBuffer[MSD_BUFFER_SIZE];
00186 
00187 /** Total data write to disk */
00188 uint32_t msdWriteTotal = 0;
00189 
00190 /** Delay TO event */
00191 uint8_t  msdRefresh = 0;
00192 
00193 
00194 /**
00195  * XDMA0 interrupt handler.
00196  */
00197 void XDMAC_Handler(void)
00198 {
00199     XDMAD_Handler(&dmaDrv);
00200 }
00201 
00202 /**
00203  * MCI interrupt handler. Forwards the event to the MCI driver handlers.
00204  */
00205 void HSMCI_Handler(void)
00206 {
00207     uint32_t i;
00208 
00209     for (i = 0; i < BOARD_NUM_MCI; i ++)
00210         MCID_Handler(&mciDrv[i]);
00211 }
00212 
00213 /*-----------------------------------------------------------------------------
00214  *         Callback re-implementation
00215  *-----------------------------------------------------------------------------*/
00216 
00217 /**
00218  * Invoked when a new SETUP request is received from the host. Forwards the
00219  * request to the Mass Storage device driver handler function.
00220  * \param request  Pointer to a USBGenericRequest instance.
00221  */
00222 void USBDCallbacks_RequestReceived(const USBGenericRequest *request)
00223 {
00224     MSDDriver_RequestHandler(request);
00225 }
00226 
00227 /**
00228  * Invoked when the configuration of the device changes. Resets the mass
00229  * storage driver.
00230  * \param cfgnum New configuration number.
00231  */
00232 void USBDDriverCallbacks_ConfigurationChanged(unsigned char cfgnum)
00233 {
00234     MSDDriver_ConfigurationChangeHandler(cfgnum);
00235 }
00236 
00237 /*----------------------------------------------------------------------------
00238  *        Callbacks
00239  *----------------------------------------------------------------------------*/
00240 /**
00241  * Invoked when the MSD finish a READ/WRITE.
00242  * \param flowDirection 1 - device to host (READ10)
00243  *                      0 - host to device (WRITE10)
00244  * \param dataLength Length of data transferred in bytes.
00245  * \param fifoNullCount Times that FIFO is NULL to wait
00246  * \param fifoFullCount Times that FIFO is filled to wait
00247  */
00248 static void MSDCallbacks_Data(uint8_t flowDirection,
00249                               uint32_t  dataLength,
00250                               uint32_t  fifoNullCount,
00251                               uint32_t  fifoFullCount)
00252 {
00253     fifoNullCount = fifoNullCount; /* dummy */
00254     fifoFullCount = fifoFullCount;  /*dummy */
00255 
00256     if (!flowDirection)
00257         msdWriteTotal += dataLength;
00258 }
00259 /*----------------------------------------------------------------------------
00260  *        Local functions
00261  *----------------------------------------------------------------------------*/
00262 /**
00263  * Configure for SD detect pin
00264  */
00265 static void CardDetectConfigure(void)
00266 {
00267     PIO_Configure(pinsCd, PIO_LISTSIZE(pinsCd));
00268     /* No protection detect pin */
00269 }
00270 
00271 /**
00272  * Check if the card is connected.
00273  * \param iMci Controller number.
00274  * Return 1 if card is inserted.
00275  */
00276 static uint8_t CardIsConnected(uint8_t iMci)
00277 {
00278     return PIO_Get(&pinsCd[iMci]) ? 0 : 1;
00279 }
00280 
00281 /**
00282  * Run init on the inserted card
00283  * \param iMci Controller number.
00284  */
00285 static void CardInit(sSdCard *pSd)
00286 {
00287     uint8_t error;
00288     uint8_t retry = 2;
00289 
00290     while (retry --) {
00291         error = SD_Init(pSd);
00292 
00293         if (error == SDMMC_OK) break;
00294     }
00295 
00296     if (error) {
00297         TRACE_ERROR("SD/MMC card initialization failed: %d\n\r", error);
00298         return;
00299     }
00300 
00301     TRACE_INFO(" SD/MMC card initialization successful\n\r");
00302 
00303     if (SD_GetCardType(pSd) & CARD_TYPE_bmSDMMC) {
00304         TRACE_INFO(" MEM Card OK, size: %d MB", (int)SD_GetTotalSizeKB(pSd) / 1000);
00305         TRACE_INFO(", %d * %dB\n\r", (int)SD_GetNumberBlocks(pSd),
00306                    (int)SD_GetBlockSize(pSd));
00307     }
00308 
00309     if (SD_GetCardType(pSd) & CARD_TYPE_bmSDIO) {
00310         TRACE_ERROR("-E- IO Card Detected \n\r");
00311     }
00312 }
00313 
00314 /**
00315  * Initialize PIOs
00316  */
00317 static void _ConfigurePIOs(void)
00318 {
00319     /* Configure SDcard pins */
00320     PIO_Configure(pinsSd, PIO_LISTSIZE(pinsSd));
00321     /* Configure SD card detection */
00322     CardDetectConfigure();
00323 }
00324 
00325 /**
00326  * Initialize driver instances.
00327  */
00328 static void _ConfigureDrivers(void)
00329 {
00330     uint32_t i;
00331     /* Initialize the DMA driver */
00332     XDMAD_Initialize(&dmaDrv, 0);
00333 
00334     /* Enable XDMA interrupt and give it priority over any other peripheral
00335         interrupt */
00336     NVIC_ClearPendingIRQ(XDMAC_IRQn);
00337     NVIC_SetPriority(XDMAC_IRQn, XDMAC_PRI);
00338     NVIC_EnableIRQ(XDMAC_IRQn);
00339 
00340     /* Initialize the HSMCI driver */
00341     MCID_Init(&mciDrv[0], HSMCI, ID_HSMCI, BOARD_MCK, &dmaDrv, 0);
00342 
00343     /* Enable MCI interrupt and give it priority lower than DMA*/
00344     NVIC_ClearPendingIRQ(HSMCI_IRQn);
00345     NVIC_SetPriority(HSMCI_IRQn, HSMCI_PRI);
00346     NVIC_EnableIRQ(HSMCI_IRQn);
00347 
00348     /* Initialize SD driver */
00349     for (i = 0; i < BOARD_NUM_MCI; i ++)
00350         SDD_InitializeSdmmcMode(&sdDrv[i], &mciDrv[i], 0);
00351 }
00352 
00353 /*----------------------------------------------------------------------------
00354  *         Internal functions
00355  *----------------------------------------------------------------------------*/
00356 static void SDDiskInit(sSdCard *pSd)
00357 {
00358     uint8_t sdConnected;
00359     pSd = &sdDrv[0];
00360     /* Infinite loop */
00361     sdConnected = 0;
00362 
00363     if (CardIsConnected(0)) {
00364         if (sdConnected == 0) {
00365             sdConnected = 1;
00366             printf("-I- connect to solt n\r");
00367             CardInit(pSd);
00368 
00369             SD_DumpCID(pSd->CID);
00370             SD_DumpCSD(pSd->CSD);
00371             SD_DumpExtCSD(pSd->EXT);
00372             MEDSdusb_Initialize(&medias[DRV_SDMMC], pSd);
00373         }
00374     } else if (sdConnected) {
00375         sdConnected = 0;
00376         printf("** Card Disconnected\n\r");
00377     }
00378 
00379     LUN_Init(&(luns[DRV_SDMMC]),
00380              &(medias[DRV_SDMMC]),
00381              mSdBuffer, MSD_BUFFER_SIZE,
00382              0, 0, 0, 0,
00383              MSDCallbacks_Data);
00384 }
00385 
00386 /**
00387  * Initialize SDRAM to assign RamDisk block
00388  */
00389 static void RamDiskInit(void)
00390 {
00391     TRACE_INFO("RamDisk @ %x, size %d\n\r", (RAMDISK_BASE_ADDR), RAMDISK_SIZE);
00392 
00393     MEDRamDisk_Initialize(&(medias[DRV_RAMDISK]),
00394                           BLOCK_SIZE,
00395                           (RAMDISK_BASE_ADDR) / BLOCK_SIZE,
00396                           RAMDISK_SIZE / BLOCK_SIZE,
00397                           1);
00398     LUN_Init(&(luns[DRV_RAMDISK]),
00399              &(medias[DRV_RAMDISK]),
00400              mRamBuffer, MSD_BUFFER_SIZE,
00401              0, 0, 0, 0,
00402              MSDCallbacks_Data);
00403 }
00404 
00405 /**
00406  * Initialize MSD Media & LUNs
00407  */
00408 static void _MemoriesInitialize(sSdCard *pSd)
00409 {
00410     uint32_t i;
00411 
00412     /* Reset all LUNs */
00413     for (i = 0; i < MAX_LUNS; i ++)
00414         LUN_Init(&luns[i], 0, 0, 0, 0, 0, 0, 0, 0);
00415 
00416     BOARD_ConfigureSdram();
00417     /*Initialize SD Card  */
00418     SDDiskInit(pSd);
00419 
00420     /*Initialize RAM disk */
00421     RamDiskInit();
00422 
00423     gNbMedias = 2;
00424 }
00425 /**
00426  * Configure USBHS settings for USB device
00427  */
00428 static void _ConfigureUotghs(void)
00429 {
00430     /* UTMI parallel mode, High/Full/Low Speed */
00431     /* UUSBCK not used in this configuration (High Speed) */
00432     PMC->PMC_SCDR = PMC_SCDR_USBCLK;
00433     /* USB clock register: USB Clock Input is UTMI PLL */
00434     PMC->PMC_USB = PMC_USB_USBS;
00435     /* Enable peripheral clock for USBHS */
00436     PMC_EnablePeripheral(ID_USBHS);
00437     USBHS->USBHS_CTRL = USBHS_CTRL_UIMOD_DEVICE;
00438     /* Enable PLL 480 MHz */
00439     PMC->CKGR_UCKR = CKGR_UCKR_UPLLEN | CKGR_UCKR_UPLLCOUNT(0xF);
00440 
00441     /* Wait that PLL is considered locked by the PMC */
00442     while (!(PMC->PMC_SR & PMC_SR_LOCKU));
00443 
00444     /* IRQ */
00445     NVIC_SetPriority(USBHS_IRQn, USBHS_PRI);
00446     NVIC_EnableIRQ(USBHS_IRQn);
00447 }
00448 /*----------------------------------------------------------------------------
00449  *        Exported functions
00450  *----------------------------------------------------------------------------*/
00451 
00452 /**
00453  * \brief usb_massstorage Application entry point.
00454  *
00455  * Configures UART,
00456  * Configures TC0, USB MSD Driver and run it.
00457  *
00458  * \return Unused (ANSI-C compatibility).
00459  */
00460 int main(void)
00461 {
00462     sSdCard *pSd = 0;
00463 
00464     /* Disable watchdog */
00465     WDT_Disable(WDT);
00466 
00467     SCB_EnableICache();
00468     SCB_EnableDCache();
00469 
00470     printf("-- USB Device Mass Storage Example %s --\n\r", SOFTPACK_VERSION);
00471     printf("-- %s\n\r", BOARD_NAME);
00472     printf("-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__ ,
00473             COMPILER_NAME);
00474 
00475     /* If they are present, configure Vbus & Wake-up pins */
00476     PIO_InitializeInterrupts(0);
00477 
00478     /* Initialize all USB power (off) */
00479     _ConfigureUotghs();
00480     /* Initialize PIO pins */
00481     _ConfigurePIOs();
00482 
00483     /* Initialize drivers */
00484     _ConfigureDrivers();
00485 
00486     _MemoriesInitialize(pSd);
00487 
00488     /* BOT driver initialization */
00489     MSDDriver_Initialize(&msdDriverDescriptors, luns, MAX_LUNS);
00490 
00491     /* connect if needed */
00492     USBD_Connect();
00493 
00494     while (1) {
00495         /* Mass storage state machine */
00496         if (USBD_GetState() < USBD_STATE_CONFIGURED) {}
00497         else {
00498             MSDDriver_StateMachine();
00499 
00500             if (msdRefresh) {
00501                 msdRefresh = 0;
00502 
00503                 if (msdWriteTotal < 50 * 1000) {
00504                     /* Flush Disk Media */
00505                 }
00506 
00507                 msdWriteTotal = 0;
00508             }
00509         }
00510     }
00511 }
00512 /** \endcond */
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines