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