A board support package for the LPC4088 Display Module.

Dependencies:   DM_HttpServer DM_USBHost

Dependents:   lpc4088_displaymodule_emwin lpc4088_displaymodule_demo_sphere sampleGUI sampleEmptyGUI ... more

Fork of DMSupport by EmbeddedArtists AB

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers <title>MCIFileSystem.cpp Source File</title>

MCIFileSystem.cpp

00001 /*
00002  *  Copyright 2014 Embedded Artists AB
00003  *
00004  *  Licensed under the Apache License, Version 2.0 (the "License");
00005  *  you may not use this file except in compliance with the License.
00006  *  You may obtain a copy of the License at
00007  *
00008  *    http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  *  Unless required by applicable law or agreed to in writing, software
00011  *  distributed under the License is distributed on an "AS IS" BASIS,
00012  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  *  See the License for the specific language governing permissions and
00014  *  limitations under the License.
00015  */
00016 
00017 /******************************************************************************
00018  * Includes
00019  *****************************************************************************/
00020 
00021 #include "MCIFileSystem.h"
00022 #include "mbed_debug.h"
00023 #include "rtos.h"
00024 #include "us_ticker_api.h"
00025 
00026 #include "diskio.h" //STA_* defines
00027 
00028 /******************************************************************************
00029  * Defines and typedefs
00030  *****************************************************************************/
00031 
00032 #define MCI_DBG             0
00033 
00034 #define CMD_TIMEOUT                  (0x10000)
00035 
00036 #define DATA_TIMER_VALUE_R           (SDC_TRAN_CLOCK_RATE / 4)    // 250ms
00037 #define DATA_TIMER_VALUE_W           (SDC_TRAN_CLOCK_RATE)    // 1000ms
00038 #define ACQUIRE_DELAY       (100)      /*!< inter-command acquire oper condition delay in milliseconds */
00039 
00040 #define SYSCTL_CLOCK_SDC    (1<<28)
00041 
00042 /**
00043  * @brief SDC Clear Register bit definitions
00044  */
00045 /** Clear all status flag*/
00046 #define SDC_CLEAR_ALL       ((uint32_t) 0x7FF)
00047 
00048 /*
00049  * SDMMC Card bus clock rate definitions
00050  */
00051 /** Card bus clock in Card Identification Mode */
00052 #define SDC_IDENT_CLOCK_RATE         (400000)  /* 400KHz */
00053 /** Card bus clock in Data Transfer Mode */
00054 #define SDC_TRAN_CLOCK_RATE        (20000000)  /* 20MHz */
00055 
00056 /**
00057  * @brief SDC Power Control Register bit definitions
00058  */
00059 /** SD_CMD Output Control */
00060 #define SDC_PWR_OPENDRAIN       (((uint32_t) 1) << 6)
00061 
00062 /**
00063  * @brief SDC Command Register bit definitions
00064  */
00065 /** SDC Command Register Bitmask */
00066 #define SDC_COMMAND_BITMASK     ((uint32_t) 0x7FF)
00067 /** SDC Command Index Bitmask */
00068 #define SDC_COMMAND_INDEX_BITMASK   ((uint32_t) 0x3F)
00069 /** Set SDC Command Index */
00070 #define SDC_COMMAND_INDEX(n)        ((uint32_t) n & 0x3F)
00071 /** No response is expected */
00072 #define SDC_COMMAND_NO_RSP          (((uint32_t) 0 ) << 6)
00073 /** Short response is expected */
00074 #define SDC_COMMAND_SHORT_RSP       (((uint32_t) 1 ) << 6)
00075 /** Long response is expected */
00076 #define SDC_COMMAND_LONG_RSP        (((uint32_t) 3 ) << 6)
00077 /** Response bit mask */
00078 #define SDC_COMMAND_RSP_BITMASK     (((uint32_t) 3 ) << 6)
00079 /** Mark that command timer is disabled and CPSM waits for interrupt request */
00080 #define SDC_COMMAND_INTERRUPT       (((uint32_t) 1 ) << 8)
00081 /** Mark that CPSM waits for CmdPend before starting sending a command*/
00082 #define SDC_COMMAND_PENDING     (((uint32_t) 1 ) << 9)
00083 /** Enable CPSM */
00084 #define SDC_COMMAND_ENABLE          (((uint32_t) 1 ) << 10)
00085 
00086 /**
00087  * @brief SDC Command Response Register bit definitions
00088  */
00089 /** SDC Command Response value */
00090 #define SDC_RESPCOMMAND_VAL(n)      ((uint32_t) n & 0x3F)
00091 
00092 /*
00093  * SD/MMC Response type definitions
00094  */
00095 #define CMDRESP_NONE_TYPE       (SDC_COMMAND_NO_RSP)
00096 #define CMDRESP_R1_TYPE         (SDC_COMMAND_SHORT_RSP)
00097 #define CMDRESP_R1b_TYPE        (SDC_COMMAND_SHORT_RSP)
00098 #define CMDRESP_R2_TYPE         (SDC_COMMAND_LONG_RSP)
00099 #define CMDRESP_R3_TYPE         (SDC_COMMAND_SHORT_RSP)
00100 #define CMDRESP_R6_TYPE         (SDC_COMMAND_SHORT_RSP)
00101 #define CMDRESP_R7_TYPE         (SDC_COMMAND_SHORT_RSP)
00102 
00103 /*
00104  * SD command values (Command Index, Response)
00105  */
00106 #define SD_GO_IDLE_STATE           (SDC_COMMAND_INDEX(MMC_GO_IDLE_STATE) | CMDRESP_NONE_TYPE | SDC_COMMAND_INTERRUPT)  /*!< GO_IDLE_STATE(MMC) or RESET(SD) */
00107 #define SD_CMD1_SEND_OP_COND       (SDC_COMMAND_INDEX(MMC_SEND_OP_COND) | CMDRESP_R3_TYPE | 0)          /*!< SEND_OP_COND(MMC) or ACMD41(SD) */
00108 #define SD_CMD2_ALL_SEND_CID       (SDC_COMMAND_INDEX(MMC_ALL_SEND_CID) | CMDRESP_R2_TYPE | 0)          /*!< ALL_SEND_CID */
00109 #define SD_CMD3_SET_RELATIVE_ADDR  (SDC_COMMAND_INDEX(MMC_SET_RELATIVE_ADDR) | CMDRESP_R1_TYPE | 0)        /*!< SET_RELATE_ADDR */
00110 #define SD_CMD3_SEND_RELATIVE_ADDR (SDC_COMMAND_INDEX(SD_SEND_RELATIVE_ADDR) | CMDRESP_R6_TYPE | 0)        /*!< SEND_RELATE_ADDR */
00111 #define SD_CMD7_SELECT_CARD        (SDC_COMMAND_INDEX(MMC_SELECT_CARD) | CMDRESP_R1b_TYPE | 0)          /*!< SELECT/DESELECT_CARD */
00112 #define SD_CMD8_SEND_IF_COND       (SDC_COMMAND_INDEX(SD_CMD8) | CMDRESP_R7_TYPE | 0)              /*!< SEND_IF_COND */
00113 #define SD_CMD9_SEND_CSD           (SDC_COMMAND_INDEX(MMC_SEND_CSD) | CMDRESP_R2_TYPE | 0)            /*!< SEND_CSD */
00114 #define SD_CMD12_STOP_TRANSMISSION (SDC_COMMAND_INDEX(MMC_STOP_TRANSMISSION) | CMDRESP_R1_TYPE | 0)        /*!< STOP_TRANSMISSION */
00115 #define SD_CMD13_SEND_STATUS       (SDC_COMMAND_INDEX(MMC_SEND_STATUS) | CMDRESP_R1_TYPE | 0)          /*!< SEND_STATUS */
00116 
00117 /* Block-Oriented Read Commands (class 2) */
00118 #define SD_CMD16_SET_BLOCKLEN      (SDC_COMMAND_INDEX(MMC_SET_BLOCKLEN) | CMDRESP_R1_TYPE | 0)          /*!< SET_BLOCK_LEN */
00119 #define SD_CMD17_READ_SINGLE_BLOCK (SDC_COMMAND_INDEX(MMC_READ_SINGLE_BLOCK) | CMDRESP_R1_TYPE | 0)        /*!< READ_SINGLE_BLOCK */
00120 #define SD_CMD18_READ_MULTIPLE_BLOCK (SDC_COMMAND_INDEX(MMC_READ_MULTIPLE_BLOCK) | CMDRESP_R1_TYPE | 0)      /*!< READ_MULTIPLE_BLOCK */
00121 
00122 /* Block-Oriented Write Commands (class 4) */
00123 #define SD_CMD24_WRITE_BLOCK       (SDC_COMMAND_INDEX(MMC_WRITE_BLOCK) | CMDRESP_R1_TYPE | 0)          /*!< WRITE_BLOCK */
00124 #define SD_CMD25_WRITE_MULTIPLE_BLOCK (SDC_COMMAND_INDEX(MMC_WRITE_MULTIPLE_BLOCK) | CMDRESP_R1_TYPE | 0)    /*!< WRITE_MULTIPLE_BLOCK */
00125 
00126 /* Erase Commands (class 5) */
00127 #define SD_CMD32_ERASE_WR_BLK_START (SDC_COMMAND_INDEX(SD_ERASE_WR_BLK_START) | CMDRESP_R1_TYPE | 0)      /*!< ERASE_WR_BLK_START */
00128 #define SD_CMD33_ERASE_WR_BLK_END   (SDC_COMMAND_INDEX(SD_ERASE_WR_BLK_END) | CMDRESP_R1_TYPE | 0)        /*!< ERASE_WR_BLK_END */
00129 #define SD_CMD38_ERASE              (SDC_COMMAND_INDEX(SD_ERASE) | CMDRESP_R1b_TYPE | 0)            /*!< ERASE */
00130 
00131 /* Application-Specific Commands (class 8) */
00132 #define SD_CMD55_APP_CMD           (SDC_COMMAND_INDEX(MMC_APP_CMD) | CMDRESP_R1_TYPE | 0)            /*!< APP_CMD */
00133 #define SD_ACMD6_SET_BUS_WIDTH     (SDC_COMMAND_INDEX(SD_APP_SET_BUS_WIDTH) | CMDRESP_R1_TYPE | 0)        /*!< SET_BUS_WIDTH */
00134 #define SD_ACMD13_SEND_SD_STATUS   (SDC_COMMAND_INDEX(MMC_SEND_STATUS) | CMDRESP_R1_TYPE | 0)          /*!< SEND_SD_STATUS */
00135 #define SD_ACMD41_SD_SEND_OP_COND  (SDC_COMMAND_INDEX(SD_APP_OP_COND) | CMDRESP_R3_TYPE | 0)          /*!< SD_SEND_OP_COND */
00136 
00137 /**
00138  * @brief SDC Interrupt Mask Register bit definitions
00139  */
00140 /** Mask CmdCrcFail flag.*/
00141 #define SDC_MASK0_CMDCRCFAIL     (((uint32_t) 1 ) << 0)
00142 /** Mask DataCrcFail flag. */
00143 #define SDC_MASK0_DATACRCFAIL     (((uint32_t) 1 ) << 1)
00144 /** Mask CmdTimeOut flag. */
00145 #define SDC_MASK0_CMDTIMEOUT     (((uint32_t) 1 ) << 2)
00146 /** Mask DataTimeOut flag. */
00147 #define SDC_MASK0_DATATIMEOUT     (((uint32_t) 1 ) << 3)
00148 /** Mask TxUnderrun flag. */
00149 #define SDC_MASK0_TXUNDERRUN     (((uint32_t) 1 ) << 4)
00150 /** Mask RxOverrun flag. */
00151 #define SDC_MASK0_RXOVERRUN     (((uint32_t) 1 ) << 5)
00152 /** Mask CmdRespEnd flag. */
00153 #define SDC_MASK0_CMDRESPEND     (((uint32_t) 1 ) << 6)
00154 /** Mask CmdSent flag.*/
00155 #define SDC_MASK0_CMDSENT     (((uint32_t) 1 ) << 7)
00156 /** Mask DataEnd flag.*/
00157 #define SDC_MASK0_DATAEND     (((uint32_t) 1 ) << 8)
00158 /** Mask StartBitErr flag.*/
00159 #define SDC_MASK0_STARTBITERR     (((uint32_t) 1 ) << 9)
00160 /** Mask DataBlockEnd flag.*/
00161 #define SDC_MASK0_DATABLOCKEND     (((uint32_t) 1 ) << 10)
00162 /** Mask CmdActive flag.*/
00163 #define SDC_MASK0_CMDACTIVE     (((uint32_t) 1 ) << 11)
00164 /** Mask TxActive flag.*/
00165 #define SDC_MASK0_TXACTIVE     (((uint32_t) 1 ) << 12)
00166 /** Mask RxActive flag.*/
00167 #define SDC_MASK0_RXACTIVE     (((uint32_t) 1 ) << 13)
00168 /** Mask TxFifoHalfEmpty flag.*/
00169 #define SDC_MASK0_TXFIFOHALFEMPTY     (((uint32_t) 1 ) << 14)
00170 /** Mask RxFifoHalfFull flag.*/
00171 #define SDC_MASK0_RXFIFOHALFFULL     (((uint32_t) 1 ) << 15)
00172 /** Mask TxFifoFull flag.*/
00173 #define SDC_MASK0_TXFIFOFULL     (((uint32_t) 1 ) << 16)
00174 /** Mask RxFifoFull flag.*/
00175 #define SDC_MASK0_RXFIFOFULL     (((uint32_t) 1 ) << 17)
00176 /** Mask TxFifoEmpty flag.*/
00177 #define SDC_MASK0_TXFIFOEMPTY     (((uint32_t) 1 ) << 18)
00178 /** Mask RxFifoEmpty flag.*/
00179 #define SDC_MASK0_RXFIFOEMPTY     (((uint32_t) 1 ) << 19)
00180 /** Mask TxDataAvlbl flag.*/
00181 #define SDC_MASK0_TXDATAAVLBL     (((uint32_t) 1 ) << 20)
00182 /** Mask RxDataAvlbl flag.*/
00183 #define SDC_MASK0_RXDATAAVLBL     (((uint32_t) 1 ) << 21)
00184 /** CMD error interrupt mask */
00185 #define SDC_MASK0_CMDERR    (SDC_MASK0_CMDCRCFAIL | SDC_MASK0_CMDTIMEOUT | SDC_MASK0_STARTBITERR)
00186 /** Data Transmit Error interrupt mask */
00187 #define SDC_MASK0_TXDATAERR    (SDC_MASK0_DATACRCFAIL | SDC_MASK0_DATATIMEOUT | SDC_MASK0_TXUNDERRUN | SDC_MASK0_STARTBITERR)
00188 /** Data Receive Error interrupt mask */
00189 #define SDC_MASK0_RXDATAERR    (SDC_MASK0_DATACRCFAIL | SDC_MASK0_DATATIMEOUT | SDC_MASK0_RXOVERRUN | SDC_MASK0_STARTBITERR)
00190 /** Data Transfer interrupt mask*/
00191 #define SDC_MASK0_DATA    (SDC_MASK0_DATAEND | SDC_MASK0_DATABLOCKEND )
00192 
00193 /**
00194  * @brief SDC Clock Control Register bit definitions
00195  */
00196 /** SDC Clock Control Register Bitmask */
00197 #define SDC_CLOCK_BITMASK       ((uint32_t) 0xFFF)
00198 /** SDC Clock Divider Bitmask */
00199 #define SDC_CLOCK_CLKDIV_BITMASK    (((uint32_t) 0xFF ) << 0)
00200 /** Set SDC Clock Divide value */
00201 #define SDC_CLOCK_CLKDIV(n)     (((uint32_t) (n & 0x0FF)) << 0)
00202 
00203 /**
00204  * @brief SDC Status Register bit definitions
00205  */
00206 /** Command Response received (CRC check failed) */
00207 #define SDC_STATUS_CMDCRCFAIL     (((uint32_t) 1 ) << 0)
00208 /** Data block sent/received (CRC check failed). */
00209 #define SDC_STATUS_DATACRCFAIL     (((uint32_t) 1 ) << 1)
00210 /** Command response timeout.. */
00211 #define SDC_STATUS_CMDTIMEOUT     (((uint32_t) 1 ) << 2)
00212 /** Data timeout. */
00213 #define SDC_STATUS_DATATIMEOUT     (((uint32_t) 1 ) << 3)
00214 /** Transmit FIFO underrun error. */
00215 #define SDC_STATUS_TXUNDERRUN     (((uint32_t) 1 ) << 4)
00216 /** Receive FIFO overrun error. */
00217 #define SDC_STATUS_RXOVERRUN     (((uint32_t) 1 ) << 5)
00218 /** Command response received (CRC check passed). */
00219 #define SDC_STATUS_CMDRESPEND     (((uint32_t) 1 ) << 6)
00220 /** Command sent (no response required).*/
00221 #define SDC_STATUS_CMDSENT     (((uint32_t) 1 ) << 7)
00222 /** Data end (data counter is zero).*/
00223 #define SDC_STATUS_DATAEND     (((uint32_t) 1 ) << 8)
00224 /** Start bit not detected on all data signals in wide bus mode..*/
00225 #define SDC_STATUS_STARTBITERR     (((uint32_t) 1 ) << 9)
00226 /** Data block sent/received (CRC check passed).*/
00227 #define SDC_STATUS_DATABLOCKEND     (((uint32_t) 1 ) << 10)
00228 /** Command transfer in progress.*/
00229 #define SDC_STATUS_CMDACTIVE     (((uint32_t) 1 ) << 11)
00230 /** Data transmit in progress.*/
00231 #define SDC_STATUS_TXACTIVE     (((uint32_t) 1 ) << 12)
00232 /** Data receive in progress.*/
00233 #define SDC_STATUS_RXACTIVE     (((uint32_t) 1 ) << 13)
00234 /** Transmit FIFO half empty.*/
00235 #define SDC_STATUS_TXFIFOHALFEMPTY     (((uint32_t) 1 ) << 14)
00236 /** Receive FIFO half full.*/
00237 #define SDC_STATUS_RXFIFOHALFFULL     (((uint32_t) 1 ) << 15)
00238 /** Transmit FIFO full.*/
00239 #define SDC_STATUS_TXFIFOFULL     (((uint32_t) 1 ) << 16)
00240 /** Receive FIFO full.*/
00241 #define SDC_STATUS_RXFIFOFULL     (((uint32_t) 1 ) << 17)
00242 /** Transmit FIFO empty.*/
00243 #define SDC_STATUS_TXFIFOEMPTY     (((uint32_t) 1 ) << 18)
00244 /** Receive FIFO empty.*/
00245 #define SDC_STATUS_RXFIFOEMPTY     (((uint32_t) 1 ) << 19)
00246 /** Data available in transmit FIFO.*/
00247 #define SDC_STATUS_TXDATAAVLBL     (((uint32_t) 1 ) << 20)
00248 /** Data available in receive FIFO.*/
00249 #define SDC_STATUS_RXDATAAVLBL     (((uint32_t) 1 ) << 21)
00250 /** Command Error Status */
00251 #define SDC_STATUS_CMDERR    (SDC_STATUS_CMDCRCFAIL | SDC_STATUS_CMDTIMEOUT | SDC_STATUS_STARTBITERR)
00252 /** Data Error Status */
00253 #define SDC_STATUS_DATAERR    (SDC_STATUS_DATACRCFAIL | SDC_STATUS_DATATIMEOUT | SDC_STATUS_TXUNDERRUN \
00254                  | SDC_STATUS_RXOVERRUN | SDC_STATUS_STARTBITERR)
00255 /** FIFO Status*/
00256 #define SDC_STATUS_FIFO    (SDC_STATUS_TXFIFOHALFEMPTY | SDC_STATUS_RXFIFOHALFFULL \
00257               | SDC_STATUS_TXFIFOFULL  | SDC_STATUS_RXFIFOFULL \
00258               | SDC_STATUS_TXFIFOEMPTY | SDC_STATUS_RXFIFOEMPTY \
00259               | SDC_STATUS_DATABLOCKEND)
00260 
00261 /** Data Transfer Status*/
00262 #define SDC_STATUS_DATA    (SDC_STATUS_DATAEND )
00263 
00264 /**
00265  * @brief SDC Data Control Register bit definitions
00266  */
00267 /** SDC Data Control Register Bitmask */
00268 #define SDC_DATACTRL_BITMASK        ((uint32_t) 0xFF)
00269 /** Enable Data Transfer */
00270 #define SDC_DATACTRL_ENABLE             (((uint32_t) 1 ) << 0)
00271 /** Mark that Data is transfer from card to controller */
00272 #define SDC_DATACTRL_DIR_FROMCARD       (((uint32_t) 1 ) << 1)
00273 /** Mark that Data is transfer from controller to card */
00274 #define SDC_DATACTRL_DIR_TOCARD         ((uint32_t) 0)
00275 /** Mark that the transfer mode is Stream Data Transfer */
00276 #define SDC_DATACTRL_XFER_MODE_STREAM   (((uint32_t) 1 ) << 2)
00277 /** Mark that the transfer mode is Block Data Transfer */
00278 #define SDC_DATACTRL_XFER_MODE_BLOCK    ((uint32_t) 0)
00279 /** Enable DMA */
00280 #define SDC_DATACTRL_DMA_ENABLE         (((uint32_t) 1 ) << 3)
00281 /** Set Data Block size */
00282 #define SDC_DATACTRL_BLOCKSIZE(n)       (((uint32_t) (n & 0x0F) ) << 4)
00283 /** Get Data Block size value */
00284 #define SDC_DATACTRL_BLOCKSIZE_VAL(n)   (((uint32_t) 1) << n)
00285 
00286 /**
00287  * @brief OCR Register definitions
00288  */
00289 /** Support voltage range 2.7-3.6 */
00290 #define SDC_OCR_27_36               ((uint32_t) 0x00FF8000)
00291 /** Card power up status bit */
00292 #define SDC_OCR_IDLE                (((uint32_t) 1) << 31)
00293 #define SDC_OCR_BUSY                (((uint32_t) 0) << 31)
00294 
00295 
00296 /* SD/MMC commands - this matrix shows the command, response types, and
00297    supported card type for that command.
00298    Command                 Number Resp  SD  MMC
00299    ----------------------- ------ ----- --- ---
00300    Reset (go idle)         CMD0   NA    x   x
00301    Send op condition       CMD1   R3        x
00302    All send CID            CMD2   R2    x   x
00303    Send relative address   CMD3   R1        x
00304    Send relative address   CMD3   R6    x
00305    Program DSR             CMD4   NA        x
00306    Select/deselect card    CMD7   R1b       x
00307    Select/deselect card    CMD7   R1    x
00308    Send CSD                CMD9   R2    x   x
00309    Send CID                CMD10  R2    x   x
00310    Read data until stop    CMD11  R1    x   x
00311    Stop transmission       CMD12  R1/b  x   x
00312    Send status             CMD13  R1    x   x
00313    Go inactive state       CMD15  NA    x   x
00314    Set block length        CMD16  R1    x   x
00315    Read single block       CMD17  R1    x   x
00316    Read multiple blocks    CMD18  R1    x   x
00317    Write data until stop   CMD20  R1        x
00318    Setblock count          CMD23  R1        x
00319    Write single block      CMD24  R1    x   x
00320    Write multiple blocks   CMD25  R1    x   x
00321    Program CID             CMD26  R1        x
00322    Program CSD             CMD27  R1    x   x
00323    Set write protection    CMD28  R1b   x   x
00324    Clear write protection  CMD29  R1b   x   x
00325    Send write protection   CMD30  R1    x   x
00326    Erase block start       CMD32  R1    x
00327    Erase block end         CMD33  R1    x
00328    Erase block start       CMD35  R1        x
00329    Erase block end         CMD36  R1        x
00330    Erase blocks            CMD38  R1b       x
00331    Fast IO                 CMD39  R4        x
00332    Go IRQ state            CMD40  R5        x
00333    Lock/unlock             CMD42  R1b       x
00334    Application command     CMD55  R1        x
00335    General command         CMD56  R1b       x
00336 
00337  *** SD card application commands - these must be preceded with ***
00338  *** MMC CMD55 application specific command first               ***
00339    Set bus width           ACMD6  R1    x
00340    Send SD status          ACMD13 R1    x
00341    Send number WR blocks   ACMD22 R1    x
00342    Set WR block erase cnt  ACMD23 R1    x
00343    Send op condition       ACMD41 R3    x
00344    Set clear card detect   ACMD42 R1    x
00345    Send CSR                ACMD51 R1    x */
00346 
00347 /**
00348  * @brief SD/MMC commands, arguments and responses
00349  * Standard SD/MMC commands (3.1)       type  argument     response
00350  */
00351 /* class 1 */
00352 #define MMC_GO_IDLE_STATE         0    /* bc                          */
00353 #define MMC_SEND_OP_COND          1    /* bcr  [31:0]  OCR        R3  */
00354 #define MMC_ALL_SEND_CID          2    /* bcr                     R2  */
00355 #define MMC_SET_RELATIVE_ADDR     3    /* ac   [31:16] RCA        R1  */
00356 #define MMC_SET_DSR               4    /* bc   [31:16] RCA            */
00357 #define MMC_SELECT_CARD           7    /* ac   [31:16] RCA        R1  */
00358 #define MMC_SEND_EXT_CSD          8    /* bc                      R1  */
00359 #define MMC_SEND_CSD              9    /* ac   [31:16] RCA        R2  */
00360 #define MMC_SEND_CID             10    /* ac   [31:16] RCA        R2  */
00361 #define MMC_STOP_TRANSMISSION    12    /* ac                      R1b */
00362 #define MMC_SEND_STATUS          13    /* ac   [31:16] RCA        R1  */
00363 #define MMC_GO_INACTIVE_STATE    15    /* ac   [31:16] RCA            */
00364 
00365 /* class 2 */
00366 #define MMC_SET_BLOCKLEN         16    /* ac   [31:0]  block len  R1  */
00367 #define MMC_READ_SINGLE_BLOCK    17    /* adtc [31:0]  data addr  R1  */
00368 #define MMC_READ_MULTIPLE_BLOCK  18    /* adtc [31:0]  data addr  R1  */
00369 
00370 /* class 3 */
00371 #define MMC_WRITE_DAT_UNTIL_STOP 20    /* adtc [31:0]  data addr  R1  */
00372 
00373 /* class 4 */
00374 #define MMC_SET_BLOCK_COUNT      23    /* adtc [31:0]  data addr  R1  */
00375 #define MMC_WRITE_BLOCK          24    /* adtc [31:0]  data addr  R1  */
00376 #define MMC_WRITE_MULTIPLE_BLOCK 25    /* adtc                    R1  */
00377 #define MMC_PROGRAM_CID          26    /* adtc                    R1  */
00378 #define MMC_PROGRAM_CSD          27    /* adtc                    R1  */
00379 
00380 /* class 6 */
00381 #define MMC_SET_WRITE_PROT       28    /* ac   [31:0]  data addr  R1b */
00382 #define MMC_CLR_WRITE_PROT       29    /* ac   [31:0]  data addr  R1b */
00383 #define MMC_SEND_WRITE_PROT      30    /* adtc [31:0]  wpdata addr R1  */
00384 
00385 /* class 5 */
00386 #define MMC_ERASE_GROUP_START    35    /* ac   [31:0]  data addr  R1  */
00387 #define MMC_ERASE_GROUP_END      36    /* ac   [31:0]  data addr  R1  */
00388 #define MMC_ERASE                37    /* ac                      R1b */
00389 #define SD_ERASE_WR_BLK_START    32    /* ac   [31:0]  data addr  R1  */
00390 #define SD_ERASE_WR_BLK_END      33    /* ac   [31:0]  data addr  R1  */
00391 #define SD_ERASE                 38    /* ac                      R1b */
00392 
00393 /* class 9 */
00394 #define MMC_FAST_IO              39    /* ac   <Complex>          R4  */
00395 #define MMC_GO_IRQ_STATE         40    /* bcr                     R5  */
00396 
00397 /* class 7 */
00398 #define MMC_LOCK_UNLOCK          42    /* adtc                    R1b */
00399 
00400 /* class 8 */
00401 #define MMC_APP_CMD              55    /* ac   [31:16] RCA        R1  */
00402 #define MMC_GEN_CMD              56    /* adtc [0]     RD/WR      R1b */
00403 
00404 /* SD commands                           type  argument     response */
00405 /* class 8 */
00406 /* This is basically the same command as for MMC with some quirks. */
00407 #define SD_SEND_RELATIVE_ADDR     3    /* ac                      R6  */
00408 #define SD_CMD8                   8    /* bcr  [31:0]  OCR        R3  */
00409 
00410 /* Application commands */
00411 #define SD_APP_SET_BUS_WIDTH      6    /* ac   [1:0]   bus width  R1   */
00412 #define SD_APP_OP_COND           41    /* bcr  [31:0]  OCR        R1 (R4)  */
00413 #define SD_APP_SEND_SCR          51    /* adtc                    R1   */
00414 
00415 
00416 /**
00417  * @brief MMC status in R1<br>
00418  * Type<br>
00419  *   e : error bit<br>
00420  *   s : status bit<br>
00421  *   r : detected and set for the actual command response<br>
00422  *   x : detected and set during command execution. the host must poll
00423  *       the card by sending status command in order to read these bits.
00424  * Clear condition<br>
00425  *   a : according to the card state<br>
00426  *   b : always related to the previous command. Reception of
00427  *       a valid command will clear it (with a delay of one command)<br>
00428  *   c : clear by read<br>
00429  */
00430 
00431 #define R1_OUT_OF_RANGE         (1UL << 31)  /* er, c */
00432 #define R1_ADDRESS_ERROR        (1 << 30)  /* erx, c */
00433 #define R1_BLOCK_LEN_ERROR      (1 << 29)  /* er, c */
00434 #define R1_ERASE_SEQ_ERROR      (1 << 28)  /* er, c */
00435 #define R1_ERASE_PARAM          (1 << 27)  /* ex, c */
00436 #define R1_WP_VIOLATION         (1 << 26)  /* erx, c */
00437 #define R1_CARD_IS_LOCKED       (1 << 25)  /* sx, a */
00438 #define R1_LOCK_UNLOCK_FAILED   (1 << 24)  /* erx, c */
00439 #define R1_COM_CRC_ERROR        (1 << 23)  /* er, b */
00440 #define R1_ILLEGAL_COMMAND      (1 << 22)  /* er, b */
00441 #define R1_CARD_ECC_FAILED      (1 << 21)  /* ex, c */
00442 #define R1_CC_ERROR             (1 << 20)  /* erx, c */
00443 #define R1_ERROR                (1 << 19)  /* erx, c */
00444 #define R1_UNDERRUN             (1 << 18)  /* ex, c */
00445 #define R1_OVERRUN              (1 << 17)  /* ex, c */
00446 #define R1_CID_CSD_OVERWRITE    (1 << 16)  /* erx, c, CID/CSD overwrite */
00447 #define R1_WP_ERASE_SKIP        (1 << 15)  /* sx, c */
00448 #define R1_CARD_ECC_DISABLED    (1 << 14)  /* sx, a */
00449 #define R1_ERASE_RESET          (1 << 13)  /* sr, c */
00450 #define R1_STATUS(x)            (x & 0xFFFFE000)
00451 #define R1_CURRENT_STATE(x)     ((x & 0x00001E00) >> 9)  /* sx, b (4 bits) */
00452 #define R1_READY_FOR_DATA       (1 << 8)  /* sx, a */
00453 #define R1_APP_CMD              (1 << 5)  /* sr, c */
00454 
00455 
00456 /**
00457  * @brief SD/MMC card OCR register bits
00458  */
00459 #define OCR_ALL_READY           (1UL << 31)  /* Card Power up status bit */
00460 #define OCR_HC_CCS              (1 << 30)  /* High capacity card */
00461 #define OCR_VOLTAGE_RANGE_MSK   (0x00FF8000)
00462 
00463 #define SD_SEND_IF_ARG          0x000001AA
00464 #define SD_SEND_IF_ECHO_MSK     0x000000FF
00465 #define SD_SEND_IF_RESP         0x000000AA
00466 
00467 /**
00468  * @brief R3 response definitions
00469  */
00470 #define CMDRESP_R3_OCR_VAL(n)           (((uint32_t) n) & 0xFFFFFF)
00471 #define CMDRESP_R3_S18A                 (((uint32_t) 1 ) << 24)
00472 #define CMDRESP_R3_HC_CCS               (((uint32_t) 1 ) << 30)
00473 #define CMDRESP_R3_INIT_COMPLETE        (((uint32_t) 1 ) << 31)
00474 
00475 /**
00476  * @brief R6 response definitions
00477  */
00478 #define CMDRESP_R6_RCA_VAL(n)           (((uint32_t) (n >> 16)) & 0xFFFF)
00479 #define CMDRESP_R6_CARD_STATUS(n)       (((uint32_t) (n & 0x1FFF)) | \
00480                      ((n & (1 << 13)) ? (1 << 19) : 0) | \
00481                      ((n & (1 << 14)) ? (1 << 22) : 0) | \
00482                      ((n & (1 << 15)) ? (1 << 23) : 0))
00483 
00484 /**
00485  * @brief R7 response definitions
00486  */
00487 /** Echo-back of check-pattern */
00488 #define CMDRESP_R7_CHECK_PATTERN(n)     (((uint32_t) n ) & 0xFF)
00489 /** Voltage accepted */
00490 #define CMDRESP_R7_VOLTAGE_ACCEPTED     (((uint32_t) 1 ) << 8)
00491 
00492 /**
00493  * @brief CMD3 command definitions
00494  */
00495 /** Card Address */
00496 #define CMD3_RCA(n)         (((uint32_t) (n & 0xFFFF) ) << 16)
00497 
00498 /**
00499  * @brief CMD7 command definitions
00500  */
00501 /** Card Address */
00502 #define CMD7_RCA(n)         (((uint32_t) (n & 0xFFFF) ) << 16)
00503 
00504 /**
00505  * @brief CMD8 command definitions
00506  */
00507 /** Check pattern */
00508 #define CMD8_CHECKPATTERN(n)            (((uint32_t) (n & 0xFF) ) << 0)
00509 /** Recommended pattern */
00510 #define CMD8_DEF_PATTERN                    (0xAA)
00511 /** Voltage supplied.*/
00512 #define CMD8_VOLTAGESUPPLIED_27_36     (((uint32_t) 1 ) << 8)
00513 
00514 /**
00515  * @brief CMD9 command definitions
00516  */
00517 #define CMD9_RCA(n)         (((uint32_t) (n & 0xFFFF) ) << 16)
00518 
00519 /**
00520  * @brief CMD13 command definitions
00521  */
00522 #define CMD13_RCA(n)            (((uint32_t) (n & 0xFFFF) ) << 16)
00523 
00524 /**
00525  * @brief APP_CMD command definitions
00526  */
00527 #define CMD55_RCA(n)            (((uint32_t) (n & 0xFFFF) ) << 16)
00528 
00529 /**
00530  * @brief ACMD41 command definitions
00531  */
00532 #define ACMD41_OCR(n)                   (((uint32_t) n) & 0xFFFFFF)
00533 #define ACMD41_S18R                     (((uint32_t) 1 ) << 24)
00534 #define ACMD41_XPC                      (((uint32_t) 1 ) << 28)
00535 #define ACMD41_HCS                      (((uint32_t) 1 ) << 30)
00536 
00537 /**
00538  * @brief ACMD6 command definitions
00539  */
00540 #define ACMD6_BUS_WIDTH(n)              ((uint32_t) n & 0x03)
00541 #define ACMD6_BUS_WIDTH_1               (0)
00542 #define ACMD6_BUS_WIDTH_4               (2)
00543 
00544 /** @brief Card type defines
00545  */
00546 #define CARD_TYPE_SD    (1 << 0)
00547 #define CARD_TYPE_4BIT  (1 << 1)
00548 #define CARD_TYPE_8BIT  (1 << 2)
00549 #define CARD_TYPE_HC    (OCR_HC_CCS)/*!< high capacity card > 2GB */
00550 
00551 /**
00552  * @brief SD/MMC sector size in bytes
00553  */
00554 #define MMC_SECTOR_SIZE     512
00555 
00556 /******************************************************************************
00557  * External global variables
00558  *****************************************************************************/
00559 
00560 /******************************************************************************
00561  * Local variables
00562  *****************************************************************************/
00563 
00564 static MCIFileSystem* pUglyForIRQ = NULL;
00565 
00566 /******************************************************************************
00567  * Local Functions
00568  *****************************************************************************/
00569 
00570 static void mymciirq()
00571 {
00572   pUglyForIRQ->mci_MCIIRQHandler();
00573 }
00574 
00575 static void mydmairq()
00576 {
00577   pUglyForIRQ->mci_DMAIRQHandler();
00578 }
00579 
00580 /******************************************************************************
00581  * Public Functions
00582  *****************************************************************************/
00583 
00584 MCIFileSystem::MCIFileSystem(PinName cd) : 
00585     _init_ref_count(0), _is_initialized(false)
00586 {
00587     pUglyForIRQ = this;
00588 
00589     memset(&_sdCardInfo, 0, sizeof(SDMMC_CARD_T));
00590     _eventReceived = false;
00591     _eventSuccess = false;
00592 
00593     initMCI();
00594 
00595     if (cd == NC)
00596     {
00597         _cardDetect = NULL;
00598     }
00599     else
00600     {
00601       _cardDetect = new DigitalIn(cd);
00602       _cardDetect->mode(PullUp);
00603     }
00604 }
00605 
00606 MCIFileSystem::~MCIFileSystem()
00607 {
00608   if (_cardDetect != NULL)
00609   {
00610     delete _cardDetect;
00611   }
00612 }
00613 void MCIFileSystem::initMCI()
00614 {
00615     // Pinsel for MCI
00616     LPC_IOCON->P1_2  = 2;          /* SD_CLK @ P1.2 */
00617     LPC_IOCON->P1_3  = 2;          /* SD_CMD @ P1.3 */
00618     LPC_IOCON->P1_5  = 2 | (1<<7); /* SD_PWR @ P1.5 - digital mode */
00619     LPC_IOCON->P1_6  = 2 | (1<<7); /* SD_DAT[0] @ P1.6 - digital mode */
00620     LPC_IOCON->P1_7  = 2 | (1<<7); /* SD_DAT[1] @ P1.7 - digital mode */
00621     LPC_IOCON->P1_11 = 2;          /* SD_DAT[2] @ P1.11 */
00622     LPC_IOCON->P1_12 = 2;          /* SD_DAT[3] @ P1.12 */
00623 
00624     LPC_SC->PCONP |= SYSCTL_CLOCK_SDC;
00625     LPC_SC->RSTCON0 = (1<<28);
00626     LPC_SC->RSTCON0 &= ~(1<<28);
00627 
00628     /* Initialize SDC peripheral */
00629     LPC_SC->PCONP |= SYSCTL_CLOCK_SDC;
00630 
00631     /* Disable SD_CLK */
00632     mci_ClockControl(SDC_CLOCK_ENABLE, false);
00633 
00634     /* Power-off */
00635     mci_PowerControl(PowerOff, 0);
00636     mci_WriteDelay();
00637 
00638     /* Disable all interrupts */
00639     LPC_MCI->MASK0 = 0;
00640 
00641     /*Setting for timeout problem */
00642     LPC_MCI->DATATMR = 0x1FFFFFFF;
00643 
00644     LPC_MCI->COMMAND = 0;
00645     mci_WriteDelay();
00646 
00647     LPC_MCI->DATACTRL = 0;
00648     mci_WriteDelay();
00649 
00650     /* clear all pending interrupts */
00651     LPC_MCI->CLEAR = SDC_CLEAR_ALL;
00652 
00653     /* Power-up SDC Peripheral */
00654     mci_PowerControl(PowerUp, 0);
00655 
00656     /* delays for the supply output is stable*/
00657     for (uint32_t i = 0; i < 0x80000; i++ ) {}
00658 
00659     mci_SetClock(SDC_IDENT_CLOCK_RATE);
00660     mci_ClockControl(SDC_CLOCK_ENABLE, true);
00661 
00662     /* Power-on SDC Interface */
00663     mci_PowerControl(PowerOn, 0);
00664 
00665     NVIC_SetVector(MCI_IRQn, (uint32_t) mymciirq);
00666     NVIC_EnableIRQ(MCI_IRQn);
00667 
00668     /* Initialize GPDMA controller */
00669     _eventDmaChannel = GPDMA::instance().acquireChannel(mydmairq);
00670 }
00671 
00672 int MCIFileSystem::init() {
00673     uint32_t val = core_util_atomic_incr_u32(&_init_ref_count, 1);
00674         
00675     if (val != 1) {
00676         return BD_ERROR_OK;
00677     }
00678 
00679     debug_if(MCI_DBG, "mcifs:disk_initialize()\n");
00680 
00681     if (!cardInserted()) {
00682         debug("No card detected\r\n");
00683         return BD_ERROR_DEVICE_ERROR;
00684     }
00685 
00686     /* Initialize the Card Data Strucutre */
00687     memset(&_sdCardInfo, 0, sizeof(SDMMC_CARD_T));
00688 
00689     /* Enumerate the card once detected. Note this function may block for a little while. */
00690     int ret = mci_Acquire();
00691     if (ret != 1) {
00692       debug("Card Acquire failed... got %d, but expected 1\r\n", ret);
00693       return BD_ERROR_DEVICE_ERROR;
00694     }
00695 
00696     _is_initialized = true;
00697     return BD_ERROR_OK;
00698 }
00699 
00700 int MCIFileSystem::deinit() {
00701 
00702     if (!_is_initialized) {
00703         return BD_ERROR_OK;
00704     }    
00705 
00706     uint32_t val = core_util_atomic_decr_u32(&_init_ref_count, 1);
00707 
00708     if (val) {
00709         return BD_ERROR_OK;
00710     }
00711 
00712     _is_initialized = false;
00713     return BD_ERROR_OK;
00714 }
00715 
00716 int MCIFileSystem::program(const void *buffer, bd_addr_t addr, bd_size_t size) {
00717     ReturnCode status;
00718     
00719     debug_if(MCI_DBG, "mcifs:disk_write(%#x, %llu, %llu)\n", (uint32_t)buffer, addr, size);
00720     
00721     if (!_is_initialized) {
00722         return BD_ERROR_DEVICE_ERROR;
00723     }
00724     
00725     /* need to convert from number of bytes to blocks */
00726     addr = addr / MMC_SECTOR_SIZE;
00727     size = size / MMC_SECTOR_SIZE;
00728     
00729     status = mci_WriteBlocks((void*)buffer, addr, size);
00730     if (status != SDC_RET_OK) {
00731         return status;
00732     }
00733 
00734     return BD_ERROR_OK;
00735 }
00736 
00737 int MCIFileSystem::read(void *buffer, bd_addr_t addr, bd_size_t size) {
00738     ReturnCode status;
00739     debug_if(MCI_DBG, "mcifs:disk_read(%#x, %llu, %llu)\n", (uint32_t)buffer, addr, size);
00740     
00741     if (!_is_initialized) {
00742         return BD_ERROR_DEVICE_ERROR;
00743     }
00744     
00745     /* need to convert from number of bytes to blocks */
00746     addr = addr / MMC_SECTOR_SIZE;
00747     size = size / MMC_SECTOR_SIZE;    
00748     
00749     status = mci_ReadBlocks(buffer, addr, size);
00750     if (status != SDC_RET_OK) {
00751         return status;
00752     }
00753 
00754     return BD_ERROR_OK;
00755 }
00756 
00757 int MCIFileSystem::sync()
00758 {
00759     debug_if(MCI_DBG, "mcifs:disk_sync()\n");
00760   
00761     if (!_is_initialized) {
00762         return BD_ERROR_OK;
00763     }  
00764   
00765     uint32_t end = us_ticker_read() + 50*1000; // 50ms
00766     while (us_ticker_read() < end)
00767     {
00768         if (mci_GetCardStatus() & R1_READY_FOR_DATA)
00769         {
00770             // card is ready
00771             return BD_ERROR_OK;
00772         }
00773     }
00774     
00775     // timeout while waiting for card to get ready
00776     return SDC_RET_TIMEOUT;
00777 }
00778 
00779 bd_size_t MCIFileSystem::get_read_size() const
00780 {
00781     return MMC_SECTOR_SIZE;
00782 }
00783 
00784 bd_size_t MCIFileSystem::get_program_size() const
00785 {
00786     return MMC_SECTOR_SIZE;
00787 }
00788 
00789 bd_size_t MCIFileSystem::size() const
00790 {
00791     return _sdCardInfo.block_len * MMC_SECTOR_SIZE;
00792 }
00793 
00794 const char *MCIFileSystem::get_type() const
00795 {
00796     return "MCI";
00797 }
00798 
00799 void MCIFileSystem::mci_MCIIRQHandler()
00800 {
00801   int32_t Ret;
00802 
00803   Ret = mci_IRQHandler(NULL, 0, NULL, 0);
00804   if(Ret < 0) {
00805     _eventSuccess = false;
00806     _eventReceived = true;
00807   }
00808 }
00809 
00810 void MCIFileSystem::mci_DMAIRQHandler()
00811 {
00812   _eventSuccess = LPC_GPDMA->IntTCStat & (1<<_eventDmaChannel);
00813   _eventReceived = true;
00814   LPC_GPDMA->IntTCClear = (1<<_eventDmaChannel);
00815   LPC_GPDMA->IntErrClr = (1<<_eventDmaChannel);
00816 }
00817 
00818 /******************************************************************************
00819  * Private Functions
00820  *****************************************************************************/
00821 
00822 static bool gpdma_transfer_to_mci(GPDMA::DMAChannels ChannelNum,
00823                                   uint32_t src,
00824                                   uint32_t Size)
00825 {
00826   GPDMA::GPDMA_Channel_CFG_T cfg;
00827   cfg.ChannelNum = ChannelNum;
00828   cfg.TransferType = GPDMA::FlowControl_M2P_Ctrl_Periph;
00829   cfg.TransferSize = Size;
00830   cfg.TransferWidth = 0;
00831   cfg.SrcAddr = src;
00832   cfg.DstAddr = (uint32_t) (&LPC_MCI->FIFO);
00833 
00834   uint32_t ctrl_word =
00835       GPDMA_DMACCxControl_TransferSize((uint32_t) cfg.TransferSize)
00836           | GPDMA_DMACCxControl_SBSize(GPDMA_BSIZE_8)
00837           | GPDMA_DMACCxControl_DBSize(GPDMA_BSIZE_8)
00838           | GPDMA_DMACCxControl_SWidth(GPDMA_WIDTH_WORD)
00839           | GPDMA_DMACCxControl_DWidth(GPDMA_WIDTH_WORD)
00840           | GPDMA_DMACCxControl_DestTransUseAHBMaster1
00841           | GPDMA_DMACCxControl_SI
00842           | GPDMA_DMACCxControl_I;
00843 
00844   /* Select SD card interface in the DMA MUX*/
00845   LPC_SC->DMAREQSEL &= ~(1 << 1);
00846 
00847   return GPDMA::instance().transfer(&cfg, ctrl_word, 0, GPDMA_CONN_MEMORY, GPDMA_CONN_SDC);
00848 }
00849 
00850 static bool gpdma_transfer_from_mci(GPDMA::DMAChannels ChannelNum,
00851                              uint32_t dst,
00852                              uint32_t Size)
00853 {
00854   GPDMA::GPDMA_Channel_CFG_T cfg;
00855   cfg.ChannelNum = ChannelNum;
00856   cfg.TransferType = GPDMA::FlowControl_P2M_Ctrl_Periph;
00857   cfg.TransferSize = Size;
00858   cfg.TransferWidth = 0;
00859   cfg.SrcAddr = (uint32_t) (&LPC_MCI->FIFO);
00860   cfg.DstAddr = dst;
00861 
00862   uint32_t ctrl_word =
00863       GPDMA_DMACCxControl_TransferSize((uint32_t) cfg.TransferSize)
00864           | GPDMA_DMACCxControl_SBSize(GPDMA_BSIZE_8)
00865           | GPDMA_DMACCxControl_DBSize(GPDMA_BSIZE_8)
00866           | GPDMA_DMACCxControl_SWidth(GPDMA_WIDTH_WORD)
00867           | GPDMA_DMACCxControl_DWidth(GPDMA_WIDTH_WORD)
00868           | GPDMA_DMACCxControl_SrcTransUseAHBMaster1
00869           | GPDMA_DMACCxControl_DI
00870           | GPDMA_DMACCxControl_I;
00871 
00872   /* Select SD card interface in the DMA MUX*/
00873   LPC_SC->DMAREQSEL &= ~(1 << 1);
00874 
00875   return GPDMA::instance().transfer(&cfg, ctrl_word, 0, GPDMA_CONN_SDC, GPDMA_CONN_MEMORY);
00876 }
00877 
00878 bool MCIFileSystem::cardInserted() const
00879 {
00880     // If no card detect pin is given, then assume that a card is inserted.
00881     // If a pin is specified then use that to determing the presence of a card.
00882     return ((_cardDetect == NULL) || (_cardDetect->read() == 0));
00883 }
00884 
00885 
00886 
00887 int32_t MCIFileSystem::mci_Acquire()
00888 {
00889   int32_t Ret;
00890 
00891   /* Initialize card info */
00892   _sdCardInfo.speed = SDC_TRAN_CLOCK_RATE;
00893   _sdCardInfo.card_type = 0;
00894 
00895   /* During identification phase, the clock should be less than
00896      400Khz. Once we pass this phase, the normal clock can be set up
00897      to 25Mhz on SD card and 20Mhz on MMC card. */
00898   mci_SetClock(SDC_IDENT_CLOCK_RATE);
00899 
00900   /* Clear Open Drain output control for SD */
00901   mci_PowerControl(PowerOn, 0);
00902   
00903   /* Card Reset */
00904   Ret = mci_ExecuteCmd(SD_GO_IDLE_STATE, 0, NULL);
00905   if (Ret != 0) {
00906     return Ret;
00907   }
00908 
00909   ThisThread::sleep_for(ACQUIRE_DELAY);
00910 
00911   /* Send interface operation condiftion */
00912   Ret = mci_SendIfCond();
00913   if (Ret == SDC_RET_BAD_PARAMETERS) {
00914     return Ret;    /* Non-compatible voltage range or check pattern is not correct */
00915 
00916   }
00917   /* Get Card Type */
00918   if (Ret == SDC_RET_OK) {/* Ver2.00 or later SD Memory Card*/
00919     bool CCS;
00920     uint32_t OCR = SDC_OCR_27_36;
00921     _sdCardInfo.card_type |= CARD_TYPE_SD;
00922     Ret = mci_SendAppOpCond(0, true, &OCR, &CCS);
00923     if (CCS) {  /* High Capacity or Extended Capacity SD Memory Card */
00924       _sdCardInfo.card_type |= CARD_TYPE_HC;
00925     }
00926   }
00927   else {  /*Ver2.00 or later SD Memory Card(voltage mismatch) or Ver1.X SD Memory Card
00928          or not SD Memory Card*/
00929     bool CCS;
00930     uint32_t OCR = SDC_OCR_27_36;
00931     Ret = mci_SendAppOpCond(0, false, &OCR, &CCS);
00932     if (Ret == SDC_RET_OK) {
00933       _sdCardInfo.card_type |= CARD_TYPE_SD;
00934     }
00935     else if (Ret == SDC_RET_BAD_PARAMETERS) {
00936       return Ret;
00937     }
00938     else {  /* MMC Card setup */
00939       uint32_t OCR;
00940       /* Enter to Open Drain mode */
00941       mci_PowerControl(PowerOn, SDC_PWR_OPENDRAIN);
00942       ThisThread::sleep_for(ACQUIRE_DELAY);
00943       Ret = mci_SendOpCond(&OCR);
00944       if (Ret != SDC_RET_OK) {
00945         return Ret;
00946       }
00947 
00948     }
00949   }
00950 
00951   /* Read CID */
00952   mci_GetCID(_sdCardInfo.cid);
00953 
00954   /* RCA send, for SD get RCA */
00955   if (_sdCardInfo.card_type & CARD_TYPE_SD) {
00956     mci_GetAddr(&_sdCardInfo.rca);
00957   }
00958   else {
00959     _sdCardInfo.rca = 1;
00960     mci_SetAddr(_sdCardInfo.rca);
00961     mci_PowerControl(PowerOn, 0);  /* enter to push-pull mode */
00962   }
00963 
00964   /* Get CSD */
00965   mci_GetCSD(_sdCardInfo.rca, _sdCardInfo.csd);
00966 
00967   /* Compute card size, block size and no. of blocks  based on CSD response recived. */
00968   if (_sdCardInfo.cid[0]) {
00969     mci_ProcessCSD();
00970 
00971     if (mci_SetTranState(_sdCardInfo.rca) != SDC_RET_OK) {
00972       return 0;
00973     }
00974 
00975     if (mci_GetCardState() != SDMMC_TRAN_ST) {
00976       return 0;
00977     }
00978 
00979     if (mci_SetCardParams() != 0) {
00980       return 0;
00981     }
00982   }
00983 
00984   return (_sdCardInfo.cid[0]) ? 1 : 0;
00985 }
00986 
00987 uint32_t MCIFileSystem::mci_GetCardStatus() const
00988 {
00989   uint32_t Status;
00990   mci_GetStatus(_sdCardInfo.rca, &Status);
00991   return Status;
00992 }
00993 
00994 MCIFileSystem::CardState MCIFileSystem::mci_GetCardState() const
00995 {
00996   uint32_t Status;
00997   volatile int32_t Ret;
00998 
00999   /* get current state of the card */
01000   Ret = mci_GetStatus(_sdCardInfo.rca, &Status);
01001 
01002   /* check card state in response */
01003   return (CardState) R1_CURRENT_STATE(Status);
01004 }
01005 
01006 MCIFileSystem::ReturnCode MCIFileSystem::mci_StopTransmission(uint32_t rca) const
01007 {
01008   uint32_t Status;
01009   ReturnCode Ret = SDC_RET_FAILED;
01010   response_t Response;
01011   uint32_t RetryCnt =  20;
01012 
01013   Ret = mci_GetStatus(rca, &Status);
01014   if (Ret != SDC_RET_OK) {
01015     return SDC_RET_ERR_STATE;
01016   }
01017 
01018   if (R1_CURRENT_STATE(Status) == SDMMC_TRAN_ST) {
01019     return SDC_RET_OK;
01020   }
01021 
01022   if ((R1_CURRENT_STATE(Status) != SDMMC_DATA_ST) &&
01023     (R1_CURRENT_STATE(Status) != SDMMC_RCV_ST)) {
01024     return SDC_RET_ERR_STATE;
01025   }
01026 
01027   while (RetryCnt > 0) {
01028     Ret = mci_ExecuteCmd(SD_CMD12_STOP_TRANSMISSION, 0, &Response);
01029     if (Ret == SDC_RET_OK) {
01030       if (mci_CheckR1Response(Response.Data[0], &Ret)) {
01031         if (Ret != SDC_RET_OK) {
01032           return Ret;
01033         }
01034         Ret = mci_GetStatus(rca, &Status);
01035         if ((R1_CURRENT_STATE(Status) == SDMMC_TRAN_ST) || (R1_CURRENT_STATE(Status) == SDMMC_PRG_ST)) {
01036           return SDC_RET_OK;
01037         }
01038         return SDC_RET_ERR_STATE;
01039       }
01040     }
01041     RetryCnt--;
01042   }
01043   return Ret;
01044 }
01045 
01046 MCIFileSystem::ReturnCode MCIFileSystem::mci_ReadBlocks(void *buffer, int32_t startBlock, int32_t blockNum)
01047 {
01048   ReturnCode Ret = SDC_RET_FAILED;
01049   int32_t ByteNum = blockNum *  MMC_SECTOR_SIZE;
01050 
01051   do
01052   {
01053     /* if card is not acquired return immediately */
01054     if (( startBlock < 0) || ( (startBlock + blockNum) > _sdCardInfo.blocknr) ) {
01055       Ret = SDC_RET_NOT_READY;
01056       break;
01057     }
01058 
01059     /* Put to tran state */
01060     Ret = mci_SetTranState(_sdCardInfo.rca);
01061     if (Ret != SDC_RET_OK) {
01062       break;
01063     }
01064 
01065     LPC_MCI->MASK0 = SDC_MASK0_DATA | SDC_MASK0_RXDATAERR;
01066 
01067     /* DMA Setup */
01068     mci_SetupEventWakeup();
01069     gpdma_transfer_from_mci(_eventDmaChannel, (uint32_t)buffer, ByteNum);
01070 
01071     /* set transfer information */
01072     mci_SetDataTransfer(blockNum, true, DATA_TIMER_VALUE_R);
01073 
01074     Ret = _readBlocks(_sdCardInfo.card_type, startBlock, blockNum);
01075     if (Ret == SDC_RET_OK) {
01076       /* Wait for transfer Finish */
01077       if (mci_WaitForEvent() != 0) {
01078         Ret = SDC_RET_FAILED;
01079       }
01080     } else {
01081       Ret = SDC_RET_FAILED;
01082     }
01083 
01084     GPDMA::instance().stopTransfer(_eventDmaChannel);
01085 
01086     if ((blockNum > 1) || (mci_GetCardState() == SDMMC_DATA_ST)) {
01087       /* Send Stop transmission command */
01088       mci_StopTransmission(_sdCardInfo.rca);
01089     }
01090 
01091     /* Wait for card to enter tran state */
01092     while (mci_GetCardState() != SDMMC_TRAN_ST) {}
01093       
01094   } while(false);
01095 
01096   return Ret;
01097 }
01098 
01099 MCIFileSystem::ReturnCode MCIFileSystem::mci_WriteBlocks(void *buffer, int32_t startBlock, int32_t blockNum)
01100 {
01101   ReturnCode Ret = SDC_RET_FAILED;
01102   
01103   do
01104   {
01105     /* if card is not acquired return immediately */
01106     if (( startBlock < 0) || ( (startBlock + blockNum) > _sdCardInfo.blocknr) ) {
01107       Ret = SDC_RET_NOT_READY;
01108       break;
01109     }
01110 
01111     /* Put to tran state */
01112     Ret = mci_SetTranState(_sdCardInfo.rca);
01113     if (Ret != SDC_RET_OK) {
01114       break;
01115     }
01116 
01117     Ret = _writeBlocks(_sdCardInfo.card_type, startBlock, blockNum);
01118     if (Ret != SDC_RET_OK) {
01119       break;
01120     }
01121 
01122     /*Wait for card enter to rcv state*/
01123     while (mci_GetCardState() != SDMMC_RCV_ST) {}
01124 
01125     LPC_MCI->MASK0 = SDC_MASK0_DATA | SDC_MASK0_TXDATAERR;
01126 
01127     /* DMA Setup */
01128     mci_SetupEventWakeup();
01129     gpdma_transfer_to_mci(_eventDmaChannel, (uint32_t)buffer, blockNum*MMC_SECTOR_SIZE);
01130 
01131     /* set transfer information */
01132     mci_SetDataTransfer(blockNum, false, DATA_TIMER_VALUE_W);
01133 
01134     /* Wait for transfer done */
01135     if (mci_WaitForEvent() != 0) {
01136       Ret = SDC_RET_FAILED;
01137     }
01138 
01139     if ((blockNum > 1) || (mci_GetCardState() == SDMMC_RCV_ST)) {
01140       /* Send Stop transmission command */
01141       mci_StopTransmission(_sdCardInfo.rca);
01142     }
01143 
01144     /* Wait for card to enter tran state */
01145     while (mci_GetCardState() != SDMMC_TRAN_ST) {}
01146       
01147   } while (false);
01148 
01149   return Ret;
01150 }
01151 
01152 void MCIFileSystem::mci_SetClock(uint32_t freq) const
01153 {
01154   uint32_t PClk;
01155   uint32_t ClkValue = 0;
01156 
01157   PClk = PeripheralClock;
01158 
01159   ClkValue = (PClk + 2 * freq - 1) / (2 * freq);
01160   if (ClkValue > 0) {
01161     ClkValue -= 1;
01162   }
01163   uint32_t temp;
01164   temp = (LPC_MCI->CLOCK & (~SDC_CLOCK_CLKDIV_BITMASK));
01165   LPC_MCI->CLOCK = temp | (SDC_CLOCK_CLKDIV(ClkValue));
01166   mci_WriteDelay();
01167 }
01168 
01169 void MCIFileSystem::mci_ClockControl(ClockControl ctrlType, bool enable) const
01170 {
01171   if (enable) {
01172     LPC_MCI->CLOCK |= (1 << ctrlType);
01173   }
01174   else {
01175     LPC_MCI->CLOCK &= (~(1 << ctrlType));
01176   }
01177   mci_WriteDelay();
01178 }
01179 
01180 void MCIFileSystem::mci_PowerControl(power_ctrl_t powerMode, uint32_t flag) const
01181 {
01182   LPC_MCI->POWER = (powerMode & 0x3) | flag;
01183   mci_WriteDelay();
01184 }
01185 
01186 MCIFileSystem::ReturnCode MCIFileSystem::mci_ExecuteCmd(uint32_t Command, uint32_t Arg, response_t* pResp) const
01187 {
01188   ReturnCode Ret = SDC_RET_FAILED;
01189 
01190   /* Send Command to card */
01191   Ret = mci_SendCmd(Command, Arg, CMD_TIMEOUT);
01192   if (Ret != SDC_RET_OK) {
01193     return Ret;
01194   }
01195 
01196   /* Get response (if any) */
01197   if ((Command & SDC_COMMAND_RSP_BITMASK) != SDC_COMMAND_NO_RSP) {
01198 
01199     mci_GetResp(pResp);
01200 
01201     /* If the response is not R1, in the response field, the Expected Cmd data
01202             won't be the same as the CMD data in SendCmd(). Below four cmds have
01203             R2 or R3 response. We don't need to check if MCI_RESP_CMD is the same
01204             as the Expected or not. */
01205     if ((SDC_COMMAND_INDEX(Command) != MMC_SEND_OP_COND) &&
01206       (SDC_COMMAND_INDEX(Command) != SD_APP_OP_COND) &&
01207       (SDC_COMMAND_INDEX(Command) != MMC_ALL_SEND_CID) &&
01208       (SDC_COMMAND_INDEX(Command) != MMC_SEND_CSD) &&
01209       (pResp->CmdIndex != SDC_COMMAND_INDEX(Command))) {
01210       return SDC_RET_CMD_FAILED;
01211     }
01212   }
01213 
01214   return SDC_RET_OK;
01215 }
01216 
01217 MCIFileSystem::ReturnCode MCIFileSystem::mci_SendIfCond() const
01218 {
01219   ReturnCode Ret = SDC_RET_FAILED;
01220   response_t Response;
01221   uint32_t RetryCnt =  20;
01222 
01223   while (RetryCnt > 0) {
01224     Ret = mci_ExecuteCmd(SD_CMD8_SEND_IF_COND, (CMD8_VOLTAGESUPPLIED_27_36 | CMD8_CHECKPATTERN(
01225                               CMD8_DEF_PATTERN)), &Response);
01226     if (Ret == SDC_RET_OK) {
01227       if ((Response.Data[0] & CMDRESP_R7_VOLTAGE_ACCEPTED) &&
01228         (CMDRESP_R7_CHECK_PATTERN(Response.Data[0]) == CMD8_DEF_PATTERN)) {
01229         return SDC_RET_OK;
01230       }
01231       return SDC_RET_BAD_PARAMETERS;
01232     }
01233     RetryCnt--;
01234   }
01235   return Ret;
01236 }
01237 
01238 MCIFileSystem::ReturnCode MCIFileSystem::mci_SendOpCond(uint32_t *pOCR) const
01239 {
01240   ReturnCode Ret = SDC_RET_FAILED;
01241   response_t Response;
01242   uint32_t RetryCnt =  0x200;
01243 
01244   while (RetryCnt > 0) {
01245     Ret = mci_ExecuteCmd(SD_CMD1_SEND_OP_COND, SDC_OCR_27_36, &Response);
01246     if (Ret == SDC_RET_OK) {
01247       *pOCR = Response.Data[0];
01248       if (*pOCR & SDC_OCR_IDLE) {
01249         if ((Response.Data[0] & SDC_OCR_27_36) != SDC_OCR_27_36) {
01250           return SDC_RET_BAD_PARAMETERS;
01251         }
01252         return SDC_RET_OK;
01253       }
01254     }
01255     RetryCnt--;
01256   }
01257   return SDC_RET_FAILED;
01258 }
01259 
01260 MCIFileSystem::ReturnCode MCIFileSystem::mci_SendAppOpCond(uint16_t rca, bool hcs, uint32_t *pOcr, bool *pCCS) const
01261 {
01262   ReturnCode Ret = SDC_RET_FAILED;
01263   response_t Response;
01264   uint32_t Argument;
01265   uint32_t RetryCnt =  0x2000;  /* The host repeatedly issues ACMD41 for at least 1 second or
01266                          until the busy bit are set to 1 */
01267 
01268   Argument = ACMD41_OCR(*pOcr);
01269   if (hcs) {
01270     Argument |= ACMD41_HCS;
01271   }
01272 
01273   while (RetryCnt > 0) {
01274     Ret = mci_SendAppCmd(rca);
01275     if (Ret == SDC_RET_OK) {
01276       Ret = mci_ExecuteCmd(SD_ACMD41_SD_SEND_OP_COND, Argument, &Response);
01277       if (Ret == SDC_RET_OK) {
01278         if (Response.Data[0] & CMDRESP_R3_INIT_COMPLETE) {
01279           if (*pOcr == 0) {
01280             *pOcr = CMDRESP_R3_OCR_VAL(Response.Data[0]);
01281             return SDC_RET_OK;
01282           }
01283           if ((CMDRESP_R3_OCR_VAL(Response.Data[0]) & *pOcr) != *pOcr) {
01284             return SDC_RET_BAD_PARAMETERS;
01285           }
01286           *pCCS = (Response.Data[0] & CMDRESP_R3_HC_CCS) ? true : false;
01287           return SDC_RET_OK;
01288         }
01289       }
01290     }
01291     else {
01292       //If we abort here then some cards will go undetected, better to keep retrying
01293       //return Ret;
01294     }
01295     RetryCnt--;
01296   }
01297   return SDC_RET_FAILED;
01298 }
01299 
01300 MCIFileSystem::ReturnCode MCIFileSystem::mci_GetCID(uint32_t *pCID) const
01301 {
01302   ReturnCode Ret = SDC_RET_FAILED;
01303   response_t Response;
01304   uint32_t RetryCnt =  20;
01305 
01306   while (RetryCnt > 0) {
01307     Ret = mci_ExecuteCmd(SD_CMD2_ALL_SEND_CID, 0, &Response);
01308     if (Ret == SDC_RET_OK) {
01309       pCID[3] = Response.Data[0];
01310       pCID[2] = Response.Data[1];
01311       pCID[1] = Response.Data[2];
01312       pCID[0] = Response.Data[3];
01313       return SDC_RET_OK;
01314     }
01315     RetryCnt--;
01316   }
01317   return Ret;
01318 }
01319 
01320 MCIFileSystem::ReturnCode MCIFileSystem::mci_SetAddr(uint16_t addr) const
01321 {
01322   ReturnCode Ret = SDC_RET_FAILED;
01323   response_t Response;
01324   uint32_t RetryCnt =  20;
01325 
01326   while (RetryCnt > 0) {
01327     Ret = mci_ExecuteCmd(SD_CMD3_SET_RELATIVE_ADDR, CMD3_RCA(addr), &Response);
01328     if (Ret == SDC_RET_OK) {
01329       if (mci_CheckR1Response(Response.Data[0], &Ret)) {
01330         return Ret;
01331       }
01332     }
01333     RetryCnt--;
01334   }
01335   return Ret;
01336 }
01337 
01338 MCIFileSystem::ReturnCode MCIFileSystem::mci_GetAddr(uint16_t *pRCA) const
01339 {
01340   ReturnCode Ret = SDC_RET_FAILED;
01341   response_t Response;
01342   uint32_t RetryCnt =  20;
01343 
01344   *pRCA = 0;
01345   while (RetryCnt > 0) {
01346     Ret = mci_ExecuteCmd(SD_CMD3_SEND_RELATIVE_ADDR, 0, &Response);
01347     if (Ret == SDC_RET_OK) {
01348       if (!(CMDRESP_R6_CARD_STATUS(Response.Data[0]) & R1_READY_FOR_DATA)) {
01349         Ret = SDC_RET_NOT_READY;
01350       }
01351       else if (R1_CURRENT_STATE(CMDRESP_R6_CARD_STATUS(Response.Data[0])) != SDMMC_STBY_ST) {
01352         Ret = SDC_RET_ERR_STATE;
01353       }
01354       else {
01355         *pRCA = CMDRESP_R6_RCA_VAL(Response.Data[0]);
01356         return SDC_RET_OK;
01357       }
01358     }
01359     RetryCnt--;
01360   }
01361   return Ret;
01362 }
01363 
01364 MCIFileSystem::ReturnCode MCIFileSystem::mci_GetCSD(uint16_t rca, uint32_t *pCSD) const
01365 {
01366   ReturnCode Ret = SDC_RET_FAILED;
01367   response_t Response;
01368   uint32_t RetryCnt =  20;
01369 
01370   while (RetryCnt > 0) {
01371     Ret = mci_ExecuteCmd(SD_CMD9_SEND_CSD, CMD9_RCA(rca), &Response);
01372     if (Ret == SDC_RET_OK) {
01373       pCSD[3] = Response.Data[0];
01374       pCSD[2] = Response.Data[1];
01375       pCSD[1] = Response.Data[2];
01376       pCSD[0] = Response.Data[3];
01377       return Ret;
01378     }
01379     RetryCnt--;
01380   }
01381   return Ret;
01382 }
01383 
01384 MCIFileSystem::ReturnCode MCIFileSystem::mci_SelectCard(uint16_t addr) const
01385 {
01386   ReturnCode Ret = SDC_RET_FAILED;
01387   response_t Response;
01388   uint32_t RetryCnt =  20;
01389 
01390   while (RetryCnt > 0) {
01391     Ret = mci_ExecuteCmd(SD_CMD7_SELECT_CARD, CMD7_RCA(addr), &Response);
01392     if (Ret == SDC_RET_OK) {
01393       if (mci_CheckR1Response(Response.Data[0], &Ret)) {
01394         return Ret;
01395       }
01396     }
01397     RetryCnt--;
01398   }
01399   return Ret;
01400 }
01401 
01402 MCIFileSystem::ReturnCode MCIFileSystem::mci_GetStatus(uint16_t rca, uint32_t *pStatus) const
01403 {
01404   ReturnCode Ret = SDC_RET_FAILED;
01405   response_t Response;
01406   uint32_t RetryCnt =  20;
01407 
01408   *pStatus = (uint32_t) -1;
01409   while (RetryCnt > 0) {
01410     Ret = mci_ExecuteCmd(SD_CMD13_SEND_STATUS, CMD13_RCA(rca), &Response);
01411     if (Ret == SDC_RET_OK) {
01412       mci_CheckR1Response(Response.Data[0], &Ret);
01413       *pStatus = Response.Data[0];
01414       return Ret;
01415     }
01416     RetryCnt--;
01417   }
01418   return Ret;
01419 }
01420 
01421 void MCIFileSystem::mci_ProcessCSD()
01422 {
01423   int32_t CSize = 0;
01424   int32_t CSizeMult = 0;
01425   int32_t Mult = 0;
01426 
01427   /* compute block length based on CSD response */
01428   _sdCardInfo.block_len = 1 << mci_GetBits(80, 83, _sdCardInfo.csd);
01429   if ((_sdCardInfo.card_type & CARD_TYPE_HC) && (_sdCardInfo.card_type & CARD_TYPE_SD)) {
01430     /* See section 5.3.3 CSD Register (CSD Version 2.0) of SD2.0 spec  an explanation for the calculation of these values */
01431     CSize = mci_GetBits(48, 63, (uint32_t *) _sdCardInfo.csd) + 1;
01432     _sdCardInfo.blocknr = CSize << 10;  /* 512 byte blocks */
01433   }
01434   else {
01435     /* See section 5.3 of the 4.1 revision of the MMC specs for  an explanation for the calculation of these values */
01436     CSize = mci_GetBits(62, 73, (uint32_t *) _sdCardInfo.csd);
01437     CSizeMult = mci_GetBits(47, 49, (uint32_t *) _sdCardInfo.csd);
01438     Mult = 1 << (CSizeMult + 2);
01439     _sdCardInfo.blocknr = (CSize + 1) * Mult;
01440 
01441     /* adjust blocknr to 512/block */
01442     if (_sdCardInfo.block_len > MMC_SECTOR_SIZE) {
01443       _sdCardInfo.blocknr = _sdCardInfo.blocknr * (_sdCardInfo.block_len >> 9);
01444     }
01445   }
01446 
01447   _sdCardInfo.device_size = _sdCardInfo.blocknr << 9;  /* blocknr * 512 */
01448 }
01449 
01450 MCIFileSystem::ReturnCode MCIFileSystem::mci_SetBusWidth(uint16_t rca, uint8_t width) const
01451 {
01452   ReturnCode Ret = SDC_RET_FAILED;
01453   response_t Response;
01454   uint8_t RetryCnt =  0x20;
01455 
01456   while (RetryCnt > 0) {
01457     Ret = mci_SendAppCmd(rca);
01458     if (Ret == SDC_RET_OK) {
01459       Ret = mci_ExecuteCmd(SD_ACMD6_SET_BUS_WIDTH, ACMD6_BUS_WIDTH(width), &Response);
01460       if (Ret == SDC_RET_OK) {
01461         if (mci_CheckR1Response(Response.Data[0], &Ret)) {
01462           return Ret;
01463         }
01464       }
01465     }
01466     RetryCnt--;
01467   }
01468   return SDC_RET_FAILED;
01469 }
01470 
01471 MCIFileSystem::ReturnCode MCIFileSystem::mci_SetTranState(uint16_t rca) const
01472 {
01473   ReturnCode Ret = SDC_RET_OK;
01474   uint32_t status = 0;
01475   CardState state;
01476 
01477   /* get current state of the card */
01478   Ret = mci_GetStatus(rca, &status);
01479   if (Ret != SDC_RET_OK) {
01480     /* unable to get the card state. So return immediatly. */
01481     return Ret;
01482   }
01483 
01484   /* check card state in response */
01485   state = (CardState) R1_CURRENT_STATE(status);
01486   switch (state) {
01487   case SDMMC_STBY_ST:
01488     /* put card in 'Trans' state */
01489     Ret = mci_SelectCard(rca);
01490     if (Ret != SDC_RET_OK) {
01491       /* unable to put the card in Trans state. So return immediatly. */
01492       return Ret;
01493     }
01494     mci_GetStatus(rca, &status);
01495     if (((CardState) R1_CURRENT_STATE(status)) != SDMMC_TRAN_ST) {
01496       return SDC_RET_ERR_STATE;
01497     }
01498     break;
01499 
01500   case SDMMC_TRAN_ST:
01501     /*do nothing */
01502     break;
01503 
01504   default:
01505     /* card shouldn't be in other states so return */
01506     return SDC_RET_ERR_STATE;
01507   }
01508 
01509   return SDC_RET_OK;
01510 }
01511 
01512 MCIFileSystem::ReturnCode MCIFileSystem::mci_SetBlockLength(uint32_t rca, uint32_t block_len) const
01513 {
01514   ReturnCode Ret = SDC_RET_FAILED;
01515   response_t Response;
01516   uint8_t RetryCnt =  0x20;
01517 
01518   while (RetryCnt > 0) {
01519     Ret = mci_ExecuteCmd(SD_CMD16_SET_BLOCKLEN, block_len, &Response);
01520     if (Ret == SDC_RET_OK) {
01521       if (mci_CheckR1Response(Response.Data[0], &Ret)) {
01522         return Ret;
01523       }
01524     }
01525     RetryCnt--;
01526   }
01527   return SDC_RET_FAILED;
01528 }
01529 
01530 MCIFileSystem::ReturnCode MCIFileSystem::mci_SetCardParams() const
01531 {
01532   ReturnCode Ret;
01533 
01534   mci_SetClock(SDC_TRAN_CLOCK_RATE);
01535   if (_sdCardInfo.card_type & CARD_TYPE_SD) {
01536     mci_ClockControl(SDC_CLOCK_WIDEBUS_MODE, true);
01537     Ret = mci_SetBusWidth(_sdCardInfo.rca, ACMD6_BUS_WIDTH_4);
01538     if (Ret != SDC_RET_OK) {
01539       return Ret;
01540     }
01541   }
01542   else {
01543     mci_ClockControl(SDC_CLOCK_WIDEBUS_MODE, false);
01544   }
01545 
01546   /* set block length */
01547   Ret = mci_SetBlockLength(_sdCardInfo.rca, MMC_SECTOR_SIZE);
01548   return Ret;
01549 }
01550 
01551 bool MCIFileSystem::mci_CheckR1Response(uint32_t resp, ReturnCode* pCheckResult) const
01552 {
01553   bool Ret = true;
01554 
01555   if (!(resp & R1_READY_FOR_DATA)) {
01556     *pCheckResult = SDC_RET_NOT_READY;
01557     Ret = false;
01558   }
01559   else if (R1_STATUS(resp)) {
01560     *pCheckResult =  SDC_RET_FAILED;
01561   }
01562   else {
01563     *pCheckResult =  SDC_RET_OK;
01564   }
01565   return Ret;
01566 }
01567 
01568 void MCIFileSystem::mci_WriteDelay() const
01569 {
01570   wait_us(10);
01571 }
01572 
01573 MCIFileSystem::ReturnCode MCIFileSystem::mci_SendCmd(uint32_t Command, uint32_t Arg, uint32_t timeout) const
01574 {
01575   ReturnCode ret = SDC_RET_TIMEOUT;
01576   uint32_t Status;
01577 
01578   /* Set Command Info */
01579   mci_SetCommand(Command, Arg);
01580 
01581   while (timeout) {
01582 
01583     Status = LPC_MCI->STATUS;
01584 
01585     /* check if command was sent */
01586     if (((Command & SDC_COMMAND_RSP_BITMASK) == SDC_COMMAND_NO_RSP) && (Status & SDC_STATUS_CMDSENT)) {
01587       ret =  SDC_RET_OK;
01588       break;
01589     }
01590     /* check if response was received */
01591     if (Status & SDC_STATUS_CMDRESPEND) {
01592       ret = SDC_RET_OK;
01593       break;
01594     }
01595 
01596     /* check command sending status */
01597     if (Status & SDC_STATUS_CMDERR) {
01598       if (Status & SDC_STATUS_CMDCRCFAIL) {
01599         if ((SDC_COMMAND_INDEX(Command) == MMC_SEND_OP_COND) ||
01600             (SDC_COMMAND_INDEX(Command) == SD_APP_OP_COND) ||
01601             (SDC_COMMAND_INDEX(Command) == MMC_STOP_TRANSMISSION)) {
01602           ret = SDC_RET_OK;  /* ignore CRC error if it's a resp for SEND_OP_COND  or STOP_TRANSMISSION. */
01603           break;
01604         }
01605       }
01606       ret = SDC_RET_CMD_FAILED;
01607       break;
01608     }
01609 
01610     timeout--;
01611   }
01612 
01613   mci_ResetCommand();
01614 
01615   return ret;
01616 }
01617 
01618 MCIFileSystem::ReturnCode MCIFileSystem::mci_SendAppCmd(uint16_t rca) const
01619 {
01620   ReturnCode Ret = SDC_RET_FAILED;
01621   response_t Response;
01622   uint32_t RetryCnt =  20;
01623 
01624   while (RetryCnt > 0) {
01625     Ret = mci_ExecuteCmd(SD_CMD55_APP_CMD, CMD55_RCA(rca), &Response);
01626     if (Ret == SDC_RET_OK) {
01627       if (mci_CheckR1Response(Response.Data[0], &Ret)) {
01628         if (Ret != SDC_RET_OK) {
01629           return Ret;
01630         }
01631         if (Response.Data[0] & R1_APP_CMD) {
01632           return SDC_RET_OK;
01633         }
01634         else {
01635           Ret = SDC_RET_FAILED;
01636         }
01637       }
01638     }
01639     RetryCnt--;
01640   }
01641   return SDC_RET_FAILED;
01642 }
01643 
01644 void MCIFileSystem::mci_SetDataTransfer(uint16_t BlockNum, bool DirFromCard, uint32_t Timeout) const
01645 {
01646   uint32_t DataCtrl = 0;
01647   LPC_MCI->DATATMR = Timeout;
01648   LPC_MCI->DATALEN = BlockNum * 512;
01649 
01650   DataCtrl = SDC_DATACTRL_ENABLE;
01651   // DataCtrl mode=block, block size=512byte
01652   DataCtrl |= (0x9 << 4);
01653   if (DirFromCard) {
01654     DataCtrl |= (0x1 << 1);
01655   }
01656   DataCtrl |= SDC_DATACTRL_DMA_ENABLE;
01657   LPC_MCI->DATACTRL = DataCtrl;
01658   mci_WriteDelay();
01659 }
01660 
01661 void MCIFileSystem::mci_GetResp(response_t* pResp) const
01662 {
01663   pResp->CmdIndex = SDC_RESPCOMMAND_VAL(LPC_MCI->RESP_CMD);
01664   pResp->Data[0] = LPC_MCI->RESP0;
01665   if (CardStatusNumBytes == 4) {
01666     pResp->Data[1] = LPC_MCI->RESP1;
01667     pResp->Data[2] = LPC_MCI->RESP2;
01668     pResp->Data[3] = LPC_MCI->RESP3;
01669   }
01670 }
01671 
01672 uint32_t MCIFileSystem::mci_GetBits(int32_t start, int32_t end, uint32_t *data) const
01673 {
01674   uint32_t v;
01675   uint32_t i = end >> 5;
01676   uint32_t j = start & 0x1f;
01677 
01678   if (i == (start >> 5)) {
01679     v = (data[i] >> j);
01680   }
01681   else {
01682     v = ((data[i] << (32 - j)) | (data[start >> 5] >> j));
01683   }
01684 
01685   return v & ((1 << (end - start + 1)) - 1);
01686 }
01687 
01688 void MCIFileSystem::mci_SetCommand(uint32_t Cmd, uint32_t Arg) const
01689 {
01690   /* Clear status register */
01691   LPC_MCI->CLEAR = SDC_CLEAR_ALL;
01692 
01693   /* Set the argument first, finally command */
01694   LPC_MCI->ARGUMENT = Arg;
01695 
01696   /* Write command value, enable the command */
01697   LPC_MCI->COMMAND = Cmd | SDC_COMMAND_ENABLE;
01698 
01699   mci_WriteDelay();
01700 }
01701 
01702 void MCIFileSystem::mci_ResetCommand() const
01703 {
01704   LPC_MCI->CLEAR = SDC_CLEAR_ALL;
01705 
01706   LPC_MCI->ARGUMENT = 0xFFFFFFFF;
01707 
01708   LPC_MCI->COMMAND = 0;
01709 
01710   mci_WriteDelay();
01711 }
01712 
01713 int32_t MCIFileSystem::mci_IRQHandler(uint8_t *txBuf, uint32_t *txCnt, uint8_t *rxBuf, uint32_t *rxCnt)
01714 {
01715   uint32_t Status;
01716 
01717   Status = LPC_MCI->STATUS;
01718 
01719   if ( Status & SDC_STATUS_DATAERR) {
01720     LPC_MCI->CLEAR = SDC_STATUS_DATAERR;
01721     return -1;  /* Data transfer error */
01722   }
01723 
01724   if ( Status & SDC_STATUS_DATAEND) {
01725     LPC_MCI->CLEAR = SDC_STATUS_DATAEND;
01726     LPC_MCI->MASK0 = 0;
01727     return 0;
01728   }
01729 
01730   if ( Status & SDC_STATUS_DATABLOCKEND) {
01731     LPC_MCI->CLEAR = SDC_STATUS_DATABLOCKEND;
01732     return 1;
01733   }
01734 
01735   if (Status & SDC_STATUS_FIFO) {
01736     return mci_FIFOIRQHandler(txBuf, txCnt, rxBuf, rxCnt);
01737   }
01738 
01739   return 1;
01740 }
01741 
01742 int32_t MCIFileSystem::mci_FIFOIRQHandler(uint8_t *txBuf, uint32_t *txCnt, uint8_t *rxBuf, uint32_t *rxCnt)
01743 {
01744   uint32_t Status;
01745   Status = LPC_MCI->STATUS;
01746 
01747   if (txBuf) {
01748     if (Status & SDC_STATUS_TXFIFOHALFEMPTY) {
01749       if (*txCnt % 64) {
01750         mci_WriteFIFO((uint32_t *) &txBuf[*txCnt], false);
01751       }
01752       else {
01753         mci_WriteFIFO((uint32_t *) &txBuf[*txCnt], true);
01754       }
01755       *txCnt += 32;
01756     }
01757   }
01758 
01759   if (rxBuf) {
01760     if (Status & SDC_STATUS_RXFIFOHALFFULL) {
01761       if (*rxCnt % 64) {
01762         mci_ReadFIFO((uint32_t *) &rxBuf[*rxCnt], false);
01763       }
01764       else {
01765         mci_ReadFIFO((uint32_t *) &rxBuf[*rxCnt], true);
01766       }
01767       *rxCnt += 32;
01768     }
01769   }
01770 
01771   LPC_MCI->CLEAR = SDC_STATUS_FIFO;
01772 
01773   return 1;
01774 }
01775 
01776 void MCIFileSystem::mci_ReadFIFO(uint32_t *pDst, bool bFirstHalf) const
01777 {
01778   uint8_t start = 0, end = 7;
01779 
01780   if (!bFirstHalf) {
01781     start += 8;
01782     end += 8;
01783   }
01784   for (; start <= end; start++) {
01785     *pDst = LPC_MCI->FIFO[start];
01786     pDst++;
01787   }
01788 }
01789 
01790 void MCIFileSystem::mci_WriteFIFO(uint32_t *pSrc, bool bFirstHalf) const
01791 {
01792   uint8_t start = 0, end = 7;
01793   if (!bFirstHalf) {
01794     start += 8;
01795     end += 8;
01796   }
01797   for (; start <= end; start++) {
01798     LPC_MCI->FIFO[start] = *pSrc;
01799     pSrc++;
01800   }
01801 }
01802 
01803 void MCIFileSystem::mci_SetupEventWakeup()
01804 {
01805   /* Wait for IRQ - for an RTOS, you would pend on an event here with a IRQ based wakeup. */
01806 
01807   _eventReceived = false;
01808   _eventSuccess = false;
01809 }
01810 
01811 uint32_t MCIFileSystem::mci_WaitForEvent() const
01812 {
01813   /* Wait for the event (DMA or MCI interrupt) for a maximum of 2 seconds */
01814   uint32_t end = us_ticker_read() + 2*1000*1000;
01815   while ((us_ticker_read() < end) && (!_eventReceived))
01816   {
01817     // If the driver is having problems reading the card, adding a delay here
01818     // might help.
01819     //wait(0.01);
01820     ThisThread::sleep_for(10);
01821   }
01822   
01823   if (_eventReceived && _eventSuccess) {
01824     return 0;
01825   }
01826 
01827   return 1;
01828 }
01829 
01830 MCIFileSystem::ReturnCode MCIFileSystem::_readBlocks(uint32_t card_type, uint32_t startBlock, uint32_t blockNum) const
01831 {
01832   ReturnCode Ret = SDC_RET_FAILED;
01833   response_t Response;
01834   uint32_t Command, Argument;
01835   uint8_t RetryCnt =  0x20;
01836 
01837   if (blockNum == 1) {
01838     Command = SD_CMD17_READ_SINGLE_BLOCK;
01839   }
01840   else {
01841     Command = SD_CMD18_READ_MULTIPLE_BLOCK;
01842   }
01843 
01844   /* Select single or multiple read based on number of blocks */
01845   /* if high capacity card use block indexing */
01846   if (card_type & CARD_TYPE_HC) {
01847     Argument = startBlock;
01848   }
01849   else {  /*fix at 512 bytes*/
01850     Argument = startBlock << 9;
01851   }
01852 
01853   while (RetryCnt > 0) {
01854     Ret = mci_ExecuteCmd(Command, Argument, &Response);
01855     if (Ret == SDC_RET_OK) {
01856       if (mci_CheckR1Response(Response.Data[0], &Ret)) {
01857         return Ret;
01858       }
01859     }
01860     RetryCnt--;
01861   }
01862   return Ret;
01863 }
01864 
01865 MCIFileSystem::ReturnCode MCIFileSystem::_writeBlocks(uint32_t card_type, uint32_t startBlock, uint32_t blockNum) const
01866 {
01867   ReturnCode Ret = SDC_RET_FAILED;
01868   response_t Response;
01869   uint32_t Command, Argument;
01870   uint8_t RetryCnt =  0x20;
01871 
01872   if (blockNum == 1) {
01873     Command = SD_CMD24_WRITE_BLOCK;
01874   }
01875   else {
01876     Command = SD_CMD25_WRITE_MULTIPLE_BLOCK;
01877   }
01878 
01879   /* if high capacity card use block indexing */
01880   if (card_type & CARD_TYPE_HC) {
01881     Argument = startBlock;
01882   }
01883   else {  /*fix at 512 bytes*/
01884     Argument = startBlock << 9;
01885 
01886   }
01887 
01888   while (RetryCnt > 0) {
01889     Ret = mci_ExecuteCmd(Command, Argument, &Response);
01890     if (Ret == SDC_RET_OK) {
01891       if (mci_CheckR1Response(Response.Data[0], &Ret)) {
01892         return Ret;
01893       }
01894     }
01895     RetryCnt--;
01896   }
01897   return Ret;
01898 }