SAMV71 Xplained Ultra Software Package 1.3

main.c

Go to the documentation of this file.
00001 /* ----------------------------------------------------------------------------
00002  *         SAM Software Package License 
00003  * ----------------------------------------------------------------------------
00004  * Copyright (c) 2012, 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_multimedia_card Basic MultiMediaCard Example
00031  *
00032  *  \section Purpose
00033  *
00034  *  The Basic MultiMediaCard 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 SD and MMC operation flow which can be used for fast implementation
00037  *  of your own SD/MMC 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  *  Open HyperTerminal before running this program, the HyperTerminal will
00046  *  give out the test hints, you can run different tests on a inserted card.
00047  *
00048  *  \section Usage
00049  *
00050  * The MultiMedia Card Example offers a set of functions to perform
00051  *  MultiMedia Card tests:
00052  *  -# Dump MultiMedia Card information
00053  *  -# Test all blocks on MultiMedia Card
00054  *  -# Test R/W Speed (performance) of the MultiMedia Card
00055  *  You can find following information depends on your needs:
00056  *  - Usage of auto detection of sdcard insert and sdcard write-protection
00057  *  - (HS)MCI interface initialize sequence and interrupt installation
00058  *  - SD/MMC card driver implementation based on (HS)MCI interface
00059  *  - SD card physical layer initialize sequence implementation
00060  *  - MMC card physical layer initialize sequence implementation
00061  *  - Sample usage of SD/MMC card write and read
00062  *
00063  *  -# Build the program and download it inside the SAM V71 Xplained Ultra board. 
00064  *     Please refer to the Getting Started with SAM V71 Microcontrollers.pdf
00065  *  -# On the computer, open and configure a terminal application
00066  *     (e.g. HyperTerminal on Microsoft Windows) with these settings:
00067  *    - 115200 bauds
00068  *    - 8 bits of data
00069  *    - No parity
00070  *    - 1 stop bit
00071  *    - No flow control
00072  *  -# Start the application
00073  *  -# In HyperTerminal, it will show something like on start up
00074  *      \code
00075  *      -- MultiMedia Card Example xxx --
00076  *      -- SAMxxxxx-xx
00077  *      -- Compiled: xxx xx xxxx xx:xx:xx --
00078  *      -I- Cannot check if SD card is write-protected
00079  *
00080  *      ==========================================
00081  *      -I- Card Type 1, CSD_STRUCTURE 0
00082  *      -I- SD 4-BITS BUS
00083  *      -I- CMD6(1) arg 0x80FFFF01
00084  *      -I- SD HS Not Supported
00085  *      -I- SD/MMC TRANS SPEED 25000 KBit/s
00086  *      -I- SD/MMC card initialization successful
00087  *      -I- Card size: 483 MB, 990976 * 512B
00088  *      ...
00089  *      \endcode
00090  *  -# Test function menu is like this
00091  *      \code
00092  *      # i,I   : Re-initialize card
00093  *      # t     : Disk R/W/Verify test
00094  *      # T     : Disk performance test
00095  *      # p     : Change number of blocks in one access for test
00096  *      \endcode
00097  *
00098  *  \par See Also
00099  *  - \ref hsmci_sdcard : Another Simple Example for SD/MMC access.
00100  *  - \ref sdmmc_lib : SD/MMC card driver with mci-interface.
00101  *  - \ref hsmci_module : sdcard physical layer driver with hsmci-interface.
00102  *
00103  *  \section References
00104  *  - hsmci_multimedia_card/main.c
00105  *  - hsmci.h
00106  *  - pio.h
00107  */
00108 
00109 /**
00110  *  \file
00111  *
00112  * This file contains all the specific code for the hsmci_multimedia_card example.
00113  *
00114  *  \section Purpose
00115  *
00116  *  \section Contents
00117  *  The hsmci_multimedia_card application can be roughly broken down as follows:
00118  *     - Optional functions for detection (card insert, card protect)
00119  *        - CardDetectConfigure(), CardIsConnected()
00120  *        - CardIsProtected()
00121  *     - Interrupt handlers
00122  *        - MCI_IrqHandler()
00123  *     - The main function, which implements the program behaviour
00124  *        - I/O configuration
00125  *        - SD/MMC card auto-detect write-protected-check (if supported)
00126  *        - Initialize MCI interface and installing an isr relating to MCI
00127  *        - Initialize sdcard, get necessary sdcard's parameters
00128  *        - write/read sdcard
00129  */
00130 
00131 /*----------------------------------------------------------------------------
00132  *         Headers
00133  *----------------------------------------------------------------------------*/
00134 
00135 #include "board.h"
00136 #include "libsdmmc.h"
00137 
00138 #include <stdint.h>
00139 #include <stdio.h>
00140 #include <string.h>
00141 #include <assert.h>
00142 
00143 
00144 /*----------------------------------------------------------------------------
00145  *         Local definitions
00146  *----------------------------------------------------------------------------*/
00147 
00148 /** Maximum number of blocks read once (for performance test) */
00149 #define NB_MULTI_BLOCKS     64//8192
00150 
00151 /** Split R/W to 2, first R/W 4 blocks then remaining */
00152 #define NB_SPLIT_MULTI      4
00153 
00154 /** Test settings: start block address (0) */
00155 #define TEST_BLOCK_START    (0)
00156 
00157 /** Test settings: end block address (total SD/MMC) */
00158 #define TEST_BLOCK_END      SD_GetNumberBlocks(&sdDrv[bMciID])
00159 
00160 /** Test settings: skip size when "skip" key pressed */
00161 #define TEST_BLOCK_SKIP     (100 * 1024 * 2)    // 100M
00162 
00163 /** Test settings: Number of bytes to test performance */
00164 #define TEST_PERFORMENCT_SIZE   (4*1024*1024)
00165 
00166 /** Test settings: The value used to generate test data */
00167 #define TEST_FILL_VALUE_U32     (0x5A6C1439)
00168 
00169 /** Number of errors displayed */
00170 #define NB_ERRORS       3
00171 
00172 /** Number of bad blocks displayed */
00173 #define NB_BAD_BLOCK    200
00174 
00175 /*----------------------------------------------------------------------------
00176  *         Local variables
00177  *----------------------------------------------------------------------------*/
00178 
00179 /** DMA driver instance */
00180 static sXdmad dmaDrv;
00181 
00182 /** MCI driver instance. */
00183 static sMcid mciDrv[2];
00184 
00185 static sSdCard sdDrv[2];
00186 
00187 /** Current selected MCI interface */
00188 static uint8_t bMciID = 0;
00189 
00190 /** SD card pins instance. */
00191 static const Pin pinsSd[] = {BOARD_MCI_PINS_SLOTA, BOARD_MCI_PIN_CK};
00192 
00193 /** SD card detection pin instance. */
00194 static const Pin pinsCd[] = {BOARD_MCI_PIN_CD};
00195 
00196 static uint8_t pBuffer[SDMMC_BLOCK_SIZE * NB_MULTI_BLOCKS];
00197 
00198 /** Number or errors detected */
00199 static uint32_t nbErrors;
00200 
00201 /** Number of block r/w once to test performance */
00202 static uint32_t performanceMultiBlock = NB_MULTI_BLOCKS;
00203 
00204 /*----------------------------------------------------------------------------
00205  *         Local macros
00206  *----------------------------------------------------------------------------*/
00207 
00208 /* Defined to test Multi-Block functions */
00209 
00210 /** \def READ_MULTI
00211  *  \brief Define to test multi-read (SD_Read())
00212  *         or
00213  *         single-read is used (SD_ReadBlocks()) */
00214 #define READ_MULTI
00215 /** \def WRITE_MULTI
00216  *  \brief Define to test multi-write (SD_Write())
00217  *         or
00218  *         single-write is used (SD_WriteBlocks()) */
00219 #define WRITE_MULTI
00220 
00221 /** \macro SDT_ReadFun
00222  * Function used for SD card test reading.
00223  * \param pSd  Pointer to a SD card driver instance.
00224  * \param address  Address of the block to read.
00225  * \param nbBlocks Number of blocks to be read.
00226  * \param pData    Data buffer whose size is at least the block size.
00227  */
00228 #ifdef  READ_MULTI
00229 #define MMCT_ReadFun(pSd, blk, nbBlk, pData) \
00230     SD_Read(pSd, blk, pData, nbBlk, NULL, NULL)
00231 #else
00232 #define MMCT_ReadFun(pSd, blk, nbBlk, pData) \
00233     SD_ReadBlocks(pSd, blk, pData, nbBlk)
00234 #endif
00235 
00236 /** \macro SDT_WriteFun
00237  * Function used for SD card test writing.
00238  * \param pSd  Pointer to a SD card driver instance.
00239  * \param address  Address of the block to read.
00240  * \param nbBlocks Number of blocks to be read.
00241  * \param pData    Data buffer whose size is at least the block size.
00242  */
00243 #ifdef  WRITE_MULTI
00244 #define MMCT_WriteFun(pSd, blk, nbBlk, pData) \
00245     SD_Write(pSd, blk, pData, nbBlk, NULL, NULL)
00246 #else
00247 #define MMCT_WriteFun(pSd, blk, nbBlk, pData) \
00248     SD_WriteBlocks(pSd, blk, pData, nbBlk)
00249 #endif
00250 
00251 /*----------------------------------------------------------------------------
00252  *         Local functions
00253  *----------------------------------------------------------------------------*/
00254 
00255 /**
00256  * DMA interrupt handler.
00257  */
00258 void XDMAC_Handler(void)
00259 {
00260     XDMAD_Handler(&dmaDrv);
00261 }
00262 
00263 
00264 /**
00265  * MCI interrupt handler. Forwards the event to the MCI driver handlers.
00266  */
00267 void HSMCI_Handler(void)
00268 {
00269     uint32_t i;
00270     for (i = 0; i < BOARD_NUM_MCI; i ++) {
00271         MCID_Handler(&mciDrv[i]);
00272     }
00273 }
00274 
00275 /*----------------------------------------------------------------------------
00276  *         Optional: SD card detection (connection, protection)
00277  *----------------------------------------------------------------------------*/
00278 
00279 /**
00280  * Configure for SD detect pin
00281  */
00282 static void CardDetectConfigure(void)
00283 {
00284     PIO_Configure(pinsCd, PIO_LISTSIZE(pinsCd));
00285     /* No protection detect pin */
00286 }
00287 
00288 /**
00289  * Check if the card is connected.
00290  * \param iMci Controller number.
00291  * Return 1 if card is inserted.
00292  */
00293 static uint8_t CardIsConnected(uint8_t iMci)
00294 {
00295     return PIO_Get(&pinsCd[iMci]) ? 0 : 1;
00296 }
00297 
00298 /**
00299  * Check if the card is write protected.
00300  * \param iMci Controller number.
00301  * Return 1 if card is protected.
00302  */
00303 static uint8_t CardIsProtected(void)
00304 {
00305     printf("-I- Cannot check if SD card is write-protected\n\r");
00306     return 0;
00307 }
00308 
00309 /**
00310  * Get Dec Input
00311  * \param numChar Number of character to wait.
00312  * \param pInt    Pointer to uint32_t for input result.
00313  * \return 0 if valid data input.
00314  */
00315 static uint8_t GetDecInput(uint8_t numChar, uint32_t *pInt)
00316 {
00317     uint8_t key;
00318     uint32_t  i;
00319     uint32_t  result = 0;
00320     for (i = 0; i < numChar;) {
00321         key = DBG_GetChar();
00322         if (key == 27 ) {
00323             printf(" Canceled\n\r");
00324             return key;
00325         }
00326         if (key > '9' || key < '0') continue;
00327         DBG_PutChar(key);
00328         result = result * 10 + (key - '0');
00329         i ++;
00330     }
00331     if (pInt) *pInt = result;
00332     return 0;
00333 }
00334 
00335 /**
00336  * \brief Max Error Break
00337  * Check if max number of error achieved.
00338  * \param halt Whether halt the device if error number achieved.
00339  */
00340 static uint8_t MaxErrorBreak(uint8_t halt)
00341 {
00342     if (NB_ERRORS) {
00343         if (nbErrors ++ > NB_ERRORS) {
00344             while(halt);
00345             nbErrors = 0;
00346             return 1;
00347         }
00348     }
00349     return 0;
00350 }
00351 
00352 /**
00353  * Display: Dump Splitting row
00354  */
00355 static void DumpSeperator(void)
00356 {
00357     printf("\n\r==========================================\n\r");
00358 }
00359 
00360 /**
00361  * Display: Dump main menu
00362  */
00363 static void DumpMenu(void)
00364 {
00365     DumpSeperator();
00366     printf("-!- MCK is %uMHz\n\r", (unsigned)BOARD_MCK/1000000);
00367     printf("-!- Buffer@%x,size 0x%x\n\r", (unsigned int)pBuffer, sizeof(pBuffer));
00368     printf("# C     : Change number of blocks in one access for test\n\r");
00369     printf("# D     : Dump block contents\n\r");
00370     printf("# I     : Re-initialize card\n\r");
00371     printf("# T     : Disk R/W/Verify test\n\r");
00372     printf("# P     : Disk performance test\n\r");
00373     printf("# R     : Read verify only test\n\r");
00374     printf("# V     : Read verify with performance test\n\r");
00375 }
00376 
00377 /**
00378  * Dump buffer
00379  * \param pData Pointer to data buffer.
00380  * \param len   Buffer length.
00381  */
00382 static void DumpBuffer(unsigned char * pData, unsigned int len)
00383 {
00384     uint32_t i;
00385     printf("-I- buffer %u: %c .. %c .. %c .. %c..",
00386             len, pData[0], pData[3], pData[8], pData[8+5]);
00387     for (i = 0; i < len; i ++) {
00388         if((i % 16) == 0) printf("\n\r%3x:", (unsigned int)i);
00389         printf(" %02X", pData[i]);
00390     }
00391     printf("\n\r");
00392 }
00393 
00394 /**
00395  * Dump block & information
00396  * \param pData Pointer to data block.
00397  * \param block Block number.
00398  */
00399 static void DumpBlock(uint8_t * pData, uint32_t block)
00400 {
00401     uint32_t i;
00402     printf("-I- Block %d: %c .. %c .. %c .. %c..",
00403             (int)block, pData[0], pData[3], pData[8], pData[8+5]);
00404     for (i = 0; i < 512; i ++) {
00405         if((i % 16) == 0) printf("\n\r%3x:", (unsigned int)i);
00406         printf(" %02X", pData[i]);
00407     }
00408     printf("\n\r");
00409 }
00410 
00411 /**
00412  * Dump card registers
00413  * \param iMci Controller number.
00414  */
00415 static void DumpCardInfo(uint8_t iMci)
00416 {
00417     sSdCard *pSd = &sdDrv[iMci];
00418 
00419     if (SD_GetCardType(pSd) & CARD_TYPE_bmSDIO) {
00420         SDIO_DumpCardInformation(pSd);
00421     }
00422     if (SD_GetCardType(pSd) & CARD_TYPE_bmSDMMC) {
00423         SD_DumpCID(pSd->CID);
00424         SD_DumpCSD(pSd->CSD);
00425     }
00426 }
00427 
00428 /**
00429  * Run tests on the inserted card
00430  * \param iMci Controller number.
00431  */
00432 static void CardInit(uint8_t iMci)
00433 {
00434     sSdCard *pSd = &sdDrv[iMci];
00435     uint8_t error;
00436     uint8_t retry = 2;
00437 
00438     DumpSeperator();
00439 
00440     while(retry --) {
00441         error = SD_Init(pSd);
00442         if (error == SDMMC_OK) break;
00443     }
00444     if (error) {
00445         printf("-E- SD/MMC card initialization failed: %d\n\r", error);
00446         return;
00447     }
00448     printf("-I- SD/MMC card initialization successful\n\r");
00449     if (SD_GetCardType(pSd) & CARD_TYPE_bmSDMMC) {
00450         printf("-I- MEM Card OK, size: %d MB", (int)SD_GetTotalSizeKB(pSd)/1000);
00451         printf(", %d * %dB\n\r", (int)SD_GetNumberBlocks(pSd), 
00452             (int)SD_GetBlockSize(pSd));
00453     }
00454     if (SD_GetCardType(pSd) & CARD_TYPE_bmSDIO) {
00455         printf("-I- IO Card Detected OK\n\r");
00456     }
00457     DumpCardInfo(iMci);
00458 }
00459 
00460 /**
00461  * Block Dump (read)
00462  * \param iMci Controller number.
00463  */
00464 static void BlockDump(uint8_t iMci)
00465 {
00466     sSdCard *pSd = &sdDrv[iMci];
00467     uint32_t block;
00468     DumpSeperator();
00469     printf("-!- Input block:");
00470     if (GetDecInput(5, &block)) {
00471         return;
00472     }
00473     printf("\n\r-I- Dump Block %d: %d\n\r", 
00474         (int)block, MMCT_ReadFun(pSd, block, 1, pBuffer));
00475     DumpBlock(pBuffer, block);
00476 }
00477 
00478 /**
00479  * Sdio test
00480  * \param iMci Controller number.
00481  */
00482 static void SdioTest(uint8_t iMci)
00483 {
00484     sSdCard *pSd = &sdDrv[iMci];
00485     uint32_t i;
00486 
00487     DumpSeperator();
00488 
00489     /* SDIO always has FN1(IEN.1) and Mem(IEN.0), test with these bits */
00490     printf("R/W Direct test:\n\r");
00491 
00492     printf("CIA:\n\r");
00493     SDIO_ReadDirect(pSd, SDIO_CIA, 0, &pBuffer[0], 0x14);
00494     DumpBuffer(pBuffer, 0x14);
00495     printf("Write 0x03 to IEN(CIA.4): rc %d\n\r",
00496             SDIO_WriteDirect(pSd, SDIO_CIA, SDIO_IEN_REG, 0x03));
00497     printf("IEN After Write:");
00498     SDIO_ReadDirect(pSd, SDIO_CIA, SDIO_IEN_REG, &pBuffer[1], 1);
00499     printf("0x%02X\n\r", pBuffer[1]);
00500     if (0x03 == pBuffer[1]) {
00501         printf("-- test OK\n\r");
00502     } else {
00503         printf("-- test FAIL\n\r");
00504     }
00505     SDIO_WriteDirect(pSd, SDIO_CIA, SDIO_IEN_REG, pBuffer[SDIO_IEN_REG]);
00506 
00507     printf("R/W Extended test:\n\r");
00508     printf("Dump CIA:\n\r");
00509     for (i = 0; i < 0x40; i ++) pBuffer[i] = 0xFF; /* Clear Buffer */
00510     SDIO_ReadBytes(pSd, SDIO_CIA, 0, 0, pBuffer, 0x39, 0, 0);
00511     DumpBuffer(pBuffer, 0x14);
00512 
00513     printf("Modify Some R/W bytes (2,4) for FN0 and write:\n\r");
00514     pBuffer[0x2] = 0x2; /* IOE */
00515     pBuffer[0x4] = 0x2; /* IEN */
00516     /* Dont write to CIA.0x7, CIA.0xD or operation pause transfer */
00517     SDIO_WriteBytes(pSd, SDIO_CIA, 2, 0, &pBuffer[2], 5/*(0xC-2)*/, 0, 0);
00518     printf("CIA after write:\n\r");
00519     //SDIO_ReadDirect(pSd, SDIO_CIA, 0, pBuffer, 0x14);
00520     SDIO_ReadBytes(pSd, SDIO_CIA, 0, 0, pBuffer, 0x14, 0, 0);
00521     DumpBuffer(pBuffer, 0x14);
00522     if (pBuffer[0x2] != 0x2) {
00523         printf("-- CIA.2 Fail\n\r");
00524     }
00525     else if (pBuffer[0x4] != 0x2) {
00526         printf("-- CIA.4 Fail\n\r");
00527     } else {
00528         printf("-- test OK\n\r");
00529     }
00530     /* Restore data to 0 */
00531     SDIO_WriteDirect(pSd, SDIO_CIA, SDIO_IOE_REG, 0);
00532     SDIO_WriteDirect(pSd, SDIO_CIA, SDIO_IEN_REG, 0);
00533 }
00534 
00535 /**
00536  * Sdio performance test
00537  * \param iMci Controller number.
00538  */
00539 static void SdioPerformanceTest(uint8_t iMci)
00540 {
00541     sSdCard *pSd = &sdDrv[iMci];
00542     uint32_t i, blkSize = 1, totalNb = 0;
00543     uint32_t tickStart, tickEnd, ticks, rwSpeed;
00544 
00545     DumpSeperator();
00546     printf("-I- IO Performance test, size %dK, MCK %dMHz\n\r",
00547             TEST_PERFORMENCT_SIZE/1024,
00548             (int)(BOARD_MCK/1000000));
00549     printf("Read Direct  speed: ");
00550     tickStart = GetTicks();
00551     for (totalNb = 0;;) {
00552         if (SDIO_ReadDirect(pSd, SDIO_CIA, 0, &pBuffer[0], 0x14)) {
00553             return;
00554         }
00555         totalNb += 0x14;
00556         tickEnd = GetTicks();
00557         ticks = GetDelayInTicks(tickStart, tickEnd);
00558         if (ticks > 800) break;
00559     }
00560     rwSpeed = totalNb / ticks;
00561     printf("%uK\n\r", (unsigned int)rwSpeed);
00562     printf("Write Direct speed: ");
00563     tickStart = GetTicks();
00564     for (totalNb = 0;;) {
00565         for (i = 0; i < 0x14; i ++) {
00566             if (SDIO_WriteDirect(pSd,
00567                         SDIO_CIA,
00568                         SDIO_IEN_REG,
00569                         pBuffer[SDIO_IEN_REG])) {
00570                 return;
00571             }
00572         }
00573         totalNb += 0x14;
00574         tickEnd = GetTicks();
00575         ticks = GetDelayInTicks(tickStart, tickEnd);
00576         if (ticks > 800) break;
00577     }
00578     rwSpeed = totalNb / ticks;
00579     printf("%uK\n\r", (unsigned int)rwSpeed);
00580 
00581     printf("R/W Extended test:\n\r");
00582     for (blkSize = 4; blkSize <= 512; blkSize <<= 1) {
00583         printf("- Cnt %3u: ", (unsigned int)blkSize);
00584         tickStart = GetTicks();
00585         for (totalNb = 0;;) {
00586             if (SDIO_ReadBytes(pSd,
00587                         SDIO_CIA, 0,
00588                         0,
00589                         pBuffer, blkSize,
00590                         0, 0)) {
00591                 return;
00592             }
00593             totalNb += blkSize;
00594             tickEnd = GetTicks();
00595             ticks = GetDelayInTicks(tickStart, tickEnd);
00596             if (ticks > 800) break;
00597         }
00598         rwSpeed = totalNb / ticks;
00599         printf("R %5uK, ", (unsigned int)rwSpeed);
00600 
00601         for (i = 0; i < blkSize; i ++)
00602             pBuffer[i] = pBuffer[SDIO_IEN_REG];
00603         tickStart = GetTicks();
00604         for (totalNb = 0;;) {
00605             if (SDIO_WriteBytes(pSd,
00606                         SDIO_CIA, SDIO_IEN_REG,
00607                         1,
00608                         pBuffer, blkSize,
00609                         0, 0)) {
00610                 return;
00611             }
00612             totalNb += blkSize;
00613             tickEnd = GetTicks();
00614             ticks = GetDelayInTicks(tickStart, tickEnd);
00615             if (ticks > 800) break;
00616         }
00617         rwSpeed = totalNb / ticks;
00618         printf("W %5uK", (unsigned int)rwSpeed);
00619         printf("\n\r");
00620     }
00621 }
00622 
00623 /**
00624  * Disk test
00625  * \param iMci Controller number.
00626  * \param clr  Do block clear.
00627  * \param wr   Do block write.
00628  * \param rd   Do block read.
00629  */
00630 static void DiskTest(uint8_t iMci,
00631         uint8_t clr,
00632         uint8_t wr,
00633         uint8_t rd)
00634 {
00635     sSdCard *pSd = &sdDrv[iMci];
00636     uint8_t error = 0;
00637     uint32_t i, errcnt = 0;
00638     uint32_t multiBlock, block, splitMulti;
00639 
00640     DumpSeperator();
00641     printf("-!- Test code: 1.clr, 2.wr, 3.rd\n\r");
00642 
00643     /* Perform tests on each block */
00644     multiBlock = 0;
00645     for (block = TEST_BLOCK_START;
00646             block < TEST_BLOCK_END;
00647             block += multiBlock) {
00648 
00649         /* Perform different single or multiple bloc operations */
00650         if (multiBlock >= 16)   multiBlock <<= 1;
00651         else                    multiBlock ++;
00652         if (multiBlock > NB_MULTI_BLOCKS)
00653             multiBlock = 1;
00654 
00655         /* Multi-block adjustment */
00656         if (block + multiBlock > TEST_BLOCK_END) {
00657             multiBlock = TEST_BLOCK_END - block;
00658         }
00659 
00660         /* ** Perform single block or multi block transfer */
00661         printf("\r-I- Testing block [%6u - %6u] ...", 
00662             (unsigned int)block, (unsigned int)(block + multiBlock -1));
00663 
00664         if (clr) {
00665             /* - Clear the block */
00666             memset(pBuffer, 0, SDMMC_BLOCK_SIZE * multiBlock);
00667             for (i=0; i < SDMMC_BLOCK_SIZE * multiBlock; i++) {
00668                 if (pBuffer[i] != 0) {
00669                     /* Fatal error */
00670                     printf("\n\r-F- Data @ %u for write : 0x00 <> 0x%02x\n\r", 
00671                         (unsigned int)i, pBuffer[i]);
00672                     return;
00673                 }
00674             }
00675             error = MMCT_WriteFun(pSd, block, multiBlock, pBuffer);
00676             if (error) {
00677                 printf("\n\r-E- 1. Write block (%d) #%u\n\r", error, 
00678                     (unsigned int)block);
00679                 if(MaxErrorBreak(0)) return;
00680                 /* Skip following test */
00681                 continue;
00682             }
00683             /* - Read back the data to check the write operation */
00684             memset(pBuffer, 0xFF, SDMMC_BLOCK_SIZE * multiBlock);
00685             error = MMCT_ReadFun(pSd, block, multiBlock, pBuffer);
00686             if (error) {
00687                 printf("\n\r-E- 1. Read block (%d) #%u\n\r", error, 
00688                     (unsigned int)block);
00689                 if(MaxErrorBreak(0)) return;
00690                 /* Skip following test */
00691                 continue;
00692             }
00693             for (i=0; i < SDMMC_BLOCK_SIZE * multiBlock; i++) {
00694                 if (pBuffer[i] != 0) {
00695                     printf("\n\r-E- 1. B%u.D[%u] : 0 <> 0x%02X\n\r", 
00696                         (unsigned int)block, (unsigned int)i, (int)pBuffer[i]);
00697                     if(MaxErrorBreak(0)) return;
00698                     /* Only find first verify error. */
00699                     break;
00700                 }
00701             }
00702         }
00703 
00704         if (wr) {
00705             /* - Write a checker board pattern on the block */
00706             for (i=0; i < SDMMC_BLOCK_SIZE * multiBlock; i++) {
00707                 if ((i & 1) == 0)  pBuffer[i] = (i & 0x55);
00708                 else               pBuffer[i] = (i & 0xAA);
00709             }
00710             for (i = 0; i < multiBlock; ) {
00711                 splitMulti = ((multiBlock - i) > NB_SPLIT_MULTI) ?
00712                     NB_SPLIT_MULTI : (multiBlock - i);
00713                 error = MMCT_WriteFun(pSd,
00714                         block + i,
00715                         splitMulti,
00716                         &pBuffer[i * SDMMC_BLOCK_SIZE]);
00717                 if (error) break;
00718                 i += splitMulti;
00719             }
00720             if (error)
00721             {
00722                 printf("\n\r-E- 2. Write block #%u(%u+%u): %d\n\r",  
00723                     (unsigned int)(block+i), 
00724                     (unsigned int)block, 
00725                     (unsigned int)i, error);
00726                 if(MaxErrorBreak(0)) return;
00727                 /* Skip Following Test */
00728                 continue;
00729             }
00730         }
00731 
00732         if (rd) {
00733             /* - Read back the data to check the write operation */
00734             memset(pBuffer, 0, SDMMC_BLOCK_SIZE * multiBlock);
00735             for (i = 0; i < multiBlock; ) {
00736                 splitMulti = ((multiBlock - i) > NB_SPLIT_MULTI) ?
00737                     NB_SPLIT_MULTI : (multiBlock - i);
00738                 error = MMCT_ReadFun(pSd,
00739                         block + i,
00740                         splitMulti,
00741                         &pBuffer[i * SDMMC_BLOCK_SIZE]);
00742                 if (error) break;
00743                 i += splitMulti;
00744             }
00745             if (error)
00746             {
00747                 printf("\n\r-E- 2. Read block #%u(%u+%u): %d\n\r", 
00748                     (unsigned int)(block + i), 
00749                     (unsigned int)block, 
00750                     (unsigned int)i, error);
00751                 if(MaxErrorBreak(0)) return;
00752                 /* Skip Following Test */
00753                 continue;
00754             }
00755             errcnt = 0;
00756             for (i=0; i < SDMMC_BLOCK_SIZE * multiBlock; i++) {
00757 
00758                 if (!(((i & 1) == 0) && (pBuffer[i] == (i & 0x55))) &&
00759                         !(((i & 1) != 0) && (pBuffer[i] == (i & 0xAA))) ) {
00760                     uint32_t j, js;
00761                     printf("\n\r-E- 2.0x%x. Data @ %u (0x%x)\n\r", 
00762                         (unsigned int)errcnt, (unsigned int)i, (unsigned int)i);
00763                     printf("  -Src:");
00764                     js = (i > 8) ? (i - 8) : 0;
00765                     for (j = js; j < i + 8; j ++)
00766                         printf(" %02x", 
00767                         (unsigned int)(((j & 1)!= 0) ? (j & 0xAA):(j & 0x55)));
00768                     printf("\n\r  -Dat:");
00769                     for (j = js; j < i + 8; j ++)
00770                         printf("%c%02x", (i == j) ? '!' : ' ', pBuffer[j]);
00771                     printf("\n\r");
00772                     if(MaxErrorBreak(0)) return;
00773                     // Only find first 3 verify error.
00774                     if (errcnt ++ >= 3)
00775                         break;
00776                 }
00777             }
00778         }
00779 
00780         if (DBG_IsRxReady()) {
00781             switch(DBG_GetChar()) {
00782                 /* Skip 100M */
00783             case 'k':
00784                 block += TEST_BLOCK_SKIP;
00785                 if (block > TEST_BLOCK_END) {
00786                     block -= 5 + multiBlock;
00787                 }
00788                 printf("\n\r");
00789                 break;
00790                 /* Cancel */
00791             case 'c':
00792                 return;
00793             }
00794         }
00795     }
00796     printf("All block tested!\n\r");
00797 }
00798 
00799 /**
00800  * Run disk performance test
00801  * R/W test can be masked to verify previous written data only
00802  * \param iMci Controller number.
00803  * \param wr   Do block write.
00804  * \param rd   Do block read.
00805  * \param errDetail Dump detailed error information.
00806  */
00807 static void DiskPerformanceTest(uint8_t iMci,
00808         uint8_t wr,
00809         uint8_t rd,
00810         uint8_t errDetail)
00811 {
00812     sSdCard *pSd = &sdDrv[iMci];
00813     uint8_t error = 0;
00814     uint32_t  block, i, nBadBlock = 0, nErrors;
00815     uint32_t  tickStart, tickEnd, ticks, rwSpeed;
00816     uint32_t *pBuf;
00817     DumpSeperator();
00818     printf("-I- Performance test, size %dK, Multi %d, MCK %dMHz\n\r",
00819             TEST_PERFORMENCT_SIZE/1024,
00820             (int)performanceMultiBlock,
00821             (int)(BOARD_MCK/1000000));
00822 #ifdef READ_MULTI
00823     printf("-I- Read by Multi block, size %d\n\r", (int)SDMMC_BLOCK_SIZE);
00824 #else
00825     printf("-I- Read block by block, size %d\n\r", (int)SDMMC_BLOCK_SIZE);
00826 #endif
00827 #ifdef WRITE_MULTI
00828     printf("-I- Write by Multi block, size %d\n\r", (int)SDMMC_BLOCK_SIZE);
00829 #else
00830     printf("-I- Write block by block, size %d\n\r", (int)SDMMC_BLOCK_SIZE);
00831 #endif
00832 
00833     if (wr) {
00834         printf("--- Write test .. ");
00835         for (i = 0; i < SDMMC_BLOCK_SIZE * performanceMultiBlock; i += 4) {
00836             pBuf = (uint32_t*)(void*)(&pBuffer[i]);
00837             *pBuf = TEST_FILL_VALUE_U32;
00838         }
00839         nBadBlock = 0;
00840         tickStart = GetTicks();
00841         for (block = TEST_BLOCK_START;
00842                 block < (TEST_PERFORMENCT_SIZE/SDMMC_BLOCK_SIZE)
00843                 + TEST_BLOCK_START;
00844                 block += performanceMultiBlock) {
00845             pBuf = (uint32_t*)(void*)pBuffer;
00846             *pBuf = block;
00847             error = MMCT_WriteFun(pSd,
00848                     block, performanceMultiBlock,
00849                     pBuffer);
00850             if (error) {
00851                 if (nBadBlock ++ >= NB_BAD_BLOCK) {
00852                     printf("-E- WR_B(%u)\n\r", (unsigned int)block);
00853                     break;
00854                 }
00855                 else error = 0;
00856             }
00857         }
00858         tickEnd = GetTicks();
00859         ticks = GetDelayInTicks(tickStart, tickEnd);
00860         rwSpeed = (TEST_PERFORMENCT_SIZE
00861                 - nBadBlock * performanceMultiBlock * SDMMC_BLOCK_SIZE)
00862             / ticks;
00863         printf("Done, Bad %u, Speed %uK\n\r", 
00864             (unsigned int)nBadBlock, (unsigned int)rwSpeed);
00865     }
00866 
00867     if (rd) {
00868         printf("--- Read test .. ");
00869         nBadBlock = 0;
00870         tickStart = GetTicks();
00871         for (block = TEST_BLOCK_START;
00872                 block < (TEST_PERFORMENCT_SIZE/SDMMC_BLOCK_SIZE)
00873                 + TEST_BLOCK_START;
00874                 block += performanceMultiBlock) {
00875 
00876             error = MMCT_ReadFun(pSd,
00877                     block, performanceMultiBlock,
00878                     pBuffer);
00879             if (error) {
00880                 if (nBadBlock ++ >= NB_BAD_BLOCK) {
00881                     printf("-E- RD_B(%u)\n\r", (unsigned int)block);
00882                     break;
00883                 }
00884                 else error = 0;
00885             }
00886             if (error) break;
00887         }
00888         tickEnd = GetTicks();
00889         ticks = GetDelayInTicks(tickStart, tickEnd);
00890         rwSpeed = (TEST_PERFORMENCT_SIZE
00891                 - nBadBlock * performanceMultiBlock * SDMMC_BLOCK_SIZE)
00892             / ticks;
00893         printf("Done, read  %u, Speed %uK\n\r", 
00894             (unsigned int)(TEST_PERFORMENCT_SIZE - 
00895             nBadBlock * performanceMultiBlock * SDMMC_BLOCK_SIZE) / SDMMC_BLOCK_SIZE,
00896             (unsigned int)rwSpeed);
00897     }
00898 
00899     printf("--- Data verify .. ");
00900     nErrors = 0;
00901     for (block = TEST_BLOCK_START;
00902             block < (TEST_PERFORMENCT_SIZE/SDMMC_BLOCK_SIZE) + TEST_BLOCK_START;
00903             block += performanceMultiBlock) {
00904 
00905         memset(pBuffer, 0x00, SDMMC_BLOCK_SIZE * performanceMultiBlock);
00906         error = MMCT_ReadFun(pSd,
00907                 block, performanceMultiBlock,
00908                 pBuffer);
00909         if (error) {
00910             printf("-E- RD_B(%u)\n\r", (unsigned int)block);
00911             break;
00912         }
00913         pBuf = (uint32_t*)(void*)pBuffer;
00914         if (*pBuf != block) {
00915             if (errDetail) {
00916                 if (nErrors ++ < NB_ERRORS) {
00917                     printf("-E- Blk(%u)[0](%08x<>%08x)\n\r", 
00918                         (unsigned int)block, 
00919                         (unsigned int)block, 
00920                         (unsigned int)(*pBuf));
00921                 }
00922             }
00923             else {
00924                 printf("-E- BlkN(%x<>%x)\n\r", 
00925                     (unsigned int)block, (unsigned int)(*pBuf));
00926                 error = 1;
00927                 break;
00928             }
00929         }
00930         for (i = 4; i < SDMMC_BLOCK_SIZE * performanceMultiBlock; i += 4) {
00931             pBuf = (uint32_t*)(void*)(&pBuffer[i]);
00932             if ( (*pBuf != TEST_FILL_VALUE_U32)) {
00933                 if (errDetail) {
00934                     /* Dump 10 errors only */
00935                     if (nErrors ++ < NB_ERRORS) {
00936                         uint32_t j;
00937                         printf("-E- Blk(%u)[%u](%08x.. <>", 
00938                             (unsigned int)block, 
00939                             (unsigned int)i, 
00940                             (unsigned int)TEST_FILL_VALUE_U32);
00941                         for (j = (i > 4) ? (i - 4) : i;
00942                                 j <= i + 4;
00943                                 j += 4) {
00944                             printf("%c%08X",
00945                                     (i == j) ? '!' : ' ',
00946                                     (unsigned int)(*pBuf));
00947                         }
00948                         printf(")\n\r");
00949                     }
00950                 } else {
00951                     printf("-E- Blk(%u)[%u](%x<>%x)\n\r", 
00952                             (unsigned int)block, 
00953                             (unsigned int)i,
00954                             (unsigned int)TEST_FILL_VALUE_U32,
00955                             (unsigned int)(*pBuf));
00956                     error = 1;
00957                     break;
00958                 }
00959             }
00960         }
00961         if (error) break;
00962     }
00963     if (errDetail && nErrors) {
00964         printf("-I- %u u32 ERRORS found!\n\r", (unsigned int)nErrors);
00965     }
00966     if (error)
00967         return;
00968     printf("OK\n\r");
00969 }
00970 
00971 
00972 /**
00973  * Initialize PIOs
00974  */
00975 static void _ConfigurePIOs(void)
00976 {
00977     /* Configure SDcard pins */
00978     PIO_Configure(pinsSd, PIO_LISTSIZE(pinsSd));
00979     /* Configure SD card detection */
00980     CardDetectConfigure();
00981     CardIsProtected();
00982 }
00983 
00984 /**
00985  * Initialize driver instances.
00986  */
00987 static void _ConfigureDrivers(void)
00988 {
00989     uint32_t i;
00990     /* Initialize the DMA driver */
00991     XDMAD_Initialize(&dmaDrv,0);
00992 
00993     NVIC_ClearPendingIRQ(XDMAC_IRQn);
00994     NVIC_SetPriority(XDMAC_IRQn, 1);
00995     NVIC_EnableIRQ( XDMAC_IRQn );
00996 
00997     /* Initialize the HSMCI driver */
00998     MCID_Init(&mciDrv[0], HSMCI, ID_HSMCI, BOARD_MCK, &dmaDrv, 0 ) ;
00999 
01000     NVIC_ClearPendingIRQ(HSMCI_IRQn);
01001     NVIC_SetPriority(HSMCI_IRQn, 3);
01002     NVIC_EnableIRQ( HSMCI_IRQn );
01003 
01004     /* Initialize SD driver */
01005     for (i = 0; i < BOARD_NUM_MCI; i ++) {
01006         SDD_InitializeSdmmcMode(&sdDrv[i], &mciDrv[i], 0);
01007     }
01008 }
01009 
01010 /*----------------------------------------------------------------------------
01011  *         Global functions
01012  *----------------------------------------------------------------------------*/
01013 
01014 /**
01015  *  \brief hsmci_multimedia_card Application entry point.
01016  *
01017  *  \return Unused (ANSI-C compatibility).
01018  */
01019 int main(void)
01020 {
01021     uint8_t connected = 0;
01022 
01023     /* Disable watchdog */
01024     WDT_Disable( WDT ) ;
01025     
01026     SCB_EnableICache() ;
01027     SCB_EnableDCache() ;
01028     TimeTick_Configure() ;
01029 
01030     /* Output example information*/
01031     printf("-- MultiMedia Card Example %s --\n\r", SOFTPACK_VERSION);
01032     printf("-- %s\n\r", BOARD_NAME);
01033     printf( "-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__ , COMPILER_NAME);
01034     bMciID = 0;
01035     /* Initialize PIO pins */
01036     _ConfigurePIOs();
01037 
01038     /* Initialize drivers */
01039     _ConfigureDrivers() ;
01040 
01041 
01042     /* Card insert detection loop */
01043     for(;;) {
01044         if (CardIsConnected(bMciID)) {
01045             if (connected == 0) {
01046                 connected = 1;
01047                 /* Delay before card initialize */
01048                 Wait(300);
01049                 /* Do card test */
01050                 CardInit(bMciID);
01051                 DumpMenu();
01052             }
01053         } else if (connected) {
01054             connected = 0;
01055             printf("** Card Disconnected\n\r");
01056         }
01057         if (DBG_IsRxReady()) {
01058             uint8_t key = DBG_GetChar();
01059             switch(key) {
01060             /* Change performance test block size */
01061             case 'c':
01062             case 'C': {
01063                 if (performanceMultiBlock >= NB_MULTI_BLOCKS)
01064                     performanceMultiBlock = 1;
01065                 else
01066                     performanceMultiBlock <<= 1;
01067                     printf("-!- Performance Multi set to %d\n\r", (int)performanceMultiBlock);
01068                 }
01069                 break;
01070             /* Show help information */
01071             default:
01072                 if (!connected) {
01073                     DumpMenu();
01074                 } else {
01075                     switch(key) {
01076                     /* Dump block contents */
01077                     case 'd':
01078                     case 'D':
01079                         BlockDump(bMciID);
01080                         break;
01081                     /* Initialize the card again */
01082                     case 'I':
01083                     case 'i':
01084                         CardInit(bMciID);
01085                         break;
01086                     /* Run test on whole disk */
01087                     case 't':
01088                     case 'T':
01089                         if (SD_GetCardType(&sdDrv[bMciID]) & CARD_TYPE_bmSDIO)
01090                             SdioTest(bMciID);
01091                         if (SD_GetCardType(&sdDrv[bMciID]) & CARD_TYPE_bmSDMMC)
01092                             DiskTest(bMciID, 1, 1, 1);
01093                         printf("\n\r");
01094                         break;
01095                     /* Run performance test */
01096                     case 'P':
01097                     case 'p':
01098                         if (SD_GetCardType(&sdDrv[bMciID]) & CARD_TYPE_bmSDIO)
01099                             SdioPerformanceTest(bMciID);
01100                         if (SD_GetCardType(&sdDrv[bMciID]) & CARD_TYPE_bmSDMMC)
01101                             DiskPerformanceTest(bMciID, 1, 1, 0);
01102                         printf("\n\r");
01103                         break;
01104                     /* Read/Verify ONLY test */
01105                     case 'r': 
01106                     case 'R':
01107                         DiskTest(bMciID, 0, 0, 1);
01108                         printf("\n\r");
01109                         break;
01110                     /* Read/Verify ONLY performance test */
01111                     case 'V':
01112                     case 'v':
01113                         DiskPerformanceTest(bMciID, 0, 1, 1);
01114                         printf("\n\r");
01115                         break;
01116                     /* Show help information */
01117                     default:
01118                         DumpMenu();
01119                     }
01120                 }
01121             break;
01122             }
01123         }
01124     }
01125 }
01126 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines