Wei Chang Shen / DMSupport

Dependencies:   DM_FATFileSystem EthernetInterface HTTPClient mbed-rtos mbed-src

Fork of DMSupport by Embedded Artists

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MCIFileSystem.cpp Source File

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  Possible SDMMC card state types
00349  */
00350 typedef enum {
00351   SDMMC_IDLE_ST = 0,  /*!< Idle state */
00352   SDMMC_READY_ST,     /*!< Ready state */
00353   SDMMC_IDENT_ST,     /*!< Identification State */
00354   SDMMC_STBY_ST,      /*!< standby state */
00355   SDMMC_TRAN_ST,      /*!< transfer state */
00356   SDMMC_DATA_ST,      /*!< Sending-data State */
00357   SDMMC_RCV_ST,       /*!< Receive-data State */
00358   SDMMC_PRG_ST,       /*!< Programming State */
00359   SDMMC_DIS_ST        /*!< Disconnect State */
00360 } SDMMC_STATE_T;
00361 
00362 
00363 /**
00364  * @brief SD/MMC commands, arguments and responses
00365  * Standard SD/MMC commands (3.1)       type  argument     response
00366  */
00367 /* class 1 */
00368 #define MMC_GO_IDLE_STATE         0    /* bc                          */
00369 #define MMC_SEND_OP_COND          1    /* bcr  [31:0]  OCR        R3  */
00370 #define MMC_ALL_SEND_CID          2    /* bcr                     R2  */
00371 #define MMC_SET_RELATIVE_ADDR     3    /* ac   [31:16] RCA        R1  */
00372 #define MMC_SET_DSR               4    /* bc   [31:16] RCA            */
00373 #define MMC_SELECT_CARD           7    /* ac   [31:16] RCA        R1  */
00374 #define MMC_SEND_EXT_CSD          8    /* bc                      R1  */
00375 #define MMC_SEND_CSD              9    /* ac   [31:16] RCA        R2  */
00376 #define MMC_SEND_CID             10    /* ac   [31:16] RCA        R2  */
00377 #define MMC_STOP_TRANSMISSION    12    /* ac                      R1b */
00378 #define MMC_SEND_STATUS          13    /* ac   [31:16] RCA        R1  */
00379 #define MMC_GO_INACTIVE_STATE    15    /* ac   [31:16] RCA            */
00380 
00381 /* class 2 */
00382 #define MMC_SET_BLOCKLEN         16    /* ac   [31:0]  block len  R1  */
00383 #define MMC_READ_SINGLE_BLOCK    17    /* adtc [31:0]  data addr  R1  */
00384 #define MMC_READ_MULTIPLE_BLOCK  18    /* adtc [31:0]  data addr  R1  */
00385 
00386 /* class 3 */
00387 #define MMC_WRITE_DAT_UNTIL_STOP 20    /* adtc [31:0]  data addr  R1  */
00388 
00389 /* class 4 */
00390 #define MMC_SET_BLOCK_COUNT      23    /* adtc [31:0]  data addr  R1  */
00391 #define MMC_WRITE_BLOCK          24    /* adtc [31:0]  data addr  R1  */
00392 #define MMC_WRITE_MULTIPLE_BLOCK 25    /* adtc                    R1  */
00393 #define MMC_PROGRAM_CID          26    /* adtc                    R1  */
00394 #define MMC_PROGRAM_CSD          27    /* adtc                    R1  */
00395 
00396 /* class 6 */
00397 #define MMC_SET_WRITE_PROT       28    /* ac   [31:0]  data addr  R1b */
00398 #define MMC_CLR_WRITE_PROT       29    /* ac   [31:0]  data addr  R1b */
00399 #define MMC_SEND_WRITE_PROT      30    /* adtc [31:0]  wpdata addr R1  */
00400 
00401 /* class 5 */
00402 #define MMC_ERASE_GROUP_START    35    /* ac   [31:0]  data addr  R1  */
00403 #define MMC_ERASE_GROUP_END      36    /* ac   [31:0]  data addr  R1  */
00404 #define MMC_ERASE                37    /* ac                      R1b */
00405 #define SD_ERASE_WR_BLK_START    32    /* ac   [31:0]  data addr  R1  */
00406 #define SD_ERASE_WR_BLK_END      33    /* ac   [31:0]  data addr  R1  */
00407 #define SD_ERASE                 38    /* ac                      R1b */
00408 
00409 /* class 9 */
00410 #define MMC_FAST_IO              39    /* ac   <Complex>          R4  */
00411 #define MMC_GO_IRQ_STATE         40    /* bcr                     R5  */
00412 
00413 /* class 7 */
00414 #define MMC_LOCK_UNLOCK          42    /* adtc                    R1b */
00415 
00416 /* class 8 */
00417 #define MMC_APP_CMD              55    /* ac   [31:16] RCA        R1  */
00418 #define MMC_GEN_CMD              56    /* adtc [0]     RD/WR      R1b */
00419 
00420 /* SD commands                           type  argument     response */
00421 /* class 8 */
00422 /* This is basically the same command as for MMC with some quirks. */
00423 #define SD_SEND_RELATIVE_ADDR     3    /* ac                      R6  */
00424 #define SD_CMD8                   8    /* bcr  [31:0]  OCR        R3  */
00425 
00426 /* Application commands */
00427 #define SD_APP_SET_BUS_WIDTH      6    /* ac   [1:0]   bus width  R1   */
00428 #define SD_APP_OP_COND           41    /* bcr  [31:0]  OCR        R1 (R4)  */
00429 #define SD_APP_SEND_SCR          51    /* adtc                    R1   */
00430 
00431 
00432 /**
00433  * @brief MMC status in R1<br>
00434  * Type<br>
00435  *   e : error bit<br>
00436  *   s : status bit<br>
00437  *   r : detected and set for the actual command response<br>
00438  *   x : detected and set during command execution. the host must poll
00439  *       the card by sending status command in order to read these bits.
00440  * Clear condition<br>
00441  *   a : according to the card state<br>
00442  *   b : always related to the previous command. Reception of
00443  *       a valid command will clear it (with a delay of one command)<br>
00444  *   c : clear by read<br>
00445  */
00446 
00447 #define R1_OUT_OF_RANGE         (1UL << 31)  /* er, c */
00448 #define R1_ADDRESS_ERROR        (1 << 30)  /* erx, c */
00449 #define R1_BLOCK_LEN_ERROR      (1 << 29)  /* er, c */
00450 #define R1_ERASE_SEQ_ERROR      (1 << 28)  /* er, c */
00451 #define R1_ERASE_PARAM          (1 << 27)  /* ex, c */
00452 #define R1_WP_VIOLATION         (1 << 26)  /* erx, c */
00453 #define R1_CARD_IS_LOCKED       (1 << 25)  /* sx, a */
00454 #define R1_LOCK_UNLOCK_FAILED   (1 << 24)  /* erx, c */
00455 #define R1_COM_CRC_ERROR        (1 << 23)  /* er, b */
00456 #define R1_ILLEGAL_COMMAND      (1 << 22)  /* er, b */
00457 #define R1_CARD_ECC_FAILED      (1 << 21)  /* ex, c */
00458 #define R1_CC_ERROR             (1 << 20)  /* erx, c */
00459 #define R1_ERROR                (1 << 19)  /* erx, c */
00460 #define R1_UNDERRUN             (1 << 18)  /* ex, c */
00461 #define R1_OVERRUN              (1 << 17)  /* ex, c */
00462 #define R1_CID_CSD_OVERWRITE    (1 << 16)  /* erx, c, CID/CSD overwrite */
00463 #define R1_WP_ERASE_SKIP        (1 << 15)  /* sx, c */
00464 #define R1_CARD_ECC_DISABLED    (1 << 14)  /* sx, a */
00465 #define R1_ERASE_RESET          (1 << 13)  /* sr, c */
00466 #define R1_STATUS(x)            (x & 0xFFFFE000)
00467 #define R1_CURRENT_STATE(x)     ((x & 0x00001E00) >> 9)  /* sx, b (4 bits) */
00468 #define R1_READY_FOR_DATA       (1 << 8)  /* sx, a */
00469 #define R1_APP_CMD              (1 << 5)  /* sr, c */
00470 
00471 
00472 /**
00473  * @brief SD/MMC card OCR register bits
00474  */
00475 #define OCR_ALL_READY           (1UL << 31)  /* Card Power up status bit */
00476 #define OCR_HC_CCS              (1 << 30)  /* High capacity card */
00477 #define OCR_VOLTAGE_RANGE_MSK   (0x00FF8000)
00478 
00479 #define SD_SEND_IF_ARG          0x000001AA
00480 #define SD_SEND_IF_ECHO_MSK     0x000000FF
00481 #define SD_SEND_IF_RESP         0x000000AA
00482 
00483 /**
00484  * @brief R3 response definitions
00485  */
00486 #define CMDRESP_R3_OCR_VAL(n)           (((uint32_t) n) & 0xFFFFFF)
00487 #define CMDRESP_R3_S18A                 (((uint32_t) 1 ) << 24)
00488 #define CMDRESP_R3_HC_CCS               (((uint32_t) 1 ) << 30)
00489 #define CMDRESP_R3_INIT_COMPLETE        (((uint32_t) 1 ) << 31)
00490 
00491 /**
00492  * @brief R6 response definitions
00493  */
00494 #define CMDRESP_R6_RCA_VAL(n)           (((uint32_t) (n >> 16)) & 0xFFFF)
00495 #define CMDRESP_R6_CARD_STATUS(n)       (((uint32_t) (n & 0x1FFF)) | \
00496                      ((n & (1 << 13)) ? (1 << 19) : 0) | \
00497                      ((n & (1 << 14)) ? (1 << 22) : 0) | \
00498                      ((n & (1 << 15)) ? (1 << 23) : 0))
00499 
00500 /**
00501  * @brief R7 response definitions
00502  */
00503 /** Echo-back of check-pattern */
00504 #define CMDRESP_R7_CHECK_PATTERN(n)     (((uint32_t) n ) & 0xFF)
00505 /** Voltage accepted */
00506 #define CMDRESP_R7_VOLTAGE_ACCEPTED     (((uint32_t) 1 ) << 8)
00507 
00508 /**
00509  * @brief CMD3 command definitions
00510  */
00511 /** Card Address */
00512 #define CMD3_RCA(n)         (((uint32_t) (n & 0xFFFF) ) << 16)
00513 
00514 /**
00515  * @brief CMD7 command definitions
00516  */
00517 /** Card Address */
00518 #define CMD7_RCA(n)         (((uint32_t) (n & 0xFFFF) ) << 16)
00519 
00520 /**
00521  * @brief CMD8 command definitions
00522  */
00523 /** Check pattern */
00524 #define CMD8_CHECKPATTERN(n)            (((uint32_t) (n & 0xFF) ) << 0)
00525 /** Recommended pattern */
00526 #define CMD8_DEF_PATTERN                    (0xAA)
00527 /** Voltage supplied.*/
00528 #define CMD8_VOLTAGESUPPLIED_27_36     (((uint32_t) 1 ) << 8)
00529 
00530 /**
00531  * @brief CMD9 command definitions
00532  */
00533 #define CMD9_RCA(n)         (((uint32_t) (n & 0xFFFF) ) << 16)
00534 
00535 /**
00536  * @brief CMD13 command definitions
00537  */
00538 #define CMD13_RCA(n)            (((uint32_t) (n & 0xFFFF) ) << 16)
00539 
00540 /**
00541  * @brief APP_CMD command definitions
00542  */
00543 #define CMD55_RCA(n)            (((uint32_t) (n & 0xFFFF) ) << 16)
00544 
00545 /**
00546  * @brief ACMD41 command definitions
00547  */
00548 #define ACMD41_OCR(n)                   (((uint32_t) n) & 0xFFFFFF)
00549 #define ACMD41_S18R                     (((uint32_t) 1 ) << 24)
00550 #define ACMD41_XPC                      (((uint32_t) 1 ) << 28)
00551 #define ACMD41_HCS                      (((uint32_t) 1 ) << 30)
00552 
00553 /**
00554  * @brief ACMD6 command definitions
00555  */
00556 #define ACMD6_BUS_WIDTH(n)              ((uint32_t) n & 0x03)
00557 #define ACMD6_BUS_WIDTH_1               (0)
00558 #define ACMD6_BUS_WIDTH_4               (2)
00559 
00560 /** @brief Card type defines
00561  */
00562 #define CARD_TYPE_SD    (1 << 0)
00563 #define CARD_TYPE_4BIT  (1 << 1)
00564 #define CARD_TYPE_8BIT  (1 << 2)
00565 #define CARD_TYPE_HC    (OCR_HC_CCS)/*!< high capacity card > 2GB */
00566 
00567 /**
00568  * @brief SD/MMC sector size in bytes
00569  */
00570 #define MMC_SECTOR_SIZE     512
00571 
00572 /******************************************************************************
00573  * External global variables
00574  *****************************************************************************/
00575 
00576 /******************************************************************************
00577  * Local variables
00578  *****************************************************************************/
00579 
00580 static MCIFileSystem* pUglyForIRQ = NULL;
00581 
00582 /******************************************************************************
00583  * Local Functions
00584  *****************************************************************************/
00585 
00586 static void mymciirq()
00587 {
00588   pUglyForIRQ->mci_MCIIRQHandler();
00589 }
00590 
00591 static void mydmairq()
00592 {
00593   pUglyForIRQ->mci_DMAIRQHandler();
00594 }
00595 
00596 /******************************************************************************
00597  * Public Functions
00598  *****************************************************************************/
00599 
00600 MCIFileSystem::MCIFileSystem(const char* name, PinName cd) :
00601     FATFileSystem(name)
00602 {
00603     pUglyForIRQ = this;
00604 
00605     _Stat = STA_NOINIT;
00606     memset(&_sdCardInfo, 0, sizeof(SDMMC_CARD_T));
00607     _eventReceived = false;
00608     _eventSuccess = false;
00609 
00610     initMCI();
00611 
00612     if (cd == NC)
00613     {
00614         _cardDetect = NULL;
00615     }
00616     else
00617     {
00618       _cardDetect = new DigitalIn(cd);
00619       _cardDetect->mode(PullUp);
00620     }
00621 }
00622 
00623 MCIFileSystem::~MCIFileSystem()
00624 {
00625   if (_cardDetect != NULL)
00626   {
00627     delete _cardDetect;
00628   }
00629 }
00630 void MCIFileSystem::initMCI()
00631 {
00632     // Pinsel for MCI
00633     LPC_IOCON->P1_2  = 2;          /* SD_CLK @ P1.2 */
00634     LPC_IOCON->P1_3  = 2;          /* SD_CMD @ P1.3 */
00635     LPC_IOCON->P1_5  = 2 | (1<<7); /* SD_PWR @ P1.5 - digital mode */
00636     LPC_IOCON->P1_6  = 2 | (1<<7); /* SD_DAT[0] @ P1.6 - digital mode */
00637     LPC_IOCON->P1_7  = 2 | (1<<7); /* SD_DAT[1] @ P1.7 - digital mode */
00638     LPC_IOCON->P1_11 = 2;          /* SD_DAT[2] @ P1.11 */
00639     LPC_IOCON->P1_12 = 2;          /* SD_DAT[3] @ P1.12 */
00640 
00641     LPC_SC->PCONP |= SYSCTL_CLOCK_SDC;
00642     LPC_SC->RSTCON0 = (1<<28);
00643     LPC_SC->RSTCON0 &= ~(1<<28);
00644 
00645     /* Initialize SDC peripheral */
00646     LPC_SC->PCONP |= SYSCTL_CLOCK_SDC;
00647 
00648     /* Disable SD_CLK */
00649     mci_ClockControl(SDC_CLOCK_ENABLE, false);
00650 
00651     /* Power-off */
00652     mci_PowerControl(PowerOff, 0);
00653     mci_WriteDelay();
00654 
00655     /* Disable all interrupts */
00656     LPC_MCI->MASK0 = 0;
00657 
00658     /*Setting for timeout problem */
00659     LPC_MCI->DATATMR = 0x1FFFFFFF;
00660 
00661     LPC_MCI->COMMAND = 0;
00662     mci_WriteDelay();
00663 
00664     LPC_MCI->DATACTRL = 0;
00665     mci_WriteDelay();
00666 
00667     /* clear all pending interrupts */
00668     LPC_MCI->CLEAR = SDC_CLEAR_ALL;
00669 
00670     /* Power-up SDC Peripheral */
00671     mci_PowerControl(PowerUp, 0);
00672 
00673     /* delays for the supply output is stable*/
00674     for (uint32_t i = 0; i < 0x80000; i++ ) {}
00675 
00676     mci_SetClock(SDC_IDENT_CLOCK_RATE);
00677     mci_ClockControl(SDC_CLOCK_ENABLE, true);
00678 
00679     /* Power-on SDC Interface */
00680     mci_PowerControl(PowerOn, 0);
00681 
00682     NVIC_SetVector(MCI_IRQn, (uint32_t) mymciirq);
00683     NVIC_EnableIRQ(MCI_IRQn);
00684 
00685     /* Initialize GPDMA controller */
00686     _eventDmaChannel = GPDMA::instance().acquireChannel(mydmairq);
00687 }
00688 
00689 int MCIFileSystem::disk_initialize() {
00690 
00691     debug_if(MCI_DBG, "mcifs:disk_initialize(), _Stat = %#x\n", _Stat);
00692 
00693     if (!cardInserted()) {
00694       /* No card in the socket */
00695       _Stat = STA_NODISK | STA_NOINIT;
00696     }
00697 
00698     if (_Stat != STA_NOINIT) {
00699         return _Stat;          /* card is already enumerated */
00700     }
00701 
00702     //rtc_init();
00703 
00704     /* Initialize the Card Data Strucutre */
00705     memset(&_sdCardInfo, 0, sizeof(SDMMC_CARD_T));
00706 
00707     /* Reset */
00708     _Stat = STA_NOINIT;
00709 
00710     /* Enumerate the card once detected. Note this function may block for a little while. */
00711     int ret = mci_Acquire();
00712     if (ret != 1) {
00713       debug("Card Acquire failed... got %d, but expected 1\r\n", ret);
00714       return 1;//Stat;
00715     }
00716 
00717     _Stat &= ~STA_NOINIT;
00718     return _Stat;
00719 }
00720 
00721 int MCIFileSystem::disk_write(const uint8_t *buffer, uint64_t block_number, uint8_t count) {
00722     debug_if(MCI_DBG, "mcifs:disk_write(%#x, %llu, %u), _Stat = %#x\n", (uint32_t)buffer, block_number, count, _Stat);
00723     if (_Stat & STA_NOINIT) {
00724         // not ready
00725         return 1;
00726     }
00727     if (mci_WriteBlocks((void*)buffer, block_number, count) == SDC_RET_OK) {
00728         return 0;
00729     }
00730 
00731     return 1;
00732 }
00733 
00734 int MCIFileSystem::disk_read(uint8_t *buffer, uint64_t block_number, uint8_t count) {
00735     debug_if(MCI_DBG, "mcifs:disk_read(%#x, %llu, %u), _Stat = %#x\n", (uint32_t)buffer, block_number, count, _Stat);
00736     if (_Stat & STA_NOINIT) {
00737         // not ready
00738         return _Stat;
00739     }
00740     if (mci_ReadBlocks(buffer, block_number, count) == SDC_RET_OK) {
00741         return 0;
00742     }
00743 
00744     return 1;
00745 }
00746 
00747 int MCIFileSystem::disk_status()
00748 {
00749   debug_if(MCI_DBG, "mcifs:disk_status(), _Stat = %#x\n", _Stat);
00750   return _Stat;
00751 }
00752 
00753 int MCIFileSystem::disk_sync()
00754 {
00755   debug_if(MCI_DBG, "mcifs:disk_sync(), _Stat = %#x\n", _Stat);
00756   uint32_t end = us_ticker_read() + 50*1000; // 50ms
00757   while (us_ticker_read() < end)
00758   {
00759     if (mci_GetCardStatus() & R1_READY_FOR_DATA)
00760     {
00761       // card is ready
00762       return 0;
00763     }
00764   }
00765   // timeout while waiting for card to get ready
00766   return 1;
00767 }
00768 
00769 uint64_t MCIFileSystem::disk_sectors()
00770 {
00771     debug_if(MCI_DBG, "mcifs:disk_sectors(), _Stat = %#x, returning %llu\n", _Stat, _sdCardInfo.blocknr);
00772     return _sdCardInfo.blocknr;
00773 }
00774 
00775 void MCIFileSystem::mci_MCIIRQHandler()
00776 {
00777   int32_t Ret;
00778 
00779   Ret = mci_IRQHandler(NULL, 0, NULL, 0);
00780   if(Ret < 0) {
00781     _eventSuccess = false;
00782     _eventReceived = true;
00783   }
00784 }
00785 
00786 void MCIFileSystem::mci_DMAIRQHandler()
00787 {
00788   _eventSuccess = LPC_GPDMA->IntTCStat & (1<<_eventDmaChannel);
00789   _eventReceived = true;
00790   LPC_GPDMA->IntTCClear = (1<<_eventDmaChannel);
00791   LPC_GPDMA->IntErrClr = (1<<_eventDmaChannel);
00792 }
00793 
00794 /******************************************************************************
00795  * Private Functions
00796  *****************************************************************************/
00797 
00798 static bool gpdma_transfer_to_mci(GPDMA::DMAChannels ChannelNum,
00799                                   uint32_t src,
00800                                   uint32_t Size)
00801 {
00802   GPDMA::GPDMA_Channel_CFG_T cfg;
00803   cfg.ChannelNum = ChannelNum;
00804   cfg.TransferType = GPDMA::FlowControl_M2P_Ctrl_Periph;
00805   cfg.TransferSize = Size;
00806   cfg.TransferWidth = 0;
00807   cfg.SrcAddr = src;
00808   cfg.DstAddr = (uint32_t) (&LPC_MCI->FIFO);
00809 
00810   uint32_t ctrl_word =
00811       GPDMA_DMACCxControl_TransferSize((uint32_t) cfg.TransferSize)
00812           | GPDMA_DMACCxControl_SBSize(GPDMA_BSIZE_8)
00813           | GPDMA_DMACCxControl_DBSize(GPDMA_BSIZE_8)
00814           | GPDMA_DMACCxControl_SWidth(GPDMA_WIDTH_WORD)
00815           | GPDMA_DMACCxControl_DWidth(GPDMA_WIDTH_WORD)
00816           | GPDMA_DMACCxControl_DestTransUseAHBMaster1
00817           | GPDMA_DMACCxControl_SI
00818           | GPDMA_DMACCxControl_I;
00819 
00820   /* Select SD card interface in the DMA MUX*/
00821   LPC_SC->DMAREQSEL &= ~(1 << 1);
00822 
00823   return GPDMA::instance().transfer(&cfg, ctrl_word, 0, GPDMA_CONN_MEMORY, GPDMA_CONN_SDC);
00824 }
00825 
00826 static bool gpdma_transfer_from_mci(GPDMA::DMAChannels ChannelNum,
00827                              uint32_t dst,
00828                              uint32_t Size)
00829 {
00830   GPDMA::GPDMA_Channel_CFG_T cfg;
00831   cfg.ChannelNum = ChannelNum;
00832   cfg.TransferType = GPDMA::FlowControl_P2M_Ctrl_Periph;
00833   cfg.TransferSize = Size;
00834   cfg.TransferWidth = 0;
00835   cfg.SrcAddr = (uint32_t) (&LPC_MCI->FIFO);
00836   cfg.DstAddr = dst;
00837 
00838   uint32_t ctrl_word =
00839       GPDMA_DMACCxControl_TransferSize((uint32_t) cfg.TransferSize)
00840           | GPDMA_DMACCxControl_SBSize(GPDMA_BSIZE_8)
00841           | GPDMA_DMACCxControl_DBSize(GPDMA_BSIZE_8)
00842           | GPDMA_DMACCxControl_SWidth(GPDMA_WIDTH_WORD)
00843           | GPDMA_DMACCxControl_DWidth(GPDMA_WIDTH_WORD)
00844           | GPDMA_DMACCxControl_SrcTransUseAHBMaster1
00845           | GPDMA_DMACCxControl_DI
00846           | GPDMA_DMACCxControl_I;
00847 
00848   /* Select SD card interface in the DMA MUX*/
00849   LPC_SC->DMAREQSEL &= ~(1 << 1);
00850 
00851   return GPDMA::instance().transfer(&cfg, ctrl_word, 0, GPDMA_CONN_SDC, GPDMA_CONN_MEMORY);
00852 }
00853 
00854 bool MCIFileSystem::cardInserted() const
00855 {
00856     // If no card detect pin is given, then assume that a card is inserted.
00857     // If a pin is specified then use that to determing the presence of a card.
00858     return ((_cardDetect == NULL) || (_cardDetect->read() == 0));
00859 }
00860 
00861 
00862 
00863 int32_t MCIFileSystem::mci_Acquire()
00864 {
00865   int32_t Ret;
00866 
00867   /* Initialize card info */
00868   _sdCardInfo.speed = SDC_TRAN_CLOCK_RATE;
00869   _sdCardInfo.card_type = 0;
00870 
00871   /* During identification phase, the clock should be less than
00872      400Khz. Once we pass this phase, the normal clock can be set up
00873      to 25Mhz on SD card and 20Mhz on MMC card. */
00874   mci_SetClock(SDC_IDENT_CLOCK_RATE);
00875 
00876   /* Clear Open Drain output control for SD */
00877   mci_PowerControl(PowerOn, 0);
00878   
00879   /* Card Reset */
00880   Ret = mci_ExecuteCmd(SD_GO_IDLE_STATE, 0, NULL);
00881   if (Ret != 0) {
00882     return Ret;
00883   }
00884 
00885   Thread::wait(ACQUIRE_DELAY);
00886 
00887   /* Send interface operation condiftion */
00888   Ret = mci_SendIfCond();
00889   if (Ret == SDC_RET_BAD_PARAMETERS) {
00890     return Ret;    /* Non-compatible voltage range or check pattern is not correct */
00891 
00892   }
00893   /* Get Card Type */
00894   if (Ret == SDC_RET_OK) {/* Ver2.00 or later SD Memory Card*/
00895     bool CCS;
00896     uint32_t OCR = SDC_OCR_27_36;
00897     _sdCardInfo.card_type |= CARD_TYPE_SD;
00898     Ret = mci_SendAppOpCond(0, true, &OCR, &CCS);
00899     if (CCS) {  /* High Capacity or Extended Capacity SD Memory Card */
00900       _sdCardInfo.card_type |= CARD_TYPE_HC;
00901     }
00902   }
00903   else {  /*Ver2.00 or later SD Memory Card(voltage mismatch) or Ver1.X SD Memory Card
00904          or not SD Memory Card*/
00905     bool CCS;
00906     uint32_t OCR = SDC_OCR_27_36;
00907     Ret = mci_SendAppOpCond(0, false, &OCR, &CCS);
00908     if (Ret == SDC_RET_OK) {
00909       _sdCardInfo.card_type |= CARD_TYPE_SD;
00910     }
00911     else if (Ret == SDC_RET_BAD_PARAMETERS) {
00912       return Ret;
00913     }
00914     else {  /* MMC Card setup */
00915       uint32_t OCR;
00916       /* Enter to Open Drain mode */
00917       mci_PowerControl(PowerOn, SDC_PWR_OPENDRAIN);
00918       Thread::wait(ACQUIRE_DELAY);
00919       Ret = mci_SendOpCond(&OCR);
00920       if (Ret != SDC_RET_OK) {
00921         return Ret;
00922       }
00923 
00924     }
00925   }
00926 
00927   /* Read CID */
00928   mci_GetCID(_sdCardInfo.cid);
00929 
00930   /* RCA send, for SD get RCA */
00931   if (_sdCardInfo.card_type & CARD_TYPE_SD) {
00932     mci_GetAddr(&_sdCardInfo.rca);
00933   }
00934   else {
00935     _sdCardInfo.rca = 1;
00936     mci_SetAddr(_sdCardInfo.rca);
00937     mci_PowerControl(PowerOn, 0);  /* enter to push-pull mode */
00938   }
00939 
00940   /* Get CSD */
00941   mci_GetCSD(_sdCardInfo.rca, _sdCardInfo.csd);
00942 
00943   /* Compute card size, block size and no. of blocks  based on CSD response recived. */
00944   if (_sdCardInfo.cid[0]) {
00945     mci_ProcessCSD();
00946 
00947     if (mci_SetTranState(_sdCardInfo.rca) != SDC_RET_OK) {
00948       return 0;
00949     }
00950 
00951     if (mci_GetCardState() != SDMMC_TRAN_ST) {
00952       return 0;
00953     }
00954 
00955     if (mci_SetCardParams() != 0) {
00956       return 0;
00957     }
00958   }
00959 
00960   return (_sdCardInfo.cid[0]) ? 1 : 0;
00961 }
00962 
00963 uint32_t MCIFileSystem::mci_GetCardStatus() const
00964 {
00965   uint32_t Status;
00966   mci_GetStatus(_sdCardInfo.rca, &Status);
00967   return Status;
00968 }
00969 
00970 MCIFileSystem::CardState MCIFileSystem::mci_GetCardState() const
00971 {
00972   uint32_t Status;
00973   volatile int32_t Ret;
00974 
00975   /* get current state of the card */
00976   Ret = mci_GetStatus(_sdCardInfo.rca, &Status);
00977 
00978   /* check card state in response */
00979   return (CardState) R1_CURRENT_STATE(Status);
00980 }
00981 
00982 MCIFileSystem::ReturnCode MCIFileSystem::mci_StopTransmission(uint32_t rca) const
00983 {
00984   uint32_t Status;
00985   ReturnCode Ret = SDC_RET_FAILED;
00986   response_t Response;
00987   uint32_t RetryCnt =  20;
00988 
00989   Ret = mci_GetStatus(rca, &Status);
00990   if (Ret != SDC_RET_OK) {
00991     return SDC_RET_ERR_STATE;
00992   }
00993 
00994   if (R1_CURRENT_STATE(Status) == SDMMC_TRAN_ST) {
00995     return SDC_RET_OK;
00996   }
00997 
00998   if ((R1_CURRENT_STATE(Status) != SDMMC_DATA_ST) &&
00999     (R1_CURRENT_STATE(Status) != SDMMC_RCV_ST)) {
01000     return SDC_RET_ERR_STATE;
01001   }
01002 
01003   while (RetryCnt > 0) {
01004     Ret = mci_ExecuteCmd(SD_CMD12_STOP_TRANSMISSION, 0, &Response);
01005     if (Ret == SDC_RET_OK) {
01006       if (mci_CheckR1Response(Response.Data[0], &Ret)) {
01007         if (Ret != SDC_RET_OK) {
01008           return Ret;
01009         }
01010         Ret = mci_GetStatus(rca, &Status);
01011         if ((R1_CURRENT_STATE(Status) == SDMMC_TRAN_ST) || (R1_CURRENT_STATE(Status) == SDMMC_PRG_ST)) {
01012           return SDC_RET_OK;
01013         }
01014         return SDC_RET_ERR_STATE;
01015       }
01016     }
01017     RetryCnt--;
01018   }
01019   return Ret;
01020 }
01021 
01022 MCIFileSystem::ReturnCode MCIFileSystem::mci_ReadBlocks(void *buffer, int32_t startBlock, int32_t blockNum)
01023 {
01024   ReturnCode Ret = SDC_RET_FAILED;
01025   int32_t ByteNum = blockNum *  MMC_SECTOR_SIZE;
01026 
01027   do
01028   {
01029     /* if card is not acquired return immediately */
01030     if (( startBlock < 0) || ( (startBlock + blockNum) > _sdCardInfo.blocknr) ) {
01031       Ret = SDC_RET_NOT_READY;
01032       break;
01033     }
01034 
01035     /* Put to tran state */
01036     Ret = mci_SetTranState(_sdCardInfo.rca);
01037     if (Ret != SDC_RET_OK) {
01038       break;
01039     }
01040 
01041     LPC_MCI->MASK0 = SDC_MASK0_DATA | SDC_MASK0_RXDATAERR;
01042 
01043     /* DMA Setup */
01044     mci_SetupEventWakeup();
01045     gpdma_transfer_from_mci(_eventDmaChannel, (uint32_t)buffer, ByteNum);
01046 
01047     /* set transfer information */
01048     mci_SetDataTransfer(blockNum, true, DATA_TIMER_VALUE_R);
01049 
01050     Ret = _readBlocks(_sdCardInfo.card_type, startBlock, blockNum);
01051     if (Ret == SDC_RET_OK) {
01052       /* Wait for transfer Finish */
01053       if (mci_WaitForEvent() != 0) {
01054         Ret = SDC_RET_FAILED;
01055       }
01056     } else {
01057       Ret = SDC_RET_FAILED;
01058     }
01059 
01060     GPDMA::instance().stopTransfer(_eventDmaChannel);
01061 
01062     if ((blockNum > 1) || (mci_GetCardState() == SDMMC_DATA_ST)) {
01063       /* Send Stop transmission command */
01064       mci_StopTransmission(_sdCardInfo.rca);
01065     }
01066 
01067     /* Wait for card to enter tran state */
01068     while (mci_GetCardState() != SDMMC_TRAN_ST) {}
01069       
01070   } while(false);
01071 
01072   return Ret;
01073 }
01074 
01075 MCIFileSystem::ReturnCode MCIFileSystem::mci_WriteBlocks(void *buffer, int32_t startBlock, int32_t blockNum)
01076 {
01077   ReturnCode Ret = SDC_RET_FAILED;
01078   
01079   do
01080   {
01081     /* if card is not acquired return immediately */
01082     if (( startBlock < 0) || ( (startBlock + blockNum) > _sdCardInfo.blocknr) ) {
01083       Ret = SDC_RET_NOT_READY;
01084       break;
01085     }
01086 
01087     /* Put to tran state */
01088     Ret = mci_SetTranState(_sdCardInfo.rca);
01089     if (Ret != SDC_RET_OK) {
01090       break;
01091     }
01092 
01093     Ret = _writeBlocks(_sdCardInfo.card_type, startBlock, blockNum);
01094     if (Ret != SDC_RET_OK) {
01095       break;
01096     }
01097 
01098     /*Wait for card enter to rcv state*/
01099     while (mci_GetCardState() != SDMMC_RCV_ST) {}
01100 
01101     LPC_MCI->MASK0 = SDC_MASK0_DATA | SDC_MASK0_TXDATAERR;
01102 
01103     /* DMA Setup */
01104     mci_SetupEventWakeup();
01105     gpdma_transfer_to_mci(_eventDmaChannel, (uint32_t)buffer, blockNum*MMC_SECTOR_SIZE);
01106 
01107     /* set transfer information */
01108     mci_SetDataTransfer(blockNum, false, DATA_TIMER_VALUE_W);
01109 
01110     /* Wait for transfer done */
01111     if (mci_WaitForEvent() != 0) {
01112       Ret = SDC_RET_FAILED;
01113     }
01114 
01115     if ((blockNum > 1) || (mci_GetCardState() == SDMMC_RCV_ST)) {
01116       /* Send Stop transmission command */
01117       mci_StopTransmission(_sdCardInfo.rca);
01118     }
01119 
01120     /* Wait for card to enter tran state */
01121     while (mci_GetCardState() != SDMMC_TRAN_ST) {}
01122       
01123   } while (false);
01124 
01125   return Ret;
01126 }
01127 
01128 void MCIFileSystem::mci_SetClock(uint32_t freq) const
01129 {
01130   uint32_t PClk;
01131   uint32_t ClkValue = 0;
01132 
01133   PClk = PeripheralClock;
01134 
01135   ClkValue = (PClk + 2 * freq - 1) / (2 * freq);
01136   if (ClkValue > 0) {
01137     ClkValue -= 1;
01138   }
01139   uint32_t temp;
01140   temp = (LPC_MCI->CLOCK & (~SDC_CLOCK_CLKDIV_BITMASK));
01141   LPC_MCI->CLOCK = temp | (SDC_CLOCK_CLKDIV(ClkValue));
01142   mci_WriteDelay();
01143 }
01144 
01145 void MCIFileSystem::mci_ClockControl(ClockControl ctrlType, bool enable) const
01146 {
01147   if (enable) {
01148     LPC_MCI->CLOCK |= (1 << ctrlType);
01149   }
01150   else {
01151     LPC_MCI->CLOCK &= (~(1 << ctrlType));
01152   }
01153   mci_WriteDelay();
01154 }
01155 
01156 void MCIFileSystem::mci_PowerControl(power_ctrl_t powerMode, uint32_t flag) const
01157 {
01158   LPC_MCI->POWER = (powerMode & 0x3) | flag;
01159   mci_WriteDelay();
01160 }
01161 
01162 MCIFileSystem::ReturnCode MCIFileSystem::mci_ExecuteCmd(uint32_t Command, uint32_t Arg, response_t* pResp) const
01163 {
01164   ReturnCode Ret = SDC_RET_FAILED;
01165 
01166   /* Send Command to card */
01167   Ret = mci_SendCmd(Command, Arg, CMD_TIMEOUT);
01168   if (Ret != SDC_RET_OK) {
01169     return Ret;
01170   }
01171 
01172   /* Get response (if any) */
01173   if ((Command & SDC_COMMAND_RSP_BITMASK) != SDC_COMMAND_NO_RSP) {
01174 
01175     mci_GetResp(pResp);
01176 
01177     /* If the response is not R1, in the response field, the Expected Cmd data
01178             won't be the same as the CMD data in SendCmd(). Below four cmds have
01179             R2 or R3 response. We don't need to check if MCI_RESP_CMD is the same
01180             as the Expected or not. */
01181     if ((SDC_COMMAND_INDEX(Command) != MMC_SEND_OP_COND) &&
01182       (SDC_COMMAND_INDEX(Command) != SD_APP_OP_COND) &&
01183       (SDC_COMMAND_INDEX(Command) != MMC_ALL_SEND_CID) &&
01184       (SDC_COMMAND_INDEX(Command) != MMC_SEND_CSD) &&
01185       (pResp->CmdIndex != SDC_COMMAND_INDEX(Command))) {
01186       return SDC_RET_CMD_FAILED;
01187     }
01188   }
01189 
01190   return SDC_RET_OK;
01191 }
01192 
01193 MCIFileSystem::ReturnCode MCIFileSystem::mci_SendIfCond() const
01194 {
01195   ReturnCode Ret = SDC_RET_FAILED;
01196   response_t Response;
01197   uint32_t RetryCnt =  20;
01198 
01199   while (RetryCnt > 0) {
01200     Ret = mci_ExecuteCmd(SD_CMD8_SEND_IF_COND, (CMD8_VOLTAGESUPPLIED_27_36 | CMD8_CHECKPATTERN(
01201                               CMD8_DEF_PATTERN)), &Response);
01202     if (Ret == SDC_RET_OK) {
01203       if ((Response.Data[0] & CMDRESP_R7_VOLTAGE_ACCEPTED) &&
01204         (CMDRESP_R7_CHECK_PATTERN(Response.Data[0]) == CMD8_DEF_PATTERN)) {
01205         return SDC_RET_OK;
01206       }
01207       return SDC_RET_BAD_PARAMETERS;
01208     }
01209     RetryCnt--;
01210   }
01211   return Ret;
01212 }
01213 
01214 MCIFileSystem::ReturnCode MCIFileSystem::mci_SendOpCond(uint32_t *pOCR) const
01215 {
01216   ReturnCode Ret = SDC_RET_FAILED;
01217   response_t Response;
01218   uint32_t RetryCnt =  0x200;
01219 
01220   while (RetryCnt > 0) {
01221     Ret = mci_ExecuteCmd(SD_CMD1_SEND_OP_COND, SDC_OCR_27_36, &Response);
01222     if (Ret == SDC_RET_OK) {
01223       *pOCR = Response.Data[0];
01224       if (*pOCR & SDC_OCR_IDLE) {
01225         if ((Response.Data[0] & SDC_OCR_27_36) != SDC_OCR_27_36) {
01226           return SDC_RET_BAD_PARAMETERS;
01227         }
01228         return SDC_RET_OK;
01229       }
01230     }
01231     RetryCnt--;
01232   }
01233   return SDC_RET_FAILED;
01234 }
01235 
01236 MCIFileSystem::ReturnCode MCIFileSystem::mci_SendAppOpCond(uint16_t rca, bool hcs, uint32_t *pOcr, bool *pCCS) const
01237 {
01238   ReturnCode Ret = SDC_RET_FAILED;
01239   response_t Response;
01240   uint32_t Argument;
01241   uint32_t RetryCnt =  0x2000;  /* The host repeatedly issues ACMD41 for at least 1 second or
01242                          until the busy bit are set to 1 */
01243 
01244   Argument = ACMD41_OCR(*pOcr);
01245   if (hcs) {
01246     Argument |= ACMD41_HCS;
01247   }
01248 
01249   while (RetryCnt > 0) {
01250     Ret = mci_SendAppCmd(rca);
01251     if (Ret == SDC_RET_OK) {
01252       Ret = mci_ExecuteCmd(SD_ACMD41_SD_SEND_OP_COND, Argument, &Response);
01253       if (Ret == SDC_RET_OK) {
01254         if (Response.Data[0] & CMDRESP_R3_INIT_COMPLETE) {
01255           if (*pOcr == 0) {
01256             *pOcr = CMDRESP_R3_OCR_VAL(Response.Data[0]);
01257             return SDC_RET_OK;
01258           }
01259           if ((CMDRESP_R3_OCR_VAL(Response.Data[0]) & *pOcr) != *pOcr) {
01260             return SDC_RET_BAD_PARAMETERS;
01261           }
01262           *pCCS = (Response.Data[0] & CMDRESP_R3_HC_CCS) ? true : false;
01263           return SDC_RET_OK;
01264         }
01265       }
01266     }
01267     else {
01268       //If we abort here then some cards will go undetected, better to keep retrying
01269       //return Ret;
01270     }
01271     RetryCnt--;
01272   }
01273   return SDC_RET_FAILED;
01274 }
01275 
01276 MCIFileSystem::ReturnCode MCIFileSystem::mci_GetCID(uint32_t *pCID) const
01277 {
01278   ReturnCode Ret = SDC_RET_FAILED;
01279   response_t Response;
01280   uint32_t RetryCnt =  20;
01281 
01282   while (RetryCnt > 0) {
01283     Ret = mci_ExecuteCmd(SD_CMD2_ALL_SEND_CID, 0, &Response);
01284     if (Ret == SDC_RET_OK) {
01285       pCID[3] = Response.Data[0];
01286       pCID[2] = Response.Data[1];
01287       pCID[1] = Response.Data[2];
01288       pCID[0] = Response.Data[3];
01289       return SDC_RET_OK;
01290     }
01291     RetryCnt--;
01292   }
01293   return Ret;
01294 }
01295 
01296 MCIFileSystem::ReturnCode MCIFileSystem::mci_SetAddr(uint16_t addr) const
01297 {
01298   ReturnCode Ret = SDC_RET_FAILED;
01299   response_t Response;
01300   uint32_t RetryCnt =  20;
01301 
01302   while (RetryCnt > 0) {
01303     Ret = mci_ExecuteCmd(SD_CMD3_SET_RELATIVE_ADDR, CMD3_RCA(addr), &Response);
01304     if (Ret == SDC_RET_OK) {
01305       if (mci_CheckR1Response(Response.Data[0], &Ret)) {
01306         return Ret;
01307       }
01308     }
01309     RetryCnt--;
01310   }
01311   return Ret;
01312 }
01313 
01314 MCIFileSystem::ReturnCode MCIFileSystem::mci_GetAddr(uint16_t *pRCA) const
01315 {
01316   ReturnCode Ret = SDC_RET_FAILED;
01317   response_t Response;
01318   uint32_t RetryCnt =  20;
01319 
01320   *pRCA = 0;
01321   while (RetryCnt > 0) {
01322     Ret = mci_ExecuteCmd(SD_CMD3_SEND_RELATIVE_ADDR, 0, &Response);
01323     if (Ret == SDC_RET_OK) {
01324       if (!(CMDRESP_R6_CARD_STATUS(Response.Data[0]) & R1_READY_FOR_DATA)) {
01325         Ret = SDC_RET_NOT_READY;
01326       }
01327       else if (R1_CURRENT_STATE(CMDRESP_R6_CARD_STATUS(Response.Data[0])) != SDMMC_STBY_ST) {
01328         Ret = SDC_RET_ERR_STATE;
01329       }
01330       else {
01331         *pRCA = CMDRESP_R6_RCA_VAL(Response.Data[0]);
01332         return SDC_RET_OK;
01333       }
01334     }
01335     RetryCnt--;
01336   }
01337   return Ret;
01338 }
01339 
01340 MCIFileSystem::ReturnCode MCIFileSystem::mci_GetCSD(uint16_t rca, uint32_t *pCSD) const
01341 {
01342   ReturnCode Ret = SDC_RET_FAILED;
01343   response_t Response;
01344   uint32_t RetryCnt =  20;
01345 
01346   while (RetryCnt > 0) {
01347     Ret = mci_ExecuteCmd(SD_CMD9_SEND_CSD, CMD9_RCA(rca), &Response);
01348     if (Ret == SDC_RET_OK) {
01349       pCSD[3] = Response.Data[0];
01350       pCSD[2] = Response.Data[1];
01351       pCSD[1] = Response.Data[2];
01352       pCSD[0] = Response.Data[3];
01353       return Ret;
01354     }
01355     RetryCnt--;
01356   }
01357   return Ret;
01358 }
01359 
01360 MCIFileSystem::ReturnCode MCIFileSystem::mci_SelectCard(uint16_t addr) const
01361 {
01362   ReturnCode Ret = SDC_RET_FAILED;
01363   response_t Response;
01364   uint32_t RetryCnt =  20;
01365 
01366   while (RetryCnt > 0) {
01367     Ret = mci_ExecuteCmd(SD_CMD7_SELECT_CARD, CMD7_RCA(addr), &Response);
01368     if (Ret == SDC_RET_OK) {
01369       if (mci_CheckR1Response(Response.Data[0], &Ret)) {
01370         return Ret;
01371       }
01372     }
01373     RetryCnt--;
01374   }
01375   return Ret;
01376 }
01377 
01378 MCIFileSystem::ReturnCode MCIFileSystem::mci_GetStatus(uint16_t rca, uint32_t *pStatus) const
01379 {
01380   ReturnCode Ret = SDC_RET_FAILED;
01381   response_t Response;
01382   uint32_t RetryCnt =  20;
01383 
01384   *pStatus = (uint32_t) -1;
01385   while (RetryCnt > 0) {
01386     Ret = mci_ExecuteCmd(SD_CMD13_SEND_STATUS, CMD13_RCA(rca), &Response);
01387     if (Ret == SDC_RET_OK) {
01388       mci_CheckR1Response(Response.Data[0], &Ret);
01389       *pStatus = Response.Data[0];
01390       return Ret;
01391     }
01392     RetryCnt--;
01393   }
01394   return Ret;
01395 }
01396 
01397 void MCIFileSystem::mci_ProcessCSD()
01398 {
01399   int32_t CSize = 0;
01400   int32_t CSizeMult = 0;
01401   int32_t Mult = 0;
01402 
01403   /* compute block length based on CSD response */
01404   _sdCardInfo.block_len = 1 << mci_GetBits(80, 83, _sdCardInfo.csd);
01405 
01406   if ((_sdCardInfo.card_type & CARD_TYPE_HC) && (_sdCardInfo.card_type & CARD_TYPE_SD)) {
01407     /* See section 5.3.3 CSD Register (CSD Version 2.0) of SD2.0 spec  an explanation for the calculation of these values */
01408     CSize = mci_GetBits(48, 63, (uint32_t *) _sdCardInfo.csd) + 1;
01409     _sdCardInfo.blocknr = CSize << 10;  /* 512 byte blocks */
01410   }
01411   else {
01412     /* See section 5.3 of the 4.1 revision of the MMC specs for  an explanation for the calculation of these values */
01413     CSize = mci_GetBits(62, 73, (uint32_t *) _sdCardInfo.csd);
01414     CSizeMult = mci_GetBits(47, 49, (uint32_t *) _sdCardInfo.csd);
01415     Mult = 1 << (CSizeMult + 2);
01416     _sdCardInfo.blocknr = (CSize + 1) * Mult;
01417 
01418     /* adjust blocknr to 512/block */
01419     if (_sdCardInfo.block_len > MMC_SECTOR_SIZE) {
01420       _sdCardInfo.blocknr = _sdCardInfo.blocknr * (_sdCardInfo.block_len >> 9);
01421     }
01422   }
01423 
01424   _sdCardInfo.device_size = _sdCardInfo.blocknr << 9;  /* blocknr * 512 */
01425 }
01426 
01427 MCIFileSystem::ReturnCode MCIFileSystem::mci_SetBusWidth(uint16_t rca, uint8_t width) const
01428 {
01429   ReturnCode Ret = SDC_RET_FAILED;
01430   response_t Response;
01431   uint8_t RetryCnt =  0x20;
01432 
01433   while (RetryCnt > 0) {
01434     Ret = mci_SendAppCmd(rca);
01435     if (Ret == SDC_RET_OK) {
01436       Ret = mci_ExecuteCmd(SD_ACMD6_SET_BUS_WIDTH, ACMD6_BUS_WIDTH(width), &Response);
01437       if (Ret == SDC_RET_OK) {
01438         if (mci_CheckR1Response(Response.Data[0], &Ret)) {
01439           return Ret;
01440         }
01441       }
01442     }
01443     RetryCnt--;
01444   }
01445   return SDC_RET_FAILED;
01446 }
01447 
01448 MCIFileSystem::ReturnCode MCIFileSystem::mci_SetTranState(uint16_t rca) const
01449 {
01450   ReturnCode Ret = SDC_RET_OK;
01451   uint32_t status = 0;
01452   SDMMC_STATE_T state;
01453 
01454   /* get current state of the card */
01455   Ret = mci_GetStatus(rca, &status);
01456   if (Ret != SDC_RET_OK) {
01457     /* unable to get the card state. So return immediatly. */
01458     return Ret;
01459   }
01460 
01461   /* check card state in response */
01462   state = (SDMMC_STATE_T) R1_CURRENT_STATE(status);
01463   switch (state) {
01464   case SDMMC_STBY_ST:
01465     /* put card in 'Trans' state */
01466     Ret = mci_SelectCard(rca);
01467     if (Ret != SDC_RET_OK) {
01468       /* unable to put the card in Trans state. So return immediatly. */
01469       return Ret;
01470     }
01471     mci_GetStatus(rca, &status);
01472     if (((SDMMC_STATE_T) R1_CURRENT_STATE(status)) != SDMMC_TRAN_ST) {
01473       return SDC_RET_ERR_STATE;
01474     }
01475     break;
01476 
01477   case SDMMC_TRAN_ST:
01478     /*do nothing */
01479     break;
01480 
01481   default:
01482     /* card shouldn't be in other states so return */
01483     return SDC_RET_ERR_STATE;
01484   }
01485 
01486   return SDC_RET_OK;
01487 }
01488 
01489 MCIFileSystem::ReturnCode MCIFileSystem::mci_SetBlockLength(uint32_t rca, uint32_t block_len) const
01490 {
01491   ReturnCode Ret = SDC_RET_FAILED;
01492   response_t Response;
01493   uint8_t RetryCnt =  0x20;
01494 
01495   while (RetryCnt > 0) {
01496     Ret = mci_ExecuteCmd(SD_CMD16_SET_BLOCKLEN, block_len, &Response);
01497     if (Ret == SDC_RET_OK) {
01498       if (mci_CheckR1Response(Response.Data[0], &Ret)) {
01499         return Ret;
01500       }
01501     }
01502     RetryCnt--;
01503   }
01504   return SDC_RET_FAILED;
01505 }
01506 
01507 MCIFileSystem::ReturnCode MCIFileSystem::mci_SetCardParams() const
01508 {
01509   ReturnCode Ret;
01510 
01511   mci_SetClock(SDC_TRAN_CLOCK_RATE);
01512   if (_sdCardInfo.card_type & CARD_TYPE_SD) {
01513     mci_ClockControl(SDC_CLOCK_WIDEBUS_MODE, true);
01514     Ret = mci_SetBusWidth(_sdCardInfo.rca, ACMD6_BUS_WIDTH_4);
01515     if (Ret != SDC_RET_OK) {
01516       return Ret;
01517     }
01518   }
01519   else {
01520     mci_ClockControl(SDC_CLOCK_WIDEBUS_MODE, false);
01521   }
01522 
01523   /* set block length */
01524   Ret = mci_SetBlockLength(_sdCardInfo.rca, MMC_SECTOR_SIZE);
01525   return Ret;
01526 }
01527 
01528 bool MCIFileSystem::mci_CheckR1Response(uint32_t resp, ReturnCode* pCheckResult) const
01529 {
01530   bool Ret = true;
01531 
01532   if (!(resp & R1_READY_FOR_DATA)) {
01533     *pCheckResult = SDC_RET_NOT_READY;
01534     Ret = false;
01535   }
01536   else if (R1_STATUS(resp)) {
01537     *pCheckResult =  SDC_RET_FAILED;
01538   }
01539   else {
01540     *pCheckResult =  SDC_RET_OK;
01541   }
01542   return Ret;
01543 }
01544 
01545 void MCIFileSystem::mci_WriteDelay() const
01546 {
01547   wait_us(10);
01548 }
01549 
01550 MCIFileSystem::ReturnCode MCIFileSystem::mci_SendCmd(uint32_t Command, uint32_t Arg, uint32_t timeout) const
01551 {
01552   ReturnCode ret = SDC_RET_TIMEOUT;
01553   uint32_t Status;
01554 
01555   /* Set Command Info */
01556   mci_SetCommand(Command, Arg);
01557 
01558   while (timeout) {
01559 
01560     Status = LPC_MCI->STATUS;
01561 
01562     /* check if command was sent */
01563     if (((Command & SDC_COMMAND_RSP_BITMASK) == SDC_COMMAND_NO_RSP) && (Status & SDC_STATUS_CMDSENT)) {
01564       ret =  SDC_RET_OK;
01565       break;
01566     }
01567     /* check if response was received */
01568     if (Status & SDC_STATUS_CMDRESPEND) {
01569       ret = SDC_RET_OK;
01570       break;
01571     }
01572 
01573     /* check command sending status */
01574     if (Status & SDC_STATUS_CMDERR) {
01575       if (Status & SDC_STATUS_CMDCRCFAIL) {
01576         if ((SDC_COMMAND_INDEX(Command) == MMC_SEND_OP_COND) ||
01577             (SDC_COMMAND_INDEX(Command) == SD_APP_OP_COND) ||
01578             (SDC_COMMAND_INDEX(Command) == MMC_STOP_TRANSMISSION)) {
01579           ret = SDC_RET_OK;  /* ignore CRC error if it's a resp for SEND_OP_COND  or STOP_TRANSMISSION. */
01580           break;
01581         }
01582       }
01583       ret = SDC_RET_CMD_FAILED;
01584       break;
01585     }
01586 
01587     timeout--;
01588   }
01589 
01590   mci_ResetCommand();
01591 
01592   return ret;
01593 }
01594 
01595 MCIFileSystem::ReturnCode MCIFileSystem::mci_SendAppCmd(uint16_t rca) const
01596 {
01597   ReturnCode Ret = SDC_RET_FAILED;
01598   response_t Response;
01599   uint32_t RetryCnt =  20;
01600 
01601   while (RetryCnt > 0) {
01602     Ret = mci_ExecuteCmd(SD_CMD55_APP_CMD, CMD55_RCA(rca), &Response);
01603     if (Ret == SDC_RET_OK) {
01604       if (mci_CheckR1Response(Response.Data[0], &Ret)) {
01605         if (Ret != SDC_RET_OK) {
01606           return Ret;
01607         }
01608         if (Response.Data[0] & R1_APP_CMD) {
01609           return SDC_RET_OK;
01610         }
01611         else {
01612           Ret = SDC_RET_FAILED;
01613         }
01614       }
01615     }
01616     RetryCnt--;
01617   }
01618   return SDC_RET_FAILED;
01619 }
01620 
01621 void MCIFileSystem::mci_SetDataTransfer(uint16_t BlockNum, bool DirFromCard, uint32_t Timeout) const
01622 {
01623   uint32_t DataCtrl = 0;
01624   LPC_MCI->DATATMR = Timeout;
01625   LPC_MCI->DATALEN = BlockNum * 512;
01626 
01627   DataCtrl = SDC_DATACTRL_ENABLE;
01628   // DataCtrl mode=block, block size=512byte
01629   DataCtrl |= (0x9 << 4);
01630   if (DirFromCard) {
01631     DataCtrl |= (0x1 << 1);
01632   }
01633   DataCtrl |= SDC_DATACTRL_DMA_ENABLE;
01634   LPC_MCI->DATACTRL = DataCtrl;
01635   mci_WriteDelay();
01636 }
01637 
01638 void MCIFileSystem::mci_GetResp(response_t* pResp) const
01639 {
01640   pResp->CmdIndex = SDC_RESPCOMMAND_VAL(LPC_MCI->RESP_CMD);
01641   pResp->Data[0] = LPC_MCI->RESP0;
01642   if (CardStatusNumBytes == 4) {
01643     pResp->Data[1] = LPC_MCI->RESP1;
01644     pResp->Data[2] = LPC_MCI->RESP2;
01645     pResp->Data[3] = LPC_MCI->RESP3;
01646   }
01647 }
01648 
01649 uint32_t MCIFileSystem::mci_GetBits(int32_t start, int32_t end, uint32_t *data) const
01650 {
01651   uint32_t v;
01652   uint32_t i = end >> 5;
01653   uint32_t j = start & 0x1f;
01654 
01655   if (i == (start >> 5)) {
01656     v = (data[i] >> j);
01657   }
01658   else {
01659     v = ((data[i] << (32 - j)) | (data[start >> 5] >> j));
01660   }
01661 
01662   return v & ((1 << (end - start + 1)) - 1);
01663 }
01664 
01665 void MCIFileSystem::mci_SetCommand(uint32_t Cmd, uint32_t Arg) const
01666 {
01667   /* Clear status register */
01668   LPC_MCI->CLEAR = SDC_CLEAR_ALL;
01669 
01670   /* Set the argument first, finally command */
01671   LPC_MCI->ARGUMENT = Arg;
01672 
01673   /* Write command value, enable the command */
01674   LPC_MCI->COMMAND = Cmd | SDC_COMMAND_ENABLE;
01675 
01676   mci_WriteDelay();
01677 }
01678 
01679 void MCIFileSystem::mci_ResetCommand() const
01680 {
01681   LPC_MCI->CLEAR = SDC_CLEAR_ALL;
01682 
01683   LPC_MCI->ARGUMENT = 0xFFFFFFFF;
01684 
01685   LPC_MCI->COMMAND = 0;
01686 
01687   mci_WriteDelay();
01688 }
01689 
01690 int32_t MCIFileSystem::mci_IRQHandler(uint8_t *txBuf, uint32_t *txCnt, uint8_t *rxBuf, uint32_t *rxCnt)
01691 {
01692   uint32_t Status;
01693 
01694   Status = LPC_MCI->STATUS;
01695 
01696   if ( Status & SDC_STATUS_DATAERR) {
01697     LPC_MCI->CLEAR = SDC_STATUS_DATAERR;
01698     return -1;  /* Data transfer error */
01699   }
01700 
01701   if ( Status & SDC_STATUS_DATAEND) {
01702     LPC_MCI->CLEAR = SDC_STATUS_DATAEND;
01703     LPC_MCI->MASK0 = 0;
01704     return 0;
01705   }
01706 
01707   if ( Status & SDC_STATUS_DATABLOCKEND) {
01708     LPC_MCI->CLEAR = SDC_STATUS_DATABLOCKEND;
01709     return 1;
01710   }
01711 
01712   if (Status & SDC_STATUS_FIFO) {
01713     return mci_FIFOIRQHandler(txBuf, txCnt, rxBuf, rxCnt);
01714   }
01715 
01716   return 1;
01717 }
01718 
01719 int32_t MCIFileSystem::mci_FIFOIRQHandler(uint8_t *txBuf, uint32_t *txCnt, uint8_t *rxBuf, uint32_t *rxCnt)
01720 {
01721   uint32_t Status;
01722   Status = LPC_MCI->STATUS;
01723 
01724   if (txBuf) {
01725     if (Status & SDC_STATUS_TXFIFOHALFEMPTY) {
01726       if (*txCnt % 64) {
01727         mci_WriteFIFO((uint32_t *) &txBuf[*txCnt], false);
01728       }
01729       else {
01730         mci_WriteFIFO((uint32_t *) &txBuf[*txCnt], true);
01731       }
01732       *txCnt += 32;
01733     }
01734   }
01735 
01736   if (rxBuf) {
01737     if (Status & SDC_STATUS_RXFIFOHALFFULL) {
01738       if (*rxCnt % 64) {
01739         mci_ReadFIFO((uint32_t *) &rxBuf[*rxCnt], false);
01740       }
01741       else {
01742         mci_ReadFIFO((uint32_t *) &rxBuf[*rxCnt], true);
01743       }
01744       *rxCnt += 32;
01745     }
01746   }
01747 
01748   LPC_MCI->CLEAR = SDC_STATUS_FIFO;
01749 
01750   return 1;
01751 }
01752 
01753 void MCIFileSystem::mci_ReadFIFO(uint32_t *pDst, bool bFirstHalf) const
01754 {
01755   uint8_t start = 0, end = 7;
01756 
01757   if (!bFirstHalf) {
01758     start += 8;
01759     end += 8;
01760   }
01761   for (; start <= end; start++) {
01762     *pDst = LPC_MCI->FIFO[start];
01763     pDst++;
01764   }
01765 }
01766 
01767 void MCIFileSystem::mci_WriteFIFO(uint32_t *pSrc, bool bFirstHalf) const
01768 {
01769   uint8_t start = 0, end = 7;
01770   if (!bFirstHalf) {
01771     start += 8;
01772     end += 8;
01773   }
01774   for (; start <= end; start++) {
01775     LPC_MCI->FIFO[start] = *pSrc;
01776     pSrc++;
01777   }
01778 }
01779 
01780 void MCIFileSystem::mci_SetupEventWakeup()
01781 {
01782   /* Wait for IRQ - for an RTOS, you would pend on an event here with a IRQ based wakeup. */
01783 
01784   _eventReceived = false;
01785   _eventSuccess = false;
01786 }
01787 
01788 uint32_t MCIFileSystem::mci_WaitForEvent() const
01789 {
01790   /* Wait for the event (DMA or MCI interrupt) for a maximum of 2 seconds */
01791   uint32_t end = us_ticker_read() + 2*1000*1000;
01792   while ((us_ticker_read() < end) && (!_eventReceived))
01793   {
01794     // If the driver is having problems reading the card, adding a delay here
01795     // might help.
01796     //wait(0.01);
01797   }
01798   
01799   if (_eventReceived && _eventSuccess) {
01800     return 0;
01801   }
01802 
01803   return 1;
01804 }
01805 
01806 MCIFileSystem::ReturnCode MCIFileSystem::_readBlocks(uint32_t card_type, uint32_t startBlock, uint32_t blockNum) const
01807 {
01808   ReturnCode Ret = SDC_RET_FAILED;
01809   response_t Response;
01810   uint32_t Command, Argument;
01811   uint8_t RetryCnt =  0x20;
01812 
01813   if (blockNum == 1) {
01814     Command = SD_CMD17_READ_SINGLE_BLOCK;
01815   }
01816   else {
01817     Command = SD_CMD18_READ_MULTIPLE_BLOCK;
01818   }
01819 
01820   /* Select single or multiple read based on number of blocks */
01821   /* if high capacity card use block indexing */
01822   if (card_type & CARD_TYPE_HC) {
01823     Argument = startBlock;
01824   }
01825   else {  /*fix at 512 bytes*/
01826     Argument = startBlock << 9;
01827   }
01828 
01829   while (RetryCnt > 0) {
01830     Ret = mci_ExecuteCmd(Command, Argument, &Response);
01831     if (Ret == SDC_RET_OK) {
01832       if (mci_CheckR1Response(Response.Data[0], &Ret)) {
01833         return Ret;
01834       }
01835     }
01836     RetryCnt--;
01837   }
01838   return Ret;
01839 }
01840 
01841 MCIFileSystem::ReturnCode MCIFileSystem::_writeBlocks(uint32_t card_type, uint32_t startBlock, uint32_t blockNum) const
01842 {
01843   ReturnCode Ret = SDC_RET_FAILED;
01844   response_t Response;
01845   uint32_t Command, Argument;
01846   uint8_t RetryCnt =  0x20;
01847 
01848   if (blockNum == 1) {
01849     Command = SD_CMD24_WRITE_BLOCK;
01850   }
01851   else {
01852     Command = SD_CMD25_WRITE_MULTIPLE_BLOCK;
01853   }
01854 
01855   /* if high capacity card use block indexing */
01856   if (card_type & CARD_TYPE_HC) {
01857     Argument = startBlock;
01858   }
01859   else {  /*fix at 512 bytes*/
01860     Argument = startBlock << 9;
01861 
01862   }
01863 
01864   while (RetryCnt > 0) {
01865     Ret = mci_ExecuteCmd(Command, Argument, &Response);
01866     if (Ret == SDC_RET_OK) {
01867       if (mci_CheckR1Response(Response.Data[0], &Ret)) {
01868         return Ret;
01869       }
01870     }
01871     RetryCnt--;
01872   }
01873   return Ret;
01874 }