SAM3S8/SD8 Software Package: examples_storage/hsmci_sdcard/main.c Source File

SAM3S8/SD8 Software Package 1.2

# main.c

Go to the documentation of this file.

    00001 /* ----------------------------------------------------------------------------
    00002  *         ATMEL Microcontroller Software Support
    00003  * ----------------------------------------------------------------------------
    00004  * Copyright (c) 2009, 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_sdcard HSMCI SD Card Example
    00031  *
    00032  * \section Purpose
    00033  *
    00034  *  The hsmci_sdcard will help you to get familiar with sdmmc_mci interface on
    00035  *  SAM microcontrollers. It can also help you to get familiar with the SD operation flow
    00036  *  which can be used for fast implementation of your own sd drivers and other applications
    00037  *  related.
    00038  *
    00039  * \section Related
    00040  *
    00041  *  You can find following information depends on your needs:
    00042  *  - Usage of auto detection of sdcard insert and sdcard write-protection detection
    00043  *  - MCI interface initialize sequence and interrupt installation
    00044  *  - Sdcard driver implementation based on MCI interface
    00045  *  - Sdcard physical layer initialize sequence implementation
    00046  *  - Sample usage of sdcard write and read
    00047  *
    00048  *  See
    00049  *
    00050  *  - \ref sdmmc_lib : SD/MMC Library.
    00051  *  - \ref hsmci_module : sdcard physical layer driver with hsmci interface.
    00052  *
    00053  *  \section Requirements
    00054  *
    00055  *  This package can be used with SAM3S evaluation kit 2.
    00056  *
    00057  *  \section Description
    00058  *
    00059  *  The demostration program detects, initialize the SD/MMC memory card
    00060  *  inserted, and performs R/W test on it.
    00061  *
    00062  *  \section Usage
    00063  *
    00064  *  -# Build the program and download it inside the evaluation board. Please
    00065  *     refer to the
    00066  *     <a href="http://www.atmel.com/dyn/resources/prod_documents/6421B.pdf">
    00067  *     SAM-BA User Guide</a>, the
    00068  *     <a href="http://www.atmel.com/dyn/resources/prod_documents/doc6310.pdf">
    00069  *     GNU-Based Software Development</a> application note or to the
    00070  *     <a href="http://www.iar.com/website1/1.0.1.0/78/1/">
    00071  *     IAR EWARM User and reference guides</a>, depending on your chosen solution.
    00072  *  -# On the computer, open and configure a terminal application
    00073  *     (e.g. HyperTerminal on Microsoft Windows) with these settings:
    00074  *    - 115200 bauds
    00075  *    - 8 bits of data
    00076  *    - No parity
    00077  *    - 1 stop bit
    00078  *    - No flow control
    00079  *  -# Start the application
    00080  *  -# In HyperTerminal, it will show something like
    00081  *      \code
    00082  *      -- HSMCI SD Card Example xxx --
    00083  *      -- xxxxxx-xx
    00084  *      -- Compiled: xxx xx xxxx xx:xx:xx --
    00085  *      -I- Please connect a SD card ...
    00086  *      -I- SD card connection detected
    00087  *      -I- Cannot check if SD card is write-protected
    00088  *      -I- SD/MMC card initialization successful
    00089  *      -I- Card size: *** MB
    00090  *      -I- Block size: *** Bytes
    00091  *      -I- Testing block [  *** -   ***] ..."
    00092  *      \endcode
    00093  *
    00094  *  \section References
    00095  *  - hsmci_sdcard/main.c
    00096  *  - hsmci.h
    00097  *  - pio.h
    00098  *
    00099  */
    00100
    00101 /**
    00102  *  \file
    00103  *
    00104  *  \section Purpose
    00105  *
    00106  *  This file contains all the specific code for the hsmci_sdcard example.
    00107  *
    00108  *  \section Contents
    00109  *  The hsmci_sdcard application can be roughly broken down as follows:
    00110  *     - Optional functions
    00111  *        - CheckProtection
    00112  *        - WaitSdConn
    00113  *     - Interrupt handlers
    00114  *        - ISR_Mci0
    00115  *     - The main function, which implements the program behavior
    00116  *        - I/O configuration
    00117  *        - sd card auto-detect and check whether sd card is write-protected
    00118  *          (if supported)
    00119  *        - Initialize MCI interface and installing an isr relating to MCI
    00120  *        - Initialize sdcard, get necessary sdcard's parameters
    00121  *        - write/read sdcard at max available sd clock
    00122  */
    00123 /*----------------------------------------------------------------------------
    00124  *         Headers
    00125  *----------------------------------------------------------------------------*/
    00126
    00127 #include "board.h"
    00128 #include "memories.h"
    00129
    00130 #include <stdint.h>
    00131 #include <stdio.h>
    00132 #include <string.h>
    00133 #include <assert.h>
    00134
    00135
    00136
    00137 /*----------------------------------------------------------------------------
    00138  *         Local constants
    00139  *----------------------------------------------------------------------------*/
    00140
    00141 /** Number of blocks read once */
    00142 #define NB_MULTI_BLOCKS     5
    00143
    00144 /** Number of blocks read in first step */
    00145 #define NB_SPLIT_MULTI      2
    00146
    00147 /**  Number of errors displayed */
    00148 #define NB_ERRORS       5
    00149
    00150
    00151 /*----------------------------------------------------------------------------
    00152  *         Local variables
    00153  *----------------------------------------------------------------------------*/
    00154
    00155 /**  MCI driver instance. */
    00156 static Mcid mciDrv;
    00157
    00158 /**  SDCard driver instance. */
    00159 static SdCard sdDrv;
    00160
    00161 /**  SD card pins. */
    00162 static const Pin pinsSd[] = {BOARD_SD_PINS};
    00163
    00164 /** Date buffer */
    00165 static uint8_t pBuffer[SDMMC_BLOCK_SIZE * NB_MULTI_BLOCKS];
    00166
    00167 /** Number of errors found */
    00168 static uint32_t nbErrors;
    00169
    00170 /*----------------------------------------------------------------------------
    00171  *         Local macros
    00172  *----------------------------------------------------------------------------*/
    00173
    00174 /** Start block address for test */
    00175 #define TEST_BLOCK_START    0
    00176
    00177 /** End block address for test */
    00178 #define TEST_BLOCK_END      SD_TOTAL_BLOCK(&sdDrv) /* Whole SD Card */
    00179
    00180 /* Defined to test Multi-Block functions */
    00181 #define READ_MULTI
    00182 #define WRITE_MULTI
    00183
    00184 /** \def SDT_ReadFun()
    00185  *  Function used for SD card test reading.
    00186  */
    00187 #ifdef  READ_MULTI
    00188 #define SDT_ReadFun(pSd, blk, nbBlk, pData) \
    00189     SD_Read(pSd, blk, pData, nbBlk, NULL, NULL)
    00190 #else
    00191 #define SDT_ReadFun(pSd, blk, nbBlk, pData) \
    00192     SD_ReadBlocks(pSd, blk, nbBlk, pData)
    00193 #endif
    00194
    00195 /** \def SDT_WriteFun()
    00196  *  Function used for SD card test writing.
    00197  */
    00198 #ifdef  WRITE_MULTI
    00199 #define SDT_WriteFun(pSd, blk, nbBlk, pData) \
    00200     SD_Write(pSd, blk, pData, nbBlk, NULL, NULL)
    00201 #else
    00202 #define SDT_WriteFun(pSd, blk, nbBlk, pData) \
    00203     SD_WriteBlocks(pSd, blk, nbBlk, pData)
    00204 #endif
    00205 /*----------------------------------------------------------------------------
    00206  *         Local functions
    00207  *----------------------------------------------------------------------------*/
    00208
    00209 /**
    00210  *  MCI0 interrupt handler. Forwards the event to the MCI driver handler.
    00211  */
    00212 void MCI_IrqHandler(void)
    00213 {
    00214     Sdmmc_Handler(&mciDrv);
    00215 }
    00216
    00217 /*------------------------------------------------------------------------------ */
    00218 /*         Optional: SD card detection */
    00219 /*------------------------------------------------------------------------------ */
    00220
    00221 /**  SD card detection pin instance. */
    00222 static const Pin pinMciCardDetect = BOARD_SD_PIN_CD;
    00223
    00224 /**
    00225  *  Waits for a SD card to be connected.
    00226  */
    00227 static void WaitSdConn(void)
    00228 {
    00229     volatile uint32_t i;
    00230
    00231     PIO_Configure(&pinMciCardDetect, 1);
    00232     printf("-I- Please connect a SD card ...\n\r");
    00233     while (PIO_Get(&pinMciCardDetect) != 0);
    00234     printf("-I- SD card connection detected\n\r");
    00235     i = 150000 * (BOARD_MCK / 1000000);    /* wait for card power stable */
    00236     while(i--);
    00237 }
    00238
    00239 /**
    00240  *  Dummy implementation for Write Protection Detect.
    00241  */
    00242 static void CheckProtection(void)
    00243 {
    00244     printf("-I- Cannot check if SD card is write-protected\n\r");
    00245 }
    00246
    00247 /**
    00248  *  Max Error Break
    00249  */
    00250 static uint8_t MaxErrorBreak(void)
    00251 {
    00252     if (NB_ERRORS) {
    00253         if (nbErrors ++ > NB_ERRORS) {
    00254             while(1);
    00255         }
    00256     }
    00257     return 0;
    00258 }
    00259
    00260 /*----------------------------------------------------------------------------
    00261  *         Global functions
    00262  *----------------------------------------------------------------------------*/
    00263
    00264 /**
    00265  *  \brief hsmci_sdcard Application entry point.
    00266  *
    00267  *  \return Unused (ANSI-C compatibility).
    00268  */
    00269 int main(void)
    00270 {
    00271     uint8_t rc;
    00272     uint32_t block;
    00273     uint32_t i;
    00274     uint16_t multiBlock;
    00275     uint8_t error;
    00276
    00277     /* Disable watchdog */
    00278     WDT_Disable( WDT ) ;
    00279
    00280     /* Output example information */
    00281     printf("-- HSMCI SD Card Example %s --\n\r", SOFTPACK_VERSION);
    00282     printf("-- %s\n\r", BOARD_NAME);
    00283     printf("-- Compiled: %s %s --\n\r", __DATE__, __TIME__);
    00284
    00285     /* Configure SDcard pins */
    00286     PIO_Configure(pinsSd, PIO_LISTSIZE(pinsSd));
    00287
    00288     /* Wait for SD card connection (if supported) */
    00289     WaitSdConn();
    00290
    00291     /* Check if card is write-protected (if supported) */
    00292     CheckProtection();
    00293
    00294     /* Initialize the MCI driver */
    00295     MCI_Init( &mciDrv, HSMCI, ID_HSMCI, BOARD_MCK ) ;
    00296     NVIC_EnableIRQ( HSMCI_IRQn ) ;
    00297
    00298     /* Initialize the SD card driver */
    00299     rc = SD_Init(&sdDrv, &mciDrv);
    00300     if ( rc )
    00301     {
    00302         printf("-E- SD/MMC initialization failed: %x\n\r", rc);
    00303     }
    00304     else
    00305     {
    00306         printf("-I- SD/MMC card initialization successful\n\r");
    00307         printf("-I- Card size: %d MB", (int)(SD_GetTotalSizeKB(&sdDrv)/1000));
    00308         printf(", %d * %dB\n\r", (int)SD_GetNumberBlocks(&sdDrv), (int)SD_GetBlockSize(&sdDrv));
    00309     }
    00310
    00311     if (SD_GetCardType(&sdDrv) & CARD_TYPE_bmSDIO)
    00312     {
    00313         SDIO_DisplayCardInformation(&sdDrv);
    00314     }
    00315
    00316     if (SD_GetCardType(&sdDrv) & CARD_TYPE_bmSDMMC)
    00317     {
    00318         SD_DisplayRegisterCID((SdCard*)&sdDrv);
    00319         SD_DisplayRegisterCSD((SdCard*)&sdDrv);
    00320         SD_DisplayRegisterECSD((SdCard*)&sdDrv);
    00321     }
    00322     else
    00323     {
    00324         printf("-I- Not SD/MMC Memory card, exit\n\r");
    00325         return 0;
    00326     }
    00327
    00328     if ( rc )
    00329     {
    00330         return 0;
    00331     }
    00332
    00333     /* Perform tests on each block */
    00334     multiBlock = 0;
    00335     for ( block = TEST_BLOCK_START; block < TEST_BLOCK_END; block += multiBlock )
    00336     {
    00337          uint32_t splitMulti;
    00338
    00339         /* Perform different single or multiple bloc operations */
    00340         if (++multiBlock > NB_MULTI_BLOCKS)
    00341         {
    00342             multiBlock = 1;
    00343         }
    00344
    00345         /* Multi-block adjustment */
    00346         if (block + multiBlock > TEST_BLOCK_END)
    00347         {
    00348             multiBlock = TEST_BLOCK_END - block;
    00349         }
    00350
    00351         /* Perform single block or multi block transfer */
    00352         printf("\r-I- Testing block [%6u - %6u] ...", (unsigned int)block, (unsigned int)(block + multiBlock -1));
    00353
    00354         /* Clear the block */
    00355         memset(pBuffer, 0, SDMMC_BLOCK_SIZE * multiBlock);
    00356         for (i=0; i < SDMMC_BLOCK_SIZE * multiBlock; i++)
    00357         {
    00358             if ( pBuffer[i] != 0 )
    00359             {
    00360                 printf("\n\r-E- Data @ %u before write : 0x00 <> 0x%02x\n\r", (unsigned int)i, pBuffer[i]);
    00361                 MaxErrorBreak();
    00362                 /* Only find first verify error. */
    00363                 continue;
    00364             }
    00365         }
    00366
    00367         error = SDT_WriteFun(&sdDrv, block, multiBlock, pBuffer);
    00368         if ( error )
    00369         {
    00370             printf("\n\r-E- 1. Write block (%d) #%u\n\r", error, (unsigned int)block);
    00371             MaxErrorBreak();
    00372             /* Skip following test */
    00373             continue;
    00374         }
    00375
    00376         /* Read back the data to check the write operation */
    00377         memset(pBuffer, 0xFF, SDMMC_BLOCK_SIZE * multiBlock);
    00378         error = SDT_ReadFun(&sdDrv, block, multiBlock, pBuffer);
    00379         if ( error )
    00380         {
    00381             printf("\n\r-E- 1. Read block (%d) #%u\n\r", error, (unsigned int)block);
    00382             MaxErrorBreak();
    00383             /* Skip following test */
    00384             continue;
    00385         }
    00386
    00387         for (i=0; i < SDMMC_BLOCK_SIZE * multiBlock; i++)
    00388         {
    00389             if (pBuffer[i] != 0)
    00390             {
    00391                 printf("\n\r-E- 1. Data @ %u : 0x00 <> 0x%02X\n\r", (unsigned int)i, pBuffer[i]);
    00392                 MaxErrorBreak();
    00393                 /* Only find first verify error. */
    00394                 break;
    00395             }
    00396         }
    00397
    00398         /* Write a checkerboard pattern on the block */
    00399         for ( i=0; i < SDMMC_BLOCK_SIZE * multiBlock; i++ )
    00400         {
    00401             if ( (i & 1) == 0 )
    00402             {
    00403                 pBuffer[i] = (i & 0x55);
    00404             }
    00405             else
    00406             {
    00407                 pBuffer[i] = (i & 0xAA);
    00408             }
    00409         }
    00410
    00411         for (i = 0;i < multiBlock;)
    00412         {
    00413             splitMulti = ((multiBlock - i) > NB_SPLIT_MULTI) ?
    00414                                     NB_SPLIT_MULTI : (multiBlock - i);
    00415             error = SDT_WriteFun(&sdDrv,
    00416                                    block + i,
    00417                                    splitMulti,
    00418                                    &pBuffer[i * SDMMC_BLOCK_SIZE]);
    00419             if (error)
    00420                 break;
    00421             i += splitMulti;
    00422         }
    00423
    00424         assert( i == multiBlock ) ;
    00425         if ( error )
    00426         {
    00427             printf("\n\r-E- 2. Write block #%u\n\r", (unsigned int)block);
    00428             MaxErrorBreak();
    00429             /* Skip Following Test */
    00430             continue;
    00431         }
    00432
    00433         /* Read back the data to check the write operation */
    00434         memset(pBuffer, 0, SDMMC_BLOCK_SIZE * multiBlock);
    00435         for ( i = 0;i < multiBlock; )
    00436         {
    00437             splitMulti = ((multiBlock - i) > NB_SPLIT_MULTI) ? NB_SPLIT_MULTI : (multiBlock - i);
    00438             error = SDT_ReadFun(&sdDrv,
    00439                                   block + i,
    00440                                   splitMulti,
    00441                                   &pBuffer[i * SDMMC_BLOCK_SIZE]);
    00442             if (error)
    00443             {
    00444                 break;
    00445             }
    00446             i += splitMulti;
    00447         }
    00448
    00449         assert( i == multiBlock ) ;
    00450
    00451         if (error)
    00452         {
    00453             printf("\n\r-E- 2. Read block #%u\n\r", (unsigned int)block);
    00454             MaxErrorBreak();
    00455             /* Skip Following Test */
    00456             continue;
    00457         }
    00458
    00459         for (i=0; i < SDMMC_BLOCK_SIZE * multiBlock; i++)
    00460         {
    00461             if (!(((i & 1) == 0) && (pBuffer[i] == (i & 0x55))) &&
    00462                 !(((i & 1) != 0) && (pBuffer[i] == (i & 0xAA))) )
    00463             {
    00464                 printf("\n\r-E- 2. Data @ %u 0x%02X <> 0x%02X\n\r", (unsigned int)i, (unsigned int)(((i & 1) == 0) ? (i & 0x55) : (i & 0xAA)), pBuffer[i]);
    00465                 MaxErrorBreak();
    00466                 /* Only find first verify error. */
    00467                 break;
    00468             }
    00469         }
    00470
    00471         /* Input key in terminal to skip blocks */
    00472         if ( UART_IsRxReady() )
    00473         {
    00474             uint8_t bKey = UART_GetChar();
    00475             if (bKey == 27)
    00476             {
    00477                 block += 500 * 2;  /* Skip 500K data */
    00478             }
    00479             else
    00480             {
    00481                 if (bKey == 'c')
    00482                 {
    00483                     printf("\n\r\n\r*** User cancel\n\r");
    00484                     break;
    00485                 }
    00486             }
    00487         }
    00488     }
    00489
    00490     return 0;
    00491 }
    00492

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines