Subdirectory provided by Embedded Artists

Dependencies:   DM_FATFileSystem DM_HttpServer DM_USBHost EthernetInterface USBDevice mbed-rpc mbed-rtos mbed-src

Dependents:   lpc4088_displaymodule_hello_world_Sept_2018

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