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 /**
00031  * \page hsmci_sdio Basic SDIO Card Example
00032  *
00033  * \section Purpose
00034  *
00035  *  The Basic SDIO Card Example will help you to get familiar with HSMCI
00036  *  interface on SAM Microcontrollers. It can also help you to get familiar
00037  *  with the SDIO operation flow which can be used for fast implementation
00038  *  of your own SD drivers and other applications related.
00039  *
00040  *  \section Requirements
00041  *
00042  *  This package can be used with SAMV71 Xplained Ultra board or SAME70 Xplained board.
00043  *
00044  *  \section Description
00045  *
00046  *  The demonstration program detects SDIO device connected and perform
00047  *  R/W operation on it.
00048  *
00049  *  Open HyperTerminal before running this program, use SAM-BA to download
00050  *  this program to SRAM , make the program run, the HyperTerminal
00051  *  will give out the test results.
00052  *
00053  *  \section Usage
00054  *
00055  *  -# Build the program and download it inside the board.
00056  *     Please refer to the Getting Started with SAM V71/E70 Microcontrollers.pdf
00057  *  -# On the computer, open and configure a terminal application
00058  *     (e.g. HyperTerminal on Microsoft Windows) with these settings:
00059  *    - 115200 bauds
00060  *    - 8 bits of data
00061  *    - No parity
00062  *    - 1 stop bit
00063  *    - No flow control
00064  *  -# Start the application
00065  *  -# In HyperTerminal, it will show something like
00066  *      \code
00067  *      -- Basic HSMCI SDIO Example xxx --
00068  *      -- SAMxxxxx-xx
00069  *      -- Compiled: xxx xx xxxx xx:xx:xx --
00070  *      -I- Please connect a SD card ...
00071  *      -I- SD card connection detected
00072  *      -I- Cannot check if SD card is write-protected
00073  *      -I- SD/MMC card initialization successful
00074  *      R/W Direct test:
00075  *      ...
00076  *      \endcode
00077  *  -# After card inserted following commands can be used:
00078  *     - 'f' Change current function number
00079  *     - 'r' Dump SDIO register value
00080  *     - 'w' Write to SDIO register
00081  *
00082  *  \section References
00083  *  - hsmci_sdcard/main.c
00084  *  - hsmci.h
00085  *  - pio.h
00086  *
00087  */
00088 
00089 /**
00090  *  \file
00091  *
00092  *  \section Purpose
00093  *
00094  *  This file contains all the specific code for the hsmci_sdcard example.
00095  *
00096  *  \section Contents
00097  *  The hsmci_sdio application can be roughly broken down as follows:
00098  *     - Optional functions
00099  *        - CardDetectConfigure
00100  *        - CardIsConnected
00101  *     - Interrupt handlers
00102  *        - MCI_IrqHandler
00103  *     - The main function, which implements the program behaviour
00104  *        - I/O configuration
00105  *        - SD card auto-detect (if supported)
00106  *        - Initialize MCI interface and installing an isr relating to MCI
00107  *        - Initialize sdcard, get necessary sdcard's parameters
00108  *        - Test RW_DIRECT and RW_EXTENDED at SDIO CIA area.
00109  */
00110 /*----------------------------------------------------------------------------
00111  *         Headers
00112  *----------------------------------------------------------------------------*/
00113 
00114 #include "board.h"
00115 #include "libsdmmc.h"
00116 
00117 #include <stdint.h>
00118 #include <stdio.h>
00119 #include <string.h>
00120 #include <assert.h>
00121 
00122 /*----------------------------------------------------------------------------
00123  *         Local definitions
00124  *----------------------------------------------------------------------------*/
00125 
00126 /*----------------------------------------------------------------------------
00127  *         Local variables
00128  *----------------------------------------------------------------------------*/
00129 
00130 /** DMA driver instance */
00131 static sXdmad dmaDrv;
00132 
00133 /** MCI driver instance. */
00134 static sMcid mciDrv[BOARD_NUM_MCI];
00135 
00136 /** SDCard driver instance. */
00137 COMPILER_ALIGNED(32) static sSdCard sdDrv[BOARD_NUM_MCI];
00138 
00139 /** Current selected MCI interface */
00140 static uint8_t bMciID = 0;
00141 
00142 /** SD card pins instance. */
00143 static const Pin pinsSd[] = {BOARD_MCI_PINS_SLOTA, BOARD_MCI_PIN_CK};
00144 
00145 /** SD card detection pin instance. */
00146 static const Pin pinsCd[] = {BOARD_MCI_PIN_CD};
00147 
00148 /** Date buffer */
00149 COMPILER_ALIGNED(32) static uint8_t pBuffer[SDMMC_BLOCK_SIZE];
00150 
00151 /** Current function */
00152 static uint8_t curFunc = 0;
00153 
00154 /*----------------------------------------------------------------------------
00155  *         Local macros
00156  *----------------------------------------------------------------------------*/
00157 
00158 /*----------------------------------------------------------------------------
00159  *         Local functions
00160  *----------------------------------------------------------------------------*/
00161 
00162 /**
00163  * MCI interrupt handler. Forwards the event to the MCI driver handlers.
00164  */
00165 void HSMCI_Handler(void)
00166 {
00167     uint32_t i;
00168 
00169     for (i = 0; i < BOARD_NUM_MCI; i++)
00170         MCID_Handler(&mciDrv[i]);
00171 }
00172 
00173 void XDMAC_Handler(void)
00174 {
00175     XDMAD_Handler(&dmaDrv);
00176 }
00177 
00178 /*----------------------------------------------------------------------------
00179  *         Optional: SD card detection (connection, protection)
00180  *----------------------------------------------------------------------------*/
00181 
00182 /**
00183  * Configure for SD detect pin
00184  */
00185 static void CardDetectConfigure(void)
00186 {
00187     PIO_Configure(pinsCd, PIO_LISTSIZE(pinsCd));
00188     /* No protection detect pin */
00189 }
00190 
00191 /**
00192  * Return 1 if card is inserted.
00193  */
00194 static uint8_t CardIsConnected(uint8_t iMci)
00195 {
00196     return PIO_Get(&pinsCd[iMci]) ? 0 : 1;
00197 }
00198 
00199 #if 0
00200 /**
00201  * Return 1 if any card is inserted.
00202  */
00203 static uint8_t AnyCardIsConnected(void)
00204 {
00205     uint32_t i;
00206 
00207     for (i = 0; i < BOARD_NUM_MCI; i ++) {
00208         if (CardIsConnected(i))
00209             return 1;
00210     }
00211 
00212     return 0;
00213 }
00214 #endif
00215 
00216 /**
00217  * Return 1 if card is protected.
00218  */
00219 static uint8_t CardIsProtected(void)
00220 {
00221     printf("-I- Cannot check if SD card is write-protected\n\r");
00222     return 0;
00223 }
00224 
00225 /**
00226  * Delay some loop
00227  */
00228 static void LoopDelay(volatile unsigned int loop)
00229 {
00230     for (; loop > 0; loop--);
00231 }
00232 
00233 /**
00234  * Display: Dump Splitting row
00235  */
00236 static void DumpSeperator(void)
00237 {
00238     printf("\n\r==========================================\n\r");
00239 }
00240 
00241 /**
00242  * Dump buffer
00243  * \param pData Pointer to data buffer.
00244  * \param len   Buffer length.
00245  */
00246 static void DumpBuffer(unsigned char *pData, unsigned int len)
00247 {
00248     unsigned int i;
00249 
00250     printf("-I- buffer %u: %c .. %c .. %c .. %c..",
00251            len, pData[0], pData[3], pData[8], pData[8 + 5]);
00252 
00253     for (i = 0; i < len; i ++) {
00254         if ((i % 16) == 0) printf("\n\r%3x:", i);
00255 
00256         printf(" %02X", pData[i]);
00257     }
00258 
00259     printf("\n\r");
00260 }
00261 
00262 /**
00263  * \brief Get 32-bit number input (Dec or Hex).
00264  * Before first character input format can be changed once by
00265  * 'x' to hex.
00266  * \param nbChar Number of character to wait.
00267  * \param pNum   Pointer to uint32_t for input result.
00268  * \return 0 if valid data input.
00269  */
00270 static uint8_t GetU32Input(uint8_t nbChar, uint32_t *pU32)
00271 {
00272     uint8_t key, isHex = 0;
00273     uint32_t  i;
00274     uint32_t  result = 0;
00275 
00276     for (i = 0; i < nbChar;) {
00277         key = DBG_GetChar();
00278 
00279         /* User cancel input */
00280         if (key == 27) {
00281             printf(" Cancelled\n\r");
00282             return key;
00283         }
00284 
00285         /* Short input */
00286         if (key == '\r') break;
00287 
00288         if (key == 'x' && i == 0) {
00289             if (isHex == 0) {
00290                 isHex = 1;
00291                 DBG_PutChar(key);
00292             }
00293 
00294             continue;
00295         }
00296 
00297         if (key > '9' || key < '0') {
00298             if (isHex) {
00299                 if (key < 'a' || key > 'z')
00300                     continue;
00301             } else
00302                 continue;
00303         }
00304 
00305         DBG_PutChar(key);
00306 
00307         if (isHex) {
00308             if (key >= 'a')
00309                 result = result * 16 + (key - 'a' + 10);
00310             else
00311                 result = result * 16 + (key - '0');
00312         } else
00313             result = result * 10 + (key - '0');
00314 
00315         i++;
00316     }
00317 
00318     if (pU32) *pU32 = result;
00319 
00320     return 0;
00321 }
00322 
00323 /**
00324  *  Dump a register
00325  */
00326 static uint8_t DumpReg(uint8_t iMci)
00327 {
00328     uint32_t addr;
00329     uint32_t data;
00330 
00331     DumpSeperator();
00332     printf("Address to read: ");
00333 
00334     if (0 == GetU32Input(5, &addr)) {
00335         printf("\n\r");
00336 
00337         if (0 == SDIO_ReadDirect(&sdDrv[iMci], curFunc, addr, (uint8_t *)&data, 1)) {
00338             printf("- SDIO.%d.0x%x: 0x%x\n\r",
00339                    curFunc, (unsigned int)addr, (uint8_t)data);
00340         }
00341     }
00342 
00343     return 0;
00344 }
00345 
00346 /**
00347  *  Write a register
00348  */
00349 static uint8_t WriteReg(uint8_t iMci)
00350 {
00351     uint32_t addr;
00352     uint32_t data;
00353 
00354     DumpSeperator();
00355     printf("Address to write: ");
00356 
00357     if (0 == GetU32Input(5, &addr)) {
00358         printf("\n\rData to write: ");
00359 
00360         if (0 == GetU32Input(3, &data)) {
00361             printf("\n\r- SDIO.%d0x%x = 0x%x\n\r",
00362                    curFunc, (unsigned int)addr, (unsigned int)data);
00363             SDIO_WriteDirect(&sdDrv[iMci], curFunc, addr, data);
00364         }
00365     }
00366 
00367     return 0;
00368 }
00369 
00370 /**
00371  *  Initialize the inserted card
00372  */
00373 static uint8_t InitCard(uint8_t iMci)
00374 {
00375     sSdCard *pSd = &sdDrv[iMci];
00376     uint8_t rc;
00377 
00378     /* Initialize the SD card driver */
00379     rc = SD_Init(pSd);
00380 
00381     if (rc)
00382         printf("-E- SD/MMC initialization failed: %x\n\r", rc);
00383     else
00384         printf("-I- SD/MMC card initialization successful\n\r");
00385 
00386     if (SD_GetCardType(pSd) & CARD_TYPE_bmSDIO) {
00387         SDIO_DumpCardInformation(pSd);
00388         return 1;
00389     } else
00390         printf("-I- Not a SDIO card, type %x\n\r", SD_GetCardType(pSd));
00391 
00392     return 0;
00393 }
00394 
00395 /**
00396  *  Perform test on SDIO.CIA
00397  */
00398 static uint8_t TestCIA(uint8_t iMci)
00399 {
00400     sSdCard *pSd = &sdDrv[iMci];
00401 
00402     DumpSeperator();
00403     /* SDIO always has FN1(IEN.1) and Mem(IEN.0), test with these bits */
00404     printf("R/W Direct test:\n\r");
00405 
00406     printf("CIA:\n\r");
00407     SDIO_ReadDirect(pSd, SDIO_CIA, 0x0, &pBuffer[0], 0x14);
00408     DumpBuffer(pBuffer, 0x14);
00409 
00410     printf("Write 0x03 to IEN(CIA.4): rc %d\n\r",
00411            SDIO_WriteDirect(pSd, SDIO_CIA, SDIO_IEN_REG, 0x03));
00412     printf("IEN After Write:");
00413 
00414     SDIO_ReadDirect(pSd, SDIO_CIA, SDIO_IEN_REG, &pBuffer[4], 1);
00415     printf("0x%02X\n\r", pBuffer[4]);
00416 
00417     if (0x03 == pBuffer[4])
00418         printf("-- test OK\n\r");
00419     else
00420         printf("-- test FAIL\n\r");
00421 
00422     printf("R/W Extended test:\n\r");
00423     pBuffer[0x0] = 0x13;
00424     pBuffer[0x1] = 0x14;
00425     pBuffer[0x2] = 0x15;
00426     SDIO_WriteBytes(pSd, SDIO_CIA, 0xFD, 0, &pBuffer[0], 0x3, 0, 0);
00427 
00428     printf("CIA after write:\n\r");
00429     SDIO_ReadBytes(pSd, SDIO_CIA, 0xF0, 0, pBuffer, 0x10, 0, 0);
00430     DumpBuffer(pBuffer, 0x10);
00431 
00432     if (pBuffer[13] != 0x13)
00433         printf("-- CIA.2 Fail\n\r");
00434     else if (pBuffer[14] != 0x14)
00435         printf("-- CIA.4 Fail\n\r");
00436     else if (pBuffer[15] != 0x15)
00437         printf("-- CIA.4 Fail\n\r");
00438     else
00439         printf("-- test OK\n\r");
00440 
00441     /* Restore data to 0 */
00442     SDIO_WriteDirect(pSd, SDIO_CIA, SDIO_IOE_REG, 0);
00443     SDIO_WriteDirect(pSd, SDIO_CIA, SDIO_IEN_REG, 0);
00444 
00445     return 0;
00446 }
00447 
00448 /**
00449  * Initialize PIOs
00450  */
00451 static void _ConfigurePIOs(void)
00452 {
00453     /* Configure SDcard pins */
00454     PIO_Configure(pinsSd, PIO_LISTSIZE(pinsSd));
00455     /* Configure SD card detection */
00456     CardDetectConfigure();
00457     /* Configure SDcard power pins */
00458     //PIO_Configure(pinsPu, PIO_LISTSIZE(pinsPu));
00459     /* Check if card is write-protected (if supported) */
00460     CardIsProtected();
00461 }
00462 
00463 /**
00464  * Initialize driver instances.
00465  */
00466 static void _ConfigureDrivers(void)
00467 {
00468     uint32_t i;
00469 
00470     /* Initialize the DMA driver */
00471     XDMAD_Initialize(&dmaDrv, 0);
00472 
00473     NVIC_EnableIRQ(XDMAC_IRQn);
00474 
00475     /* Initialize the HSMCI driver */
00476     MCID_Init(&mciDrv[0], HSMCI, ID_HSMCI, BOARD_MCK, &dmaDrv, 0);
00477 
00478     NVIC_EnableIRQ(HSMCI_IRQn);
00479 
00480     /* Initialize SD driver */
00481     for (i = 0; i < BOARD_NUM_MCI; i++)
00482         SDD_InitializeSdmmcMode(&sdDrv[i], &mciDrv[i], 0);
00483 }
00484 
00485 
00486 /**
00487  * \brief Display menu.
00488  */
00489 static void _DisplayMenu(void)
00490 {
00491     printf("\n\r");
00492     printf("=========================================================\n\r");
00493     printf("Menu: press a key to test.\n\r");
00494     printf("---------------------------------------------------------\n\r");
00495     printf(" m: Switch SDIO connection (MCI0, MCI1).\n\r");
00496     printf(" r: Dump SDIO register value.\n\r");
00497     printf(" w: Write to SDIO register.\n\r");
00498     printf(" f: Change current function number.\n\r");
00499     printf("=========================================================\n\r");
00500 }
00501 
00502 /*----------------------------------------------------------------------------
00503  *         Global functions
00504  *----------------------------------------------------------------------------*/
00505 /**
00506  *  \brief hsmci_sdcard Application entry point.
00507  *
00508  *  \return Unused (ANSI-C compatibility).
00509  */
00510 int main(void)
00511 {
00512     uint8_t sdState = 0; /* 0: no card, 1: connected, 2: error */
00513 
00514     /* Disable watchdog */
00515     WDT_Disable(WDT);
00516 
00517     SCB_EnableICache();
00518     SCB_EnableDCache();
00519 
00520     /* Output example information */
00521     printf("-- Basic HSMCI SDIO Example %s --\n\r", SOFTPACK_VERSION);
00522     printf("-- %s\n\r", BOARD_NAME);
00523     printf("-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__ , COMPILER_NAME);
00524 
00525     /* Initialize PIO pins */
00526     _ConfigurePIOs();
00527 
00528     /* Initialize drivers */
00529     _ConfigureDrivers();
00530 
00531     while (1) {
00532         /* Check card connection */
00533         if (CardIsConnected(bMciID)) {
00534             if (sdState == 0) {
00535                 LoopDelay(BOARD_MCK / 50);
00536 
00537                 if (InitCard(bMciID)) {
00538                     sdState = 1;
00539                     TestCIA(bMciID);
00540                     _DisplayMenu();
00541                 } else
00542                     sdState = 2;
00543             }
00544         } else if (sdState) {
00545             printf("\n\r** Card disconnected\n\r");
00546             sdState = 0;
00547         }
00548 
00549         if (DBG_IsRxReady()) {
00550             uint8_t key = DBG_GetChar();
00551 
00552             switch (key | (sdState << 8)) {
00553             case 'm':
00554             case 0x100 | 'm':
00555             case 0x200 | 'm':
00556                 bMciID = !bMciID;
00557                 sdState = 0;
00558                 break;
00559 
00560             case 0x100 | 'r':
00561                 DumpReg(bMciID);
00562                 break;
00563 
00564             case 0x100 | 'w':
00565                 WriteReg(bMciID);
00566                 break;
00567 
00568             case 0x100 | 't':
00569                 TestCIA(bMciID);
00570                 printf("\n\r");
00571                 break;
00572 
00573             case 0x100 | 'f':
00574                 curFunc = ((curFunc + 1) % 7);
00575                 printf("** SDIO Function -> %d\n\r", curFunc);
00576                 break;
00577             }
00578 
00579             _DisplayMenu();
00580         }
00581     }
00582 }
00583 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines