A library with drivers for different peripherals on the LPC4088 QuickStart Board or related add-on boards.

Dependencies:   FATFileSystem

Fork of EALib by EmbeddedArtists AB

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MCIFileSystem.cpp Source File

MCIFileSystem.cpp

00001 /*
00002  *  Copyright 2013 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 
00024 #include "diskio.h" //STA_* defines
00025 #include "gpdma.h"
00026 #include "us_ticker_api.h"
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       (0.100f)      /*!< inter-command acquire oper condition delay in seconds */
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 GPDMA controller */
00646     gpdma_init();
00647 
00648     /* Initialize SDC peripheral */
00649     LPC_SC->PCONP |= SYSCTL_CLOCK_SDC;
00650 
00651     /* Disable SD_CLK */
00652     mci_ClockControl(SDC_CLOCK_ENABLE, false);
00653 
00654     /* Power-off */
00655     mci_PowerControl(PowerOff, 0);
00656     mci_WriteDelay();
00657 
00658     /* Disable all interrupts */
00659     LPC_MCI->MASK0 = 0;
00660 
00661     /*Setting for timeout problem */
00662     LPC_MCI->DATATMR = 0x1FFFFFFF;
00663 
00664     LPC_MCI->COMMAND = 0;
00665     mci_WriteDelay();
00666 
00667     LPC_MCI->DATACTRL = 0;
00668     mci_WriteDelay();
00669 
00670     /* clear all pending interrupts */
00671     LPC_MCI->CLEAR = SDC_CLEAR_ALL;
00672 
00673     /* Power-up SDC Peripheral */
00674     mci_PowerControl(PowerUp, 0);
00675 
00676     /* delays for the supply output is stable*/
00677     for (uint32_t i = 0; i < 0x80000; i++ ) {}
00678 
00679     mci_SetClock(SDC_IDENT_CLOCK_RATE);
00680     mci_ClockControl(SDC_CLOCK_ENABLE, true);
00681 
00682     /* Power-on SDC Interface */
00683     mci_PowerControl(PowerOn, 0);
00684 
00685     NVIC_SetVector(MCI_IRQn, (uint32_t) mymciirq);
00686     NVIC_EnableIRQ(MCI_IRQn);
00687 
00688     NVIC_SetVector(DMA_IRQn, (uint32_t) mydmairq);
00689     NVIC_EnableIRQ(DMA_IRQn);
00690 }
00691 
00692 int MCIFileSystem::disk_initialize() {
00693 
00694     debug_if(MCI_DBG, "mcifs:disk_initialize(), _Stat = %#x\n", _Stat);
00695 
00696     if (!cardInserted()) {
00697       /* No card in the socket */
00698       _Stat = STA_NODISK | STA_NOINIT;
00699     }
00700 
00701     if (_Stat != STA_NOINIT) {
00702         return _Stat;          /* card is already enumerated */
00703     }
00704 
00705     //rtc_init();
00706 
00707     /* Initialize the Card Data Strucutre */
00708     memset(&_sdCardInfo, 0, sizeof(SDMMC_CARD_T));
00709 
00710     /* Reset */
00711     _Stat = STA_NOINIT;
00712 
00713     /* Enumerate the card once detected. Note this function may block for a little while. */
00714     int ret = mci_Acquire();
00715     if (ret != 1) {
00716       debug("Card Acquire failed... got %d, but expected 1\r\n", ret);
00717       return 1;//Stat;
00718     }
00719 
00720     _Stat &= ~STA_NOINIT;
00721     return _Stat;
00722 }
00723 
00724 int MCIFileSystem::disk_write(const uint8_t *buffer, uint64_t block_number) {
00725     debug_if(MCI_DBG, "mcifs:disk_write(%#x, %llu), _Stat = %#x\n", (uint32_t)buffer, block_number, _Stat);
00726     if (_Stat & STA_NOINIT) {
00727         // not ready
00728         return 1;
00729     }
00730     if (mci_WriteBlocks((void*)buffer, block_number, 1) == SDC_RET_OK) {
00731         return 0;
00732     }
00733 
00734     return 1;
00735 }
00736 
00737 int MCIFileSystem::disk_read(uint8_t *buffer, uint64_t block_number) {
00738     debug_if(MCI_DBG, "mcifs:disk_read(%#x, %llu), _Stat = %#x\n", (uint32_t)buffer, block_number, _Stat);
00739     if (_Stat & STA_NOINIT) {
00740         // not ready
00741         return _Stat;
00742     }
00743     if (mci_ReadBlocks(buffer, block_number, 1) == SDC_RET_OK) {
00744         return 0;
00745     }
00746 
00747     return 1;
00748 }
00749 
00750 int MCIFileSystem::disk_status()
00751 {
00752   debug_if(MCI_DBG, "mcifs:disk_status(), _Stat = %#x\n", _Stat);
00753   return _Stat;
00754 }
00755 
00756 int MCIFileSystem::disk_sync()
00757 {
00758   debug_if(MCI_DBG, "mcifs:disk_sync(), _Stat = %#x\n", _Stat);
00759   uint32_t end = us_ticker_read() + 50*1000; // 50ms
00760   while (us_ticker_read() < end)
00761   {
00762     if (mci_GetCardStatus() & R1_READY_FOR_DATA)
00763     {
00764       // card is ready
00765       return 0;
00766     }
00767   }
00768   // timeout while waiting for card to get ready
00769   return 1;
00770 }
00771 
00772 uint64_t MCIFileSystem::disk_sectors()
00773 {
00774     debug_if(MCI_DBG, "mcifs:disk_sectors(), _Stat = %#x, returning %llu\n", _Stat, _sdCardInfo.blocknr);
00775     return _sdCardInfo.blocknr;
00776 }
00777 
00778 void MCIFileSystem::mci_MCIIRQHandler()
00779 {
00780   int32_t Ret;
00781 
00782   Ret = mci_IRQHandler(NULL, 0, NULL, 0);
00783   if(Ret < 0) {
00784     _eventSuccess = false;
00785     _eventReceived = true;
00786   }
00787 }
00788 
00789 void MCIFileSystem::mci_DMAIRQHandler()
00790 {
00791   _eventSuccess = gpdma_interrupt(_eventDmaChannel);
00792   _eventReceived = true;
00793   NVIC_DisableIRQ(DMA_IRQn);
00794 }
00795 
00796 /******************************************************************************
00797  * Private Functions
00798  *****************************************************************************/
00799 
00800 bool MCIFileSystem::cardInserted() const
00801 {
00802     // If no card detect pin is given, then assume that a card is inserted.
00803     // If a pin is specified then use that to determing the presence of a card.
00804     return ((_cardDetect == NULL) || (_cardDetect->read() == 0));
00805 }
00806 
00807 
00808 
00809 int32_t MCIFileSystem::mci_Acquire()
00810 {
00811   int32_t Ret;
00812 
00813   /* Initialize card info */
00814   _sdCardInfo.speed = SDC_TRAN_CLOCK_RATE;
00815   _sdCardInfo.card_type = 0;
00816 
00817   /* During identification phase, the clock should be less than
00818      400Khz. Once we pass this phase, the normal clock can be set up
00819      to 25Mhz on SD card and 20Mhz on MMC card. */
00820   mci_SetClock(SDC_IDENT_CLOCK_RATE);
00821 
00822   /* Clear Open Drain output control for SD */
00823   mci_PowerControl(PowerOn, 0);
00824   
00825   /* Card Reset */
00826   Ret = mci_ExecuteCmd(SD_GO_IDLE_STATE, 0, NULL);
00827   if (Ret != 0) {
00828     return Ret;
00829   }
00830 
00831   wait(ACQUIRE_DELAY);
00832 
00833   /* Send interface operation condiftion */
00834   Ret = mci_SendIfCond();
00835   if (Ret == SDC_RET_BAD_PARAMETERS) {
00836     return Ret;    /* Non-compatible voltage range or check pattern is not correct */
00837 
00838   }
00839   /* Get Card Type */
00840   if (Ret == SDC_RET_OK) {/* Ver2.00 or later SD Memory Card*/
00841     bool CCS;
00842     uint32_t OCR = SDC_OCR_27_36;
00843     _sdCardInfo.card_type |= CARD_TYPE_SD;
00844     Ret = mci_SendAppOpCond(0, true, &OCR, &CCS);
00845     if (CCS) {  /* High Capacity or Extended Capacity SD Memory Card */
00846       _sdCardInfo.card_type |= CARD_TYPE_HC;
00847     }
00848   }
00849   else {  /*Ver2.00 or later SD Memory Card(voltage mismatch) or Ver1.X SD Memory Card
00850          or not SD Memory Card*/
00851     bool CCS;
00852     uint32_t OCR = SDC_OCR_27_36;
00853     Ret = mci_SendAppOpCond(0, false, &OCR, &CCS);
00854     if (Ret == SDC_RET_OK) {
00855       _sdCardInfo.card_type |= CARD_TYPE_SD;
00856     }
00857     else if (Ret == SDC_RET_BAD_PARAMETERS) {
00858       return Ret;
00859     }
00860     else {  /* MMC Card setup */
00861       uint32_t OCR;
00862       /* Enter to Open Drain mode */
00863       mci_PowerControl(PowerOn, SDC_PWR_OPENDRAIN);
00864       wait(ACQUIRE_DELAY);
00865       Ret = mci_SendOpCond(&OCR);
00866       if (Ret != SDC_RET_OK) {
00867         return Ret;
00868       }
00869 
00870     }
00871   }
00872 
00873   /* Read CID */
00874   mci_GetCID(_sdCardInfo.cid);
00875 
00876   /* RCA send, for SD get RCA */
00877   if (_sdCardInfo.card_type & CARD_TYPE_SD) {
00878     mci_GetAddr(&_sdCardInfo.rca);
00879   }
00880   else {
00881     _sdCardInfo.rca = 1;
00882     mci_SetAddr(_sdCardInfo.rca);
00883     mci_PowerControl(PowerOn, 0);  /* enter to push-pull mode */
00884   }
00885 
00886   /* Get CSD */
00887   mci_GetCSD(_sdCardInfo.rca, _sdCardInfo.csd);
00888 
00889   /* Compute card size, block size and no. of blocks  based on CSD response recived. */
00890   if (_sdCardInfo.cid[0]) {
00891     mci_ProcessCSD();
00892 
00893     if (mci_SetTranState(_sdCardInfo.rca) != SDC_RET_OK) {
00894       return 0;
00895     }
00896 
00897     if (mci_GetCardState() != SDMMC_TRAN_ST) {
00898       return 0;
00899     }
00900 
00901     if (mci_SetCardParams() != 0) {
00902       return 0;
00903     }
00904   }
00905 
00906   return (_sdCardInfo.cid[0]) ? 1 : 0;
00907 }
00908 
00909 uint32_t MCIFileSystem::mci_GetCardStatus() const
00910 {
00911   uint32_t Status;
00912   mci_GetStatus(_sdCardInfo.rca, &Status);
00913   return Status;
00914 }
00915 
00916 MCIFileSystem::CardState MCIFileSystem::mci_GetCardState() const
00917 {
00918   uint32_t Status;
00919   volatile int32_t Ret;
00920 
00921   /* get current state of the card */
00922   Ret = mci_GetStatus(_sdCardInfo.rca, &Status);
00923 
00924   /* check card state in response */
00925   return (CardState) R1_CURRENT_STATE(Status);
00926 }
00927 
00928 MCIFileSystem::ReturnCode MCIFileSystem::mci_StopTransmission(uint32_t rca) const
00929 {
00930   uint32_t Status;
00931   ReturnCode Ret = SDC_RET_FAILED;
00932   response_t Response;
00933   uint32_t RetryCnt =  20;
00934 
00935   Ret = mci_GetStatus(rca, &Status);
00936   if (Ret != SDC_RET_OK) {
00937     return SDC_RET_ERR_STATE;
00938   }
00939 
00940   if (R1_CURRENT_STATE(Status) == SDMMC_TRAN_ST) {
00941     return SDC_RET_OK;
00942   }
00943 
00944   if ((R1_CURRENT_STATE(Status) != SDMMC_DATA_ST) &&
00945     (R1_CURRENT_STATE(Status) != SDMMC_RCV_ST)) {
00946     return SDC_RET_ERR_STATE;
00947   }
00948 
00949   while (RetryCnt > 0) {
00950     Ret = mci_ExecuteCmd(SD_CMD12_STOP_TRANSMISSION, 0, &Response);
00951     if (Ret == SDC_RET_OK) {
00952       if (mci_CheckR1Response(Response.Data[0], &Ret)) {
00953         if (Ret != SDC_RET_OK) {
00954           return Ret;
00955         }
00956         Ret = mci_GetStatus(rca, &Status);
00957         if ((R1_CURRENT_STATE(Status) == SDMMC_TRAN_ST) || (R1_CURRENT_STATE(Status) == SDMMC_PRG_ST)) {
00958           return SDC_RET_OK;
00959         }
00960         return SDC_RET_ERR_STATE;
00961       }
00962     }
00963     RetryCnt--;
00964   }
00965   return Ret;
00966 }
00967 
00968 MCIFileSystem::ReturnCode MCIFileSystem::mci_ReadBlocks(void *buffer, int32_t startBlock, int32_t blockNum)
00969 {
00970   ReturnCode Ret = SDC_RET_FAILED;
00971   uint8_t dmaChannel;
00972   int32_t ByteNum = blockNum *  MMC_SECTOR_SIZE;
00973 
00974   do
00975   {
00976     /* if card is not acquired return immediately */
00977     if (( startBlock < 0) || ( (startBlock + blockNum) > _sdCardInfo.blocknr) ) {
00978       Ret = SDC_RET_NOT_READY;
00979       break;
00980     }
00981 
00982     /* Put to tran state */
00983     Ret = mci_SetTranState(_sdCardInfo.rca);
00984     if (Ret != SDC_RET_OK) {
00985       break;
00986     }
00987 
00988     LPC_MCI->MASK0 = SDC_MASK0_DATA | SDC_MASK0_RXDATAERR;
00989 
00990     /* DMA Setup */
00991     gpdma_getFreeChannel(&dmaChannel);
00992     gpdma_transfer_from_mci(dmaChannel, (uint32_t)buffer, ByteNum);
00993     mci_SetupEventWakeup(dmaChannel);
00994 
00995     /* set transfer information */
00996     mci_SetDataTransfer(blockNum, true, DATA_TIMER_VALUE_R);
00997 
00998     Ret = _readBlocks(_sdCardInfo.card_type, startBlock, blockNum);
00999     if (Ret == SDC_RET_OK) {
01000       /* Wait for transfer Finish */
01001       if (mci_WaitForEvent() != 0) {
01002         Ret = SDC_RET_FAILED;
01003       }
01004     } else {
01005       Ret = SDC_RET_FAILED;
01006     }
01007 
01008     gpdma_stop(dmaChannel);
01009 
01010     if ((blockNum > 1) || (mci_GetCardState() == SDMMC_DATA_ST)) {
01011       /* Send Stop transmission command */
01012       mci_StopTransmission(_sdCardInfo.rca);
01013     }
01014 
01015     /* Wait for card to enter tran state */
01016     while (mci_GetCardState() != SDMMC_TRAN_ST) {}
01017       
01018   } while(false);
01019 
01020   return Ret;
01021 }
01022 
01023 MCIFileSystem::ReturnCode MCIFileSystem::mci_WriteBlocks(void *buffer, int32_t startBlock, int32_t blockNum)
01024 {
01025   ReturnCode Ret = SDC_RET_FAILED;
01026   uint8_t dmaChannel;
01027   
01028   do
01029   {
01030     /* if card is not acquired return immediately */
01031     if (( startBlock < 0) || ( (startBlock + blockNum) > _sdCardInfo.blocknr) ) {
01032       Ret = SDC_RET_NOT_READY;
01033       break;
01034     }
01035 
01036     /* Put to tran state */
01037     Ret = mci_SetTranState(_sdCardInfo.rca);
01038     if (Ret != SDC_RET_OK) {
01039       break;
01040     }
01041 
01042     Ret = _writeBlocks(_sdCardInfo.card_type, startBlock, blockNum);
01043     if (Ret != SDC_RET_OK) {
01044       break;
01045     }
01046 
01047     /*Wait for card enter to rcv state*/
01048     while (mci_GetCardState() != SDMMC_RCV_ST) {}
01049 
01050     LPC_MCI->MASK0 = SDC_MASK0_DATA | SDC_MASK0_TXDATAERR;
01051 
01052     /* DMA Setup */
01053     gpdma_getFreeChannel(&dmaChannel);
01054     gpdma_transfer_to_mci(dmaChannel, (uint32_t)buffer, blockNum*MMC_SECTOR_SIZE);
01055     mci_SetupEventWakeup(dmaChannel);
01056 
01057     /* set transfer information */
01058     mci_SetDataTransfer(blockNum, false, DATA_TIMER_VALUE_W);
01059 
01060     /* Wait for transfer done */
01061     if (mci_WaitForEvent() != 0) {
01062       Ret = SDC_RET_FAILED;
01063     }
01064     gpdma_stop(dmaChannel);
01065 
01066     if ((blockNum > 1) || (mci_GetCardState() == SDMMC_RCV_ST)) {
01067       /* Send Stop transmission command */
01068       mci_StopTransmission(_sdCardInfo.rca);
01069     }
01070 
01071     /* Wait for card to enter tran state */
01072     while (mci_GetCardState() != SDMMC_TRAN_ST) {}
01073       
01074   } while (false);
01075 
01076   return Ret;
01077 }
01078 
01079 void MCIFileSystem::mci_SetClock(uint32_t freq) const
01080 {
01081   uint32_t PClk;
01082   uint32_t ClkValue = 0;
01083 
01084   PClk = PeripheralClock;
01085 
01086   ClkValue = (PClk + 2 * freq - 1) / (2 * freq);
01087   if (ClkValue > 0) {
01088     ClkValue -= 1;
01089   }
01090   uint32_t temp;
01091   temp = (LPC_MCI->CLOCK & (~SDC_CLOCK_CLKDIV_BITMASK));
01092   LPC_MCI->CLOCK = temp | (SDC_CLOCK_CLKDIV(ClkValue));
01093   mci_WriteDelay();
01094 }
01095 
01096 void MCIFileSystem::mci_ClockControl(ClockControl ctrlType, bool enable) const
01097 {
01098   if (enable) {
01099     LPC_MCI->CLOCK |= (1 << ctrlType);
01100   }
01101   else {
01102     LPC_MCI->CLOCK &= (~(1 << ctrlType));
01103   }
01104   mci_WriteDelay();
01105 }
01106 
01107 void MCIFileSystem::mci_PowerControl(power_ctrl_t powerMode, uint32_t flag) const
01108 {
01109   LPC_MCI->POWER = (powerMode & 0x3) | flag;
01110   mci_WriteDelay();
01111 }
01112 
01113 MCIFileSystem::ReturnCode MCIFileSystem::mci_ExecuteCmd(uint32_t Command, uint32_t Arg, response_t* pResp) const
01114 {
01115   ReturnCode Ret = SDC_RET_FAILED;
01116 
01117   /* Send Command to card */
01118   Ret = mci_SendCmd(Command, Arg, CMD_TIMEOUT);
01119   if (Ret != SDC_RET_OK) {
01120     return Ret;
01121   }
01122 
01123   /* Get response (if any) */
01124   if ((Command & SDC_COMMAND_RSP_BITMASK) != SDC_COMMAND_NO_RSP) {
01125 
01126     mci_GetResp(pResp);
01127 
01128     /* If the response is not R1, in the response field, the Expected Cmd data
01129             won't be the same as the CMD data in SendCmd(). Below four cmds have
01130             R2 or R3 response. We don't need to check if MCI_RESP_CMD is the same
01131             as the Expected or not. */
01132     if ((SDC_COMMAND_INDEX(Command) != MMC_SEND_OP_COND) &&
01133       (SDC_COMMAND_INDEX(Command) != SD_APP_OP_COND) &&
01134       (SDC_COMMAND_INDEX(Command) != MMC_ALL_SEND_CID) &&
01135       (SDC_COMMAND_INDEX(Command) != MMC_SEND_CSD) &&
01136       (pResp->CmdIndex != SDC_COMMAND_INDEX(Command))) {
01137       return SDC_RET_CMD_FAILED;
01138     }
01139   }
01140 
01141   return SDC_RET_OK;
01142 }
01143 
01144 MCIFileSystem::ReturnCode MCIFileSystem::mci_SendIfCond() const
01145 {
01146   ReturnCode Ret = SDC_RET_FAILED;
01147   response_t Response;
01148   uint32_t RetryCnt =  20;
01149 
01150   while (RetryCnt > 0) {
01151     Ret = mci_ExecuteCmd(SD_CMD8_SEND_IF_COND, (CMD8_VOLTAGESUPPLIED_27_36 | CMD8_CHECKPATTERN(
01152                               CMD8_DEF_PATTERN)), &Response);
01153     if (Ret == SDC_RET_OK) {
01154       if ((Response.Data[0] & CMDRESP_R7_VOLTAGE_ACCEPTED) &&
01155         (CMDRESP_R7_CHECK_PATTERN(Response.Data[0]) == CMD8_DEF_PATTERN)) {
01156         return SDC_RET_OK;
01157       }
01158       return SDC_RET_BAD_PARAMETERS;
01159     }
01160     RetryCnt--;
01161   }
01162   return Ret;
01163 }
01164 
01165 MCIFileSystem::ReturnCode MCIFileSystem::mci_SendOpCond(uint32_t *pOCR) const
01166 {
01167   ReturnCode Ret = SDC_RET_FAILED;
01168   response_t Response;
01169   uint32_t RetryCnt =  0x200;
01170 
01171   while (RetryCnt > 0) {
01172     Ret = mci_ExecuteCmd(SD_CMD1_SEND_OP_COND, SDC_OCR_27_36, &Response);
01173     if (Ret == SDC_RET_OK) {
01174       *pOCR = Response.Data[0];
01175       if (*pOCR & SDC_OCR_IDLE) {
01176         if ((Response.Data[0] & SDC_OCR_27_36) != SDC_OCR_27_36) {
01177           return SDC_RET_BAD_PARAMETERS;
01178         }
01179         return SDC_RET_OK;
01180       }
01181     }
01182     RetryCnt--;
01183   }
01184   return SDC_RET_FAILED;
01185 }
01186 
01187 MCIFileSystem::ReturnCode MCIFileSystem::mci_SendAppOpCond(uint16_t rca, bool hcs, uint32_t *pOcr, bool *pCCS) const
01188 {
01189   ReturnCode Ret = SDC_RET_FAILED;
01190   response_t Response;
01191   uint32_t Argument;
01192   uint32_t RetryCnt =  0x2000;  /* The host repeatedly issues ACMD41 for at least 1 second or
01193                          until the busy bit are set to 1 */
01194 
01195   Argument = ACMD41_OCR(*pOcr);
01196   if (hcs) {
01197     Argument |= ACMD41_HCS;
01198   }
01199 
01200   while (RetryCnt > 0) {
01201     Ret = mci_SendAppCmd(rca);
01202     if (Ret == SDC_RET_OK) {
01203       Ret = mci_ExecuteCmd(SD_ACMD41_SD_SEND_OP_COND, Argument, &Response);
01204       if (Ret == SDC_RET_OK) {
01205         if (Response.Data[0] & CMDRESP_R3_INIT_COMPLETE) {
01206           if (*pOcr == 0) {
01207             *pOcr = CMDRESP_R3_OCR_VAL(Response.Data[0]);
01208             return SDC_RET_OK;
01209           }
01210           if ((CMDRESP_R3_OCR_VAL(Response.Data[0]) & *pOcr) != *pOcr) {
01211             return SDC_RET_BAD_PARAMETERS;
01212           }
01213           *pCCS = (Response.Data[0] & CMDRESP_R3_HC_CCS) ? true : false;
01214           return SDC_RET_OK;
01215         }
01216       }
01217     }
01218     else {
01219       //If we abort here then some cards will go undetected, better to keep retrying
01220       //return Ret;
01221     }
01222     RetryCnt--;
01223   }
01224   return SDC_RET_FAILED;
01225 }
01226 
01227 MCIFileSystem::ReturnCode MCIFileSystem::mci_GetCID(uint32_t *pCID) const
01228 {
01229   ReturnCode Ret = SDC_RET_FAILED;
01230   response_t Response;
01231   uint32_t RetryCnt =  20;
01232 
01233   while (RetryCnt > 0) {
01234     Ret = mci_ExecuteCmd(SD_CMD2_ALL_SEND_CID, 0, &Response);
01235     if (Ret == SDC_RET_OK) {
01236       pCID[3] = Response.Data[0];
01237       pCID[2] = Response.Data[1];
01238       pCID[1] = Response.Data[2];
01239       pCID[0] = Response.Data[3];
01240       return SDC_RET_OK;
01241     }
01242     RetryCnt--;
01243   }
01244   return Ret;
01245 }
01246 
01247 MCIFileSystem::ReturnCode MCIFileSystem::mci_SetAddr(uint16_t addr) const
01248 {
01249   ReturnCode Ret = SDC_RET_FAILED;
01250   response_t Response;
01251   uint32_t RetryCnt =  20;
01252 
01253   while (RetryCnt > 0) {
01254     Ret = mci_ExecuteCmd(SD_CMD3_SET_RELATIVE_ADDR, CMD3_RCA(addr), &Response);
01255     if (Ret == SDC_RET_OK) {
01256       if (mci_CheckR1Response(Response.Data[0], &Ret)) {
01257         return Ret;
01258       }
01259     }
01260     RetryCnt--;
01261   }
01262   return Ret;
01263 }
01264 
01265 MCIFileSystem::ReturnCode MCIFileSystem::mci_GetAddr(uint16_t *pRCA) const
01266 {
01267   ReturnCode Ret = SDC_RET_FAILED;
01268   response_t Response;
01269   uint32_t RetryCnt =  20;
01270 
01271   *pRCA = 0;
01272   while (RetryCnt > 0) {
01273     Ret = mci_ExecuteCmd(SD_CMD3_SEND_RELATIVE_ADDR, 0, &Response);
01274     if (Ret == SDC_RET_OK) {
01275       if (!(CMDRESP_R6_CARD_STATUS(Response.Data[0]) & R1_READY_FOR_DATA)) {
01276         Ret = SDC_RET_NOT_READY;
01277       }
01278       else if (R1_CURRENT_STATE(CMDRESP_R6_CARD_STATUS(Response.Data[0])) != SDMMC_STBY_ST) {
01279         Ret = SDC_RET_ERR_STATE;
01280       }
01281       else {
01282         *pRCA = CMDRESP_R6_RCA_VAL(Response.Data[0]);
01283         return SDC_RET_OK;
01284       }
01285     }
01286     RetryCnt--;
01287   }
01288   return Ret;
01289 }
01290 
01291 MCIFileSystem::ReturnCode MCIFileSystem::mci_GetCSD(uint16_t rca, uint32_t *pCSD) const
01292 {
01293   ReturnCode Ret = SDC_RET_FAILED;
01294   response_t Response;
01295   uint32_t RetryCnt =  20;
01296 
01297   while (RetryCnt > 0) {
01298     Ret = mci_ExecuteCmd(SD_CMD9_SEND_CSD, CMD9_RCA(rca), &Response);
01299     if (Ret == SDC_RET_OK) {
01300       pCSD[3] = Response.Data[0];
01301       pCSD[2] = Response.Data[1];
01302       pCSD[1] = Response.Data[2];
01303       pCSD[0] = Response.Data[3];
01304       return Ret;
01305     }
01306     RetryCnt--;
01307   }
01308   return Ret;
01309 }
01310 
01311 MCIFileSystem::ReturnCode MCIFileSystem::mci_SelectCard(uint16_t addr) const
01312 {
01313   ReturnCode Ret = SDC_RET_FAILED;
01314   response_t Response;
01315   uint32_t RetryCnt =  20;
01316 
01317   while (RetryCnt > 0) {
01318     Ret = mci_ExecuteCmd(SD_CMD7_SELECT_CARD, CMD7_RCA(addr), &Response);
01319     if (Ret == SDC_RET_OK) {
01320       if (mci_CheckR1Response(Response.Data[0], &Ret)) {
01321         return Ret;
01322       }
01323     }
01324     RetryCnt--;
01325   }
01326   return Ret;
01327 }
01328 
01329 MCIFileSystem::ReturnCode MCIFileSystem::mci_GetStatus(uint16_t rca, uint32_t *pStatus) const
01330 {
01331   ReturnCode Ret = SDC_RET_FAILED;
01332   response_t Response;
01333   uint32_t RetryCnt =  20;
01334 
01335   *pStatus = (uint32_t) -1;
01336   while (RetryCnt > 0) {
01337     Ret = mci_ExecuteCmd(SD_CMD13_SEND_STATUS, CMD13_RCA(rca), &Response);
01338     if (Ret == SDC_RET_OK) {
01339       mci_CheckR1Response(Response.Data[0], &Ret);
01340       *pStatus = Response.Data[0];
01341       return Ret;
01342     }
01343     RetryCnt--;
01344   }
01345   return Ret;
01346 }
01347 
01348 void MCIFileSystem::mci_ProcessCSD()
01349 {
01350   int32_t CSize = 0;
01351   int32_t CSizeMult = 0;
01352   int32_t Mult = 0;
01353 
01354   /* compute block length based on CSD response */
01355   _sdCardInfo.block_len = 1 << mci_GetBits(80, 83, _sdCardInfo.csd);
01356 
01357   if ((_sdCardInfo.card_type & CARD_TYPE_HC) && (_sdCardInfo.card_type & CARD_TYPE_SD)) {
01358     /* See section 5.3.3 CSD Register (CSD Version 2.0) of SD2.0 spec  an explanation for the calculation of these values */
01359     CSize = mci_GetBits(48, 63, (uint32_t *) _sdCardInfo.csd) + 1;
01360     _sdCardInfo.blocknr = CSize << 10;  /* 512 byte blocks */
01361   }
01362   else {
01363     /* See section 5.3 of the 4.1 revision of the MMC specs for  an explanation for the calculation of these values */
01364     CSize = mci_GetBits(62, 73, (uint32_t *) _sdCardInfo.csd);
01365     CSizeMult = mci_GetBits(47, 49, (uint32_t *) _sdCardInfo.csd);
01366     Mult = 1 << (CSizeMult + 2);
01367     _sdCardInfo.blocknr = (CSize + 1) * Mult;
01368 
01369     /* adjust blocknr to 512/block */
01370     if (_sdCardInfo.block_len > MMC_SECTOR_SIZE) {
01371       _sdCardInfo.blocknr = _sdCardInfo.blocknr * (_sdCardInfo.block_len >> 9);
01372     }
01373   }
01374 
01375   _sdCardInfo.device_size = _sdCardInfo.blocknr << 9;  /* blocknr * 512 */
01376 }
01377 
01378 MCIFileSystem::ReturnCode MCIFileSystem::mci_SetBusWidth(uint16_t rca, uint8_t width) const
01379 {
01380   ReturnCode Ret = SDC_RET_FAILED;
01381   response_t Response;
01382   uint8_t RetryCnt =  0x20;
01383 
01384   while (RetryCnt > 0) {
01385     Ret = mci_SendAppCmd(rca);
01386     if (Ret == SDC_RET_OK) {
01387       Ret = mci_ExecuteCmd(SD_ACMD6_SET_BUS_WIDTH, ACMD6_BUS_WIDTH(width), &Response);
01388       if (Ret == SDC_RET_OK) {
01389         if (mci_CheckR1Response(Response.Data[0], &Ret)) {
01390           return Ret;
01391         }
01392       }
01393     }
01394     RetryCnt--;
01395   }
01396   return SDC_RET_FAILED;
01397 }
01398 
01399 MCIFileSystem::ReturnCode MCIFileSystem::mci_SetTranState(uint16_t rca) const
01400 {
01401   ReturnCode Ret = SDC_RET_OK;
01402   uint32_t status = 0;
01403   SDMMC_STATE_T state;
01404 
01405   /* get current state of the card */
01406   Ret = mci_GetStatus(rca, &status);
01407   if (Ret != SDC_RET_OK) {
01408     /* unable to get the card state. So return immediatly. */
01409     return Ret;
01410   }
01411 
01412   /* check card state in response */
01413   state = (SDMMC_STATE_T) R1_CURRENT_STATE(status);
01414   switch (state) {
01415   case SDMMC_STBY_ST:
01416     /* put card in 'Trans' state */
01417     Ret = mci_SelectCard(rca);
01418     if (Ret != SDC_RET_OK) {
01419       /* unable to put the card in Trans state. So return immediatly. */
01420       return Ret;
01421     }
01422     mci_GetStatus(rca, &status);
01423     if (((SDMMC_STATE_T) R1_CURRENT_STATE(status)) != SDMMC_TRAN_ST) {
01424       return SDC_RET_ERR_STATE;
01425     }
01426     break;
01427 
01428   case SDMMC_TRAN_ST:
01429     /*do nothing */
01430     break;
01431 
01432   default:
01433     /* card shouldn't be in other states so return */
01434     return SDC_RET_ERR_STATE;
01435   }
01436 
01437   return SDC_RET_OK;
01438 }
01439 
01440 MCIFileSystem::ReturnCode MCIFileSystem::mci_SetBlockLength(uint32_t rca, uint32_t block_len) const
01441 {
01442   ReturnCode Ret = SDC_RET_FAILED;
01443   response_t Response;
01444   uint8_t RetryCnt =  0x20;
01445 
01446   while (RetryCnt > 0) {
01447     Ret = mci_ExecuteCmd(SD_CMD16_SET_BLOCKLEN, block_len, &Response);
01448     if (Ret == SDC_RET_OK) {
01449       if (mci_CheckR1Response(Response.Data[0], &Ret)) {
01450         return Ret;
01451       }
01452     }
01453     RetryCnt--;
01454   }
01455   return SDC_RET_FAILED;
01456 }
01457 
01458 MCIFileSystem::ReturnCode MCIFileSystem::mci_SetCardParams() const
01459 {
01460   ReturnCode Ret;
01461 
01462   mci_SetClock(SDC_TRAN_CLOCK_RATE);
01463   if (_sdCardInfo.card_type & CARD_TYPE_SD) {
01464     mci_ClockControl(SDC_CLOCK_WIDEBUS_MODE, true);
01465     Ret = mci_SetBusWidth(_sdCardInfo.rca, ACMD6_BUS_WIDTH_4);
01466     if (Ret != SDC_RET_OK) {
01467       return Ret;
01468     }
01469   }
01470   else {
01471     mci_ClockControl(SDC_CLOCK_WIDEBUS_MODE, false);
01472   }
01473 
01474   /* set block length */
01475   Ret = mci_SetBlockLength(_sdCardInfo.rca, MMC_SECTOR_SIZE);
01476   return Ret;
01477 }
01478 
01479 bool MCIFileSystem::mci_CheckR1Response(uint32_t resp, ReturnCode* pCheckResult) const
01480 {
01481   bool Ret = true;
01482 
01483   if (!(resp & R1_READY_FOR_DATA)) {
01484     *pCheckResult = SDC_RET_NOT_READY;
01485     Ret = false;
01486   }
01487   else if (R1_STATUS(resp)) {
01488     *pCheckResult =  SDC_RET_FAILED;
01489   }
01490   else {
01491     *pCheckResult =  SDC_RET_OK;
01492   }
01493   return Ret;
01494 }
01495 
01496 void MCIFileSystem::mci_WriteDelay() const
01497 {
01498 //  volatile uint8_t i;
01499 //  for ( i = 0; i < 0x10; i++ ) {  /* delay 3MCLK + 2PCLK  */
01500 //  }
01501   wait(0.00001f); /* delay 10 us */
01502 }
01503 
01504 MCIFileSystem::ReturnCode MCIFileSystem::mci_SendCmd(uint32_t Command, uint32_t Arg, uint32_t timeout) const
01505 {
01506   ReturnCode ret = SDC_RET_TIMEOUT;
01507   uint32_t Status;
01508 
01509   /* Set Command Info */
01510   mci_SetCommand(Command, Arg);
01511 
01512   while (timeout) {
01513 
01514     Status = LPC_MCI->STATUS;
01515 
01516     /* check if command was sent */
01517     if (((Command & SDC_COMMAND_RSP_BITMASK) == SDC_COMMAND_NO_RSP) && (Status & SDC_STATUS_CMDSENT)) {
01518       ret =  SDC_RET_OK;
01519       break;
01520     }
01521     /* check if response was received */
01522     if (Status & SDC_STATUS_CMDRESPEND) {
01523       ret = SDC_RET_OK;
01524       break;
01525     }
01526 
01527     /* check command sending status */
01528     if (Status & SDC_STATUS_CMDERR) {
01529       if (Status & SDC_STATUS_CMDCRCFAIL) {
01530         if ((SDC_COMMAND_INDEX(Command) == MMC_SEND_OP_COND) ||
01531             (SDC_COMMAND_INDEX(Command) == SD_APP_OP_COND) ||
01532             (SDC_COMMAND_INDEX(Command) == MMC_STOP_TRANSMISSION)) {
01533           ret = SDC_RET_OK;  /* ignore CRC error if it's a resp for SEND_OP_COND  or STOP_TRANSMISSION. */
01534           break;
01535         }
01536       }
01537       ret = SDC_RET_CMD_FAILED;
01538       break;
01539     }
01540 
01541     timeout--;
01542   }
01543 
01544   mci_ResetCommand();
01545 
01546   return ret;
01547 }
01548 
01549 MCIFileSystem::ReturnCode MCIFileSystem::mci_SendAppCmd(uint16_t rca) const
01550 {
01551   ReturnCode Ret = SDC_RET_FAILED;
01552   response_t Response;
01553   uint32_t RetryCnt =  20;
01554 
01555   while (RetryCnt > 0) {
01556     Ret = mci_ExecuteCmd(SD_CMD55_APP_CMD, CMD55_RCA(rca), &Response);
01557     if (Ret == SDC_RET_OK) {
01558       if (mci_CheckR1Response(Response.Data[0], &Ret)) {
01559         if (Ret != SDC_RET_OK) {
01560           return Ret;
01561         }
01562         if (Response.Data[0] & R1_APP_CMD) {
01563           return SDC_RET_OK;
01564         }
01565         else {
01566           Ret = SDC_RET_FAILED;
01567         }
01568       }
01569     }
01570     RetryCnt--;
01571   }
01572   return SDC_RET_FAILED;
01573 }
01574 
01575 void MCIFileSystem::mci_SetDataTransfer(uint16_t BlockNum, bool DirFromCard, uint32_t Timeout) const
01576 {
01577   uint32_t DataCtrl = 0;
01578   LPC_MCI->DATATMR = Timeout;
01579   LPC_MCI->DATALEN = BlockNum * 512;
01580 
01581   DataCtrl = SDC_DATACTRL_ENABLE;
01582   // DataCtrl mode=block, block size=512byte
01583   DataCtrl |= (0x9 << 4);
01584   if (DirFromCard) {
01585     DataCtrl |= (0x1 << 1);
01586   }
01587   DataCtrl |= SDC_DATACTRL_DMA_ENABLE;
01588   LPC_MCI->DATACTRL = DataCtrl;
01589   mci_WriteDelay();
01590 }
01591 
01592 void MCIFileSystem::mci_GetResp(response_t* pResp) const
01593 {
01594   pResp->CmdIndex = SDC_RESPCOMMAND_VAL(LPC_MCI->RESP_CMD);
01595   pResp->Data[0] = LPC_MCI->RESP0;
01596   if (CardStatusNumBytes == 4) {
01597     pResp->Data[1] = LPC_MCI->RESP1;
01598     pResp->Data[2] = LPC_MCI->RESP2;
01599     pResp->Data[3] = LPC_MCI->RESP3;
01600   }
01601 }
01602 
01603 uint32_t MCIFileSystem::mci_GetBits(int32_t start, int32_t end, uint32_t *data) const
01604 {
01605   uint32_t v;
01606   uint32_t i = end >> 5;
01607   uint32_t j = start & 0x1f;
01608 
01609   if (i == (start >> 5)) {
01610     v = (data[i] >> j);
01611   }
01612   else {
01613     v = ((data[i] << (32 - j)) | (data[start >> 5] >> j));
01614   }
01615 
01616   return v & ((1 << (end - start + 1)) - 1);
01617 }
01618 
01619 void MCIFileSystem::mci_SetCommand(uint32_t Cmd, uint32_t Arg) const
01620 {
01621   /* Clear status register */
01622   LPC_MCI->CLEAR = SDC_CLEAR_ALL;
01623 
01624   /* Set the argument first, finally command */
01625   LPC_MCI->ARGUMENT = Arg;
01626 
01627   /* Write command value, enable the command */
01628   LPC_MCI->COMMAND = Cmd | SDC_COMMAND_ENABLE;
01629 
01630   mci_WriteDelay();
01631 }
01632 
01633 void MCIFileSystem::mci_ResetCommand() const
01634 {
01635   LPC_MCI->CLEAR = SDC_CLEAR_ALL;
01636 
01637   LPC_MCI->ARGUMENT = 0xFFFFFFFF;
01638 
01639   LPC_MCI->COMMAND = 0;
01640 
01641   mci_WriteDelay();
01642 }
01643 
01644 int32_t MCIFileSystem::mci_IRQHandler(uint8_t *txBuf, uint32_t *txCnt, uint8_t *rxBuf, uint32_t *rxCnt)
01645 {
01646   uint32_t Status;
01647 
01648   Status = LPC_MCI->STATUS;
01649 
01650   if ( Status & SDC_STATUS_DATAERR) {
01651     LPC_MCI->CLEAR = SDC_STATUS_DATAERR;
01652     return -1;  /* Data transfer error */
01653   }
01654 
01655   if ( Status & SDC_STATUS_DATAEND) {
01656     LPC_MCI->CLEAR = SDC_STATUS_DATAEND;
01657     LPC_MCI->MASK0 = 0;
01658     return 0;
01659   }
01660 
01661   if ( Status & SDC_STATUS_DATABLOCKEND) {
01662     LPC_MCI->CLEAR = SDC_STATUS_DATABLOCKEND;
01663     return 1;
01664   }
01665 
01666   if (Status & SDC_STATUS_FIFO) {
01667     return mci_FIFOIRQHandler(txBuf, txCnt, rxBuf, rxCnt);
01668   }
01669 
01670   return 1;
01671 }
01672 
01673 int32_t MCIFileSystem::mci_FIFOIRQHandler(uint8_t *txBuf, uint32_t *txCnt, uint8_t *rxBuf, uint32_t *rxCnt)
01674 {
01675   uint32_t Status;
01676   Status = LPC_MCI->STATUS;
01677 
01678   if (txBuf) {
01679     if (Status & SDC_STATUS_TXFIFOHALFEMPTY) {
01680       if (*txCnt % 64) {
01681         mci_WriteFIFO((uint32_t *) &txBuf[*txCnt], false);
01682       }
01683       else {
01684         mci_WriteFIFO((uint32_t *) &txBuf[*txCnt], true);
01685       }
01686       *txCnt += 32;
01687     }
01688   }
01689 
01690   if (rxBuf) {
01691     if (Status & SDC_STATUS_RXFIFOHALFFULL) {
01692       if (*rxCnt % 64) {
01693         mci_ReadFIFO((uint32_t *) &rxBuf[*rxCnt], false);
01694       }
01695       else {
01696         mci_ReadFIFO((uint32_t *) &rxBuf[*rxCnt], true);
01697       }
01698       *rxCnt += 32;
01699     }
01700   }
01701 
01702   LPC_MCI->CLEAR = SDC_STATUS_FIFO;
01703 
01704   return 1;
01705 }
01706 
01707 void MCIFileSystem::mci_ReadFIFO(uint32_t *pDst, bool bFirstHalf) const
01708 {
01709   uint8_t start = 0, end = 7;
01710 
01711   if (!bFirstHalf) {
01712     start += 8;
01713     end += 8;
01714   }
01715   for (; start <= end; start++) {
01716     *pDst = LPC_MCI->FIFO[start];
01717     pDst++;
01718   }
01719 }
01720 
01721 void MCIFileSystem::mci_WriteFIFO(uint32_t *pSrc, bool bFirstHalf) const
01722 {
01723   uint8_t start = 0, end = 7;
01724   if (!bFirstHalf) {
01725     start += 8;
01726     end += 8;
01727   }
01728   for (; start <= end; start++) {
01729     LPC_MCI->FIFO[start] = *pSrc;
01730     pSrc++;
01731   }
01732 }
01733 
01734 void MCIFileSystem::mci_SetupEventWakeup(uint8_t dmaChannel)
01735 {
01736   /* Wait for IRQ - for an RTOS, you would pend on an event here with a IRQ based wakeup. */
01737   NVIC_ClearPendingIRQ(DMA_IRQn);
01738 
01739   _eventDmaChannel = dmaChannel;
01740   _eventReceived = false;
01741   _eventSuccess = false;
01742 
01743   NVIC_EnableIRQ(DMA_IRQn);
01744 }
01745 
01746 uint32_t MCIFileSystem::mci_WaitForEvent() const
01747 {
01748   /* Wait for the event (DMA or MCI interrupt) for a maximum of 2 seconds */
01749   uint32_t end = us_ticker_read() + 2*1000*1000;
01750   while ((us_ticker_read() < end) && (!_eventReceived))
01751   {
01752     // If the driver is having problems reading the card, adding a delay here
01753     // might help.
01754     //wait(0.01);
01755   }
01756   
01757   if (_eventReceived && _eventSuccess) {
01758     return 0;
01759   }
01760 
01761   return 1;
01762 }
01763 
01764 MCIFileSystem::ReturnCode MCIFileSystem::_readBlocks(uint32_t card_type, uint32_t startBlock, uint32_t blockNum) const
01765 {
01766   ReturnCode Ret = SDC_RET_FAILED;
01767   response_t Response;
01768   uint32_t Command, Argument;
01769   uint8_t RetryCnt =  0x20;
01770 
01771   if (blockNum == 1) {
01772     Command = SD_CMD17_READ_SINGLE_BLOCK;
01773   }
01774   else {
01775     Command = SD_CMD18_READ_MULTIPLE_BLOCK;
01776   }
01777 
01778   /* Select single or multiple read based on number of blocks */
01779   /* if high capacity card use block indexing */
01780   if (card_type & CARD_TYPE_HC) {
01781     Argument = startBlock;
01782   }
01783   else {  /*fix at 512 bytes*/
01784     Argument = startBlock << 9;
01785   }
01786 
01787   while (RetryCnt > 0) {
01788     Ret = mci_ExecuteCmd(Command, Argument, &Response);
01789     if (Ret == SDC_RET_OK) {
01790       if (mci_CheckR1Response(Response.Data[0], &Ret)) {
01791         return Ret;
01792       }
01793     }
01794     RetryCnt--;
01795   }
01796   return Ret;
01797 }
01798 
01799 MCIFileSystem::ReturnCode MCIFileSystem::_writeBlocks(uint32_t card_type, uint32_t startBlock, uint32_t blockNum) const
01800 {
01801   ReturnCode Ret = SDC_RET_FAILED;
01802   response_t Response;
01803   uint32_t Command, Argument;
01804   uint8_t RetryCnt =  0x20;
01805 
01806   if (blockNum == 1) {
01807     Command = SD_CMD24_WRITE_BLOCK;
01808   }
01809   else {
01810     Command = SD_CMD25_WRITE_MULTIPLE_BLOCK;
01811   }
01812 
01813   /* if high capacity card use block indexing */
01814   if (card_type & CARD_TYPE_HC) {
01815     Argument = startBlock;
01816   }
01817   else {  /*fix at 512 bytes*/
01818     Argument = startBlock << 9;
01819 
01820   }
01821 
01822   while (RetryCnt > 0) {
01823     Ret = mci_ExecuteCmd(Command, Argument, &Response);
01824     if (Ret == SDC_RET_OK) {
01825       if (mci_CheckR1Response(Response.Data[0], &Ret)) {
01826         return Ret;
01827       }
01828     }
01829     RetryCnt--;
01830   }
01831   return Ret;
01832 }
01833