Update version of EALib.

Dependencies:   FATFileSystem

Fork of EALib by IONX

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 =
00923   mci_GetStatus(_sdCardInfo.rca, &Status);
00924 
00925   /* check card state in response */
00926   return (CardState) R1_CURRENT_STATE(Status);
00927 }
00928 
00929 MCIFileSystem::ReturnCode MCIFileSystem::mci_StopTransmission(uint32_t rca) const
00930 {
00931   uint32_t Status;
00932   ReturnCode Ret = SDC_RET_FAILED;
00933   response_t Response;
00934   uint32_t RetryCnt =  20;
00935 
00936   Ret = mci_GetStatus(rca, &Status);
00937   if (Ret != SDC_RET_OK) {
00938     return SDC_RET_ERR_STATE;
00939   }
00940 
00941   if (R1_CURRENT_STATE(Status) == SDMMC_TRAN_ST) {
00942     return SDC_RET_OK;
00943   }
00944 
00945   if ((R1_CURRENT_STATE(Status) != SDMMC_DATA_ST) &&
00946     (R1_CURRENT_STATE(Status) != SDMMC_RCV_ST)) {
00947     return SDC_RET_ERR_STATE;
00948   }
00949 
00950   while (RetryCnt > 0) {
00951     Ret = mci_ExecuteCmd(SD_CMD12_STOP_TRANSMISSION, 0, &Response);
00952     if (Ret == SDC_RET_OK) {
00953       if (mci_CheckR1Response(Response.Data[0], &Ret)) {
00954         if (Ret != SDC_RET_OK) {
00955           return Ret;
00956         }
00957         Ret = mci_GetStatus(rca, &Status);
00958         if ((R1_CURRENT_STATE(Status) == SDMMC_TRAN_ST) || (R1_CURRENT_STATE(Status) == SDMMC_PRG_ST)) {
00959           return SDC_RET_OK;
00960         }
00961         return SDC_RET_ERR_STATE;
00962       }
00963     }
00964     RetryCnt--;
00965   }
00966   return Ret;
00967 }
00968 
00969 MCIFileSystem::ReturnCode MCIFileSystem::mci_ReadBlocks(void *buffer, int32_t startBlock, uint32_t blockNum)
00970 {
00971   ReturnCode Ret = SDC_RET_FAILED;
00972   uint8_t dmaChannel;
00973   int32_t ByteNum = blockNum *  MMC_SECTOR_SIZE;
00974 
00975   do
00976   {
00977     /* if card is not acquired return immediately */
00978     if (( startBlock < 0) || ( (startBlock + blockNum) > _sdCardInfo.blocknr) ) {
00979       Ret = SDC_RET_NOT_READY;
00980       break;
00981     }
00982 
00983     /* Put to tran state */
00984     Ret = mci_SetTranState(_sdCardInfo.rca);
00985     if (Ret != SDC_RET_OK) {
00986       break;
00987     }
00988 
00989     LPC_MCI->MASK0 = SDC_MASK0_DATA | SDC_MASK0_RXDATAERR;
00990 
00991     /* DMA Setup */
00992     gpdma_getFreeChannel(&dmaChannel);
00993     gpdma_transfer_from_mci(dmaChannel, (uint32_t)buffer, ByteNum);
00994     mci_SetupEventWakeup(dmaChannel);
00995 
00996     /* set transfer information */
00997     mci_SetDataTransfer(blockNum, true, DATA_TIMER_VALUE_R);
00998 
00999     Ret = _readBlocks(_sdCardInfo.card_type, startBlock, blockNum);
01000     if (Ret == SDC_RET_OK) {
01001       /* Wait for transfer Finish */
01002       if (mci_WaitForEvent() != 0) {
01003         Ret = SDC_RET_FAILED;
01004       }
01005     } else {
01006       Ret = SDC_RET_FAILED;
01007     }
01008 
01009     gpdma_stop(dmaChannel);
01010 
01011     if ((blockNum > 1) || (mci_GetCardState() == SDMMC_DATA_ST)) {
01012       /* Send Stop transmission command */
01013       mci_StopTransmission(_sdCardInfo.rca);
01014     }
01015 
01016     /* Wait for card to enter tran state */
01017     while (mci_GetCardState() != SDMMC_TRAN_ST) {}
01018       
01019   } while(false);
01020 
01021   return Ret;
01022 }
01023 
01024 MCIFileSystem::ReturnCode MCIFileSystem::mci_WriteBlocks(void *buffer, int32_t startBlock, uint32_t blockNum)
01025 {
01026   ReturnCode Ret = SDC_RET_FAILED;
01027   uint8_t dmaChannel;
01028   
01029   do
01030   {
01031     /* if card is not acquired return immediately */
01032     if (( startBlock < 0) || ( (startBlock + blockNum) > _sdCardInfo.blocknr) ) {
01033       Ret = SDC_RET_NOT_READY;
01034       break;
01035     }
01036 
01037     /* Put to tran state */
01038     Ret = mci_SetTranState(_sdCardInfo.rca);
01039     if (Ret != SDC_RET_OK) {
01040       break;
01041     }
01042 
01043     Ret = _writeBlocks(_sdCardInfo.card_type, startBlock, blockNum);
01044     if (Ret != SDC_RET_OK) {
01045       break;
01046     }
01047 
01048     /*Wait for card enter to rcv state*/
01049     while (mci_GetCardState() != SDMMC_RCV_ST) {}
01050 
01051     LPC_MCI->MASK0 = SDC_MASK0_DATA | SDC_MASK0_TXDATAERR;
01052 
01053     /* DMA Setup */
01054     gpdma_getFreeChannel(&dmaChannel);
01055     gpdma_transfer_to_mci(dmaChannel, (uint32_t)buffer, blockNum*MMC_SECTOR_SIZE);
01056     mci_SetupEventWakeup(dmaChannel);
01057 
01058     /* set transfer information */
01059     mci_SetDataTransfer(blockNum, false, DATA_TIMER_VALUE_W);
01060 
01061     /* Wait for transfer done */
01062     if (mci_WaitForEvent() != 0) {
01063       Ret = SDC_RET_FAILED;
01064     }
01065     gpdma_stop(dmaChannel);
01066 
01067     if ((blockNum > 1) || (mci_GetCardState() == SDMMC_RCV_ST)) {
01068       /* Send Stop transmission command */
01069       mci_StopTransmission(_sdCardInfo.rca);
01070     }
01071 
01072     /* Wait for card to enter tran state */
01073     while (mci_GetCardState() != SDMMC_TRAN_ST) {}
01074       
01075   } while (false);
01076 
01077   return Ret;
01078 }
01079 
01080 void MCIFileSystem::mci_SetClock(uint32_t freq) const
01081 {
01082   uint32_t PClk;
01083   uint32_t ClkValue = 0;
01084 
01085   PClk = PeripheralClock;
01086 
01087   ClkValue = (PClk + 2 * freq - 1) / (2 * freq);
01088   if (ClkValue > 0) {
01089     ClkValue -= 1;
01090   }
01091   uint32_t temp;
01092   temp = (LPC_MCI->CLOCK & (~SDC_CLOCK_CLKDIV_BITMASK));
01093   LPC_MCI->CLOCK = temp | (SDC_CLOCK_CLKDIV(ClkValue));
01094   mci_WriteDelay();
01095 }
01096 
01097 void MCIFileSystem::mci_ClockControl(ClockControl ctrlType, bool enable) const
01098 {
01099   if (enable) {
01100     LPC_MCI->CLOCK |= (1 << ctrlType);
01101   }
01102   else {
01103     LPC_MCI->CLOCK &= (~(1 << ctrlType));
01104   }
01105   mci_WriteDelay();
01106 }
01107 
01108 void MCIFileSystem::mci_PowerControl(power_ctrl_t powerMode, uint32_t flag) const
01109 {
01110   LPC_MCI->POWER = (powerMode & 0x3) | flag;
01111   mci_WriteDelay();
01112 }
01113 
01114 MCIFileSystem::ReturnCode MCIFileSystem::mci_ExecuteCmd(uint32_t Command, uint32_t Arg, response_t* pResp) const
01115 {
01116   ReturnCode Ret = SDC_RET_FAILED;
01117 
01118   /* Send Command to card */
01119   Ret = mci_SendCmd(Command, Arg, CMD_TIMEOUT);
01120   if (Ret != SDC_RET_OK) {
01121     return Ret;
01122   }
01123 
01124   /* Get response (if any) */
01125   if ((Command & SDC_COMMAND_RSP_BITMASK) != SDC_COMMAND_NO_RSP) {
01126 
01127     mci_GetResp(pResp);
01128 
01129     /* If the response is not R1, in the response field, the Expected Cmd data
01130             won't be the same as the CMD data in SendCmd(). Below four cmds have
01131             R2 or R3 response. We don't need to check if MCI_RESP_CMD is the same
01132             as the Expected or not. */
01133     if ((SDC_COMMAND_INDEX(Command) != MMC_SEND_OP_COND) &&
01134       (SDC_COMMAND_INDEX(Command) != SD_APP_OP_COND) &&
01135       (SDC_COMMAND_INDEX(Command) != MMC_ALL_SEND_CID) &&
01136       (SDC_COMMAND_INDEX(Command) != MMC_SEND_CSD) &&
01137       (pResp->CmdIndex != SDC_COMMAND_INDEX(Command))) {
01138       return SDC_RET_CMD_FAILED;
01139     }
01140   }
01141 
01142   return SDC_RET_OK;
01143 }
01144 
01145 MCIFileSystem::ReturnCode MCIFileSystem::mci_SendIfCond() const
01146 {
01147   ReturnCode Ret = SDC_RET_FAILED;
01148   response_t Response;
01149   uint32_t RetryCnt =  20;
01150 
01151   while (RetryCnt > 0) {
01152     Ret = mci_ExecuteCmd(SD_CMD8_SEND_IF_COND, (CMD8_VOLTAGESUPPLIED_27_36 | CMD8_CHECKPATTERN(
01153                               CMD8_DEF_PATTERN)), &Response);
01154     if (Ret == SDC_RET_OK) {
01155       if ((Response.Data[0] & CMDRESP_R7_VOLTAGE_ACCEPTED) &&
01156         (CMDRESP_R7_CHECK_PATTERN(Response.Data[0]) == CMD8_DEF_PATTERN)) {
01157         return SDC_RET_OK;
01158       }
01159       return SDC_RET_BAD_PARAMETERS;
01160     }
01161     RetryCnt--;
01162   }
01163   return Ret;
01164 }
01165 
01166 MCIFileSystem::ReturnCode MCIFileSystem::mci_SendOpCond(uint32_t *pOCR) const
01167 {
01168   ReturnCode Ret = SDC_RET_FAILED;
01169   response_t Response;
01170   uint32_t RetryCnt =  0x200;
01171 
01172   while (RetryCnt > 0) {
01173     Ret = mci_ExecuteCmd(SD_CMD1_SEND_OP_COND, SDC_OCR_27_36, &Response);
01174     if (Ret == SDC_RET_OK) {
01175       *pOCR = Response.Data[0];
01176       if (*pOCR & SDC_OCR_IDLE) {
01177         if ((Response.Data[0] & SDC_OCR_27_36) != SDC_OCR_27_36) {
01178           return SDC_RET_BAD_PARAMETERS;
01179         }
01180         return SDC_RET_OK;
01181       }
01182     }
01183     RetryCnt--;
01184   }
01185   return SDC_RET_FAILED;
01186 }
01187 
01188 MCIFileSystem::ReturnCode MCIFileSystem::mci_SendAppOpCond(uint16_t rca, bool hcs, uint32_t *pOcr, bool *pCCS) const
01189 {
01190   ReturnCode Ret = SDC_RET_FAILED;
01191   response_t Response;
01192   uint32_t Argument;
01193   uint32_t RetryCnt =  0x2000;  /* The host repeatedly issues ACMD41 for at least 1 second or
01194                          until the busy bit are set to 1 */
01195 
01196   Argument = ACMD41_OCR(*pOcr);
01197   if (hcs) {
01198     Argument |= ACMD41_HCS;
01199   }
01200 
01201   while (RetryCnt > 0) {
01202     Ret = mci_SendAppCmd(rca);
01203     if (Ret == SDC_RET_OK) {
01204       Ret = mci_ExecuteCmd(SD_ACMD41_SD_SEND_OP_COND, Argument, &Response);
01205       if (Ret == SDC_RET_OK) {
01206         if (Response.Data[0] & CMDRESP_R3_INIT_COMPLETE) {
01207           if (*pOcr == 0) {
01208             *pOcr = CMDRESP_R3_OCR_VAL(Response.Data[0]);
01209             return SDC_RET_OK;
01210           }
01211           if ((CMDRESP_R3_OCR_VAL(Response.Data[0]) & *pOcr) != *pOcr) {
01212             return SDC_RET_BAD_PARAMETERS;
01213           }
01214           *pCCS = (Response.Data[0] & CMDRESP_R3_HC_CCS) ? true : false;
01215           return SDC_RET_OK;
01216         }
01217       }
01218     }
01219     else {
01220       //If we abort here then some cards will go undetected, better to keep retrying
01221       //return Ret;
01222     }
01223     RetryCnt--;
01224   }
01225   return SDC_RET_FAILED;
01226 }
01227 
01228 MCIFileSystem::ReturnCode MCIFileSystem::mci_GetCID(uint32_t *pCID) const
01229 {
01230   ReturnCode Ret = SDC_RET_FAILED;
01231   response_t Response;
01232   uint32_t RetryCnt =  20;
01233 
01234   while (RetryCnt > 0) {
01235     Ret = mci_ExecuteCmd(SD_CMD2_ALL_SEND_CID, 0, &Response);
01236     if (Ret == SDC_RET_OK) {
01237       pCID[3] = Response.Data[0];
01238       pCID[2] = Response.Data[1];
01239       pCID[1] = Response.Data[2];
01240       pCID[0] = Response.Data[3];
01241       return SDC_RET_OK;
01242     }
01243     RetryCnt--;
01244   }
01245   return Ret;
01246 }
01247 
01248 MCIFileSystem::ReturnCode MCIFileSystem::mci_SetAddr(uint16_t addr) const
01249 {
01250   ReturnCode Ret = SDC_RET_FAILED;
01251   response_t Response;
01252   uint32_t RetryCnt =  20;
01253 
01254   while (RetryCnt > 0) {
01255     Ret = mci_ExecuteCmd(SD_CMD3_SET_RELATIVE_ADDR, CMD3_RCA(addr), &Response);
01256     if (Ret == SDC_RET_OK) {
01257       if (mci_CheckR1Response(Response.Data[0], &Ret)) {
01258         return Ret;
01259       }
01260     }
01261     RetryCnt--;
01262   }
01263   return Ret;
01264 }
01265 
01266 MCIFileSystem::ReturnCode MCIFileSystem::mci_GetAddr(uint16_t *pRCA) const
01267 {
01268   ReturnCode Ret = SDC_RET_FAILED;
01269   response_t Response;
01270   uint32_t RetryCnt =  20;
01271 
01272   *pRCA = 0;
01273   while (RetryCnt > 0) {
01274     Ret = mci_ExecuteCmd(SD_CMD3_SEND_RELATIVE_ADDR, 0, &Response);
01275     if (Ret == SDC_RET_OK) {
01276       if (!(CMDRESP_R6_CARD_STATUS(Response.Data[0]) & R1_READY_FOR_DATA)) {
01277         Ret = SDC_RET_NOT_READY;
01278       }
01279       else if (R1_CURRENT_STATE(CMDRESP_R6_CARD_STATUS(Response.Data[0])) != SDMMC_STBY_ST) {
01280         Ret = SDC_RET_ERR_STATE;
01281       }
01282       else {
01283         *pRCA = CMDRESP_R6_RCA_VAL(Response.Data[0]);
01284         return SDC_RET_OK;
01285       }
01286     }
01287     RetryCnt--;
01288   }
01289   return Ret;
01290 }
01291 
01292 MCIFileSystem::ReturnCode MCIFileSystem::mci_GetCSD(uint16_t rca, uint32_t *pCSD) const
01293 {
01294   ReturnCode Ret = SDC_RET_FAILED;
01295   response_t Response;
01296   uint32_t RetryCnt =  20;
01297 
01298   while (RetryCnt > 0) {
01299     Ret = mci_ExecuteCmd(SD_CMD9_SEND_CSD, CMD9_RCA(rca), &Response);
01300     if (Ret == SDC_RET_OK) {
01301       pCSD[3] = Response.Data[0];
01302       pCSD[2] = Response.Data[1];
01303       pCSD[1] = Response.Data[2];
01304       pCSD[0] = Response.Data[3];
01305       return Ret;
01306     }
01307     RetryCnt--;
01308   }
01309   return Ret;
01310 }
01311 
01312 MCIFileSystem::ReturnCode MCIFileSystem::mci_SelectCard(uint16_t addr) const
01313 {
01314   ReturnCode Ret = SDC_RET_FAILED;
01315   response_t Response;
01316   uint32_t RetryCnt =  20;
01317 
01318   while (RetryCnt > 0) {
01319     Ret = mci_ExecuteCmd(SD_CMD7_SELECT_CARD, CMD7_RCA(addr), &Response);
01320     if (Ret == SDC_RET_OK) {
01321       if (mci_CheckR1Response(Response.Data[0], &Ret)) {
01322         return Ret;
01323       }
01324     }
01325     RetryCnt--;
01326   }
01327   return Ret;
01328 }
01329 
01330 MCIFileSystem::ReturnCode MCIFileSystem::mci_GetStatus(uint16_t rca, uint32_t *pStatus) const
01331 {
01332   ReturnCode Ret = SDC_RET_FAILED;
01333   response_t Response;
01334   uint32_t RetryCnt =  20;
01335 
01336   *pStatus = (uint32_t) -1;
01337   while (RetryCnt > 0) {
01338     Ret = mci_ExecuteCmd(SD_CMD13_SEND_STATUS, CMD13_RCA(rca), &Response);
01339     if (Ret == SDC_RET_OK) {
01340       mci_CheckR1Response(Response.Data[0], &Ret);
01341       *pStatus = Response.Data[0];
01342       return Ret;
01343     }
01344     RetryCnt--;
01345   }
01346   return Ret;
01347 }
01348 
01349 void MCIFileSystem::mci_ProcessCSD()
01350 {
01351   int32_t CSize = 0;
01352   int32_t CSizeMult = 0;
01353   int32_t Mult = 0;
01354 
01355   /* compute block length based on CSD response */
01356   _sdCardInfo.block_len = 1 << mci_GetBits(80, 83, _sdCardInfo.csd);
01357 
01358   if ((_sdCardInfo.card_type & CARD_TYPE_HC) && (_sdCardInfo.card_type & CARD_TYPE_SD)) {
01359     /* See section 5.3.3 CSD Register (CSD Version 2.0) of SD2.0 spec  an explanation for the calculation of these values */
01360     CSize = mci_GetBits(48, 63, (uint32_t *) _sdCardInfo.csd) + 1;
01361     _sdCardInfo.blocknr = CSize << 10;  /* 512 byte blocks */
01362   }
01363   else {
01364     /* See section 5.3 of the 4.1 revision of the MMC specs for  an explanation for the calculation of these values */
01365     CSize = mci_GetBits(62, 73, (uint32_t *) _sdCardInfo.csd);
01366     CSizeMult = mci_GetBits(47, 49, (uint32_t *) _sdCardInfo.csd);
01367     Mult = 1 << (CSizeMult + 2);
01368     _sdCardInfo.blocknr = (CSize + 1) * Mult;
01369 
01370     /* adjust blocknr to 512/block */
01371     if (_sdCardInfo.block_len > MMC_SECTOR_SIZE) {
01372       _sdCardInfo.blocknr = _sdCardInfo.blocknr * (_sdCardInfo.block_len >> 9);
01373     }
01374   }
01375 
01376   _sdCardInfo.device_size = _sdCardInfo.blocknr << 9;  /* blocknr * 512 */
01377 }
01378 
01379 MCIFileSystem::ReturnCode MCIFileSystem::mci_SetBusWidth(uint16_t rca, uint8_t width) const
01380 {
01381   ReturnCode Ret = SDC_RET_FAILED;
01382   response_t Response;
01383   uint8_t RetryCnt =  0x20;
01384 
01385   while (RetryCnt > 0) {
01386     Ret = mci_SendAppCmd(rca);
01387     if (Ret == SDC_RET_OK) {
01388       Ret = mci_ExecuteCmd(SD_ACMD6_SET_BUS_WIDTH, ACMD6_BUS_WIDTH(width), &Response);
01389       if (Ret == SDC_RET_OK) {
01390         if (mci_CheckR1Response(Response.Data[0], &Ret)) {
01391           return Ret;
01392         }
01393       }
01394     }
01395     RetryCnt--;
01396   }
01397   return SDC_RET_FAILED;
01398 }
01399 
01400 MCIFileSystem::ReturnCode MCIFileSystem::mci_SetTranState(uint16_t rca) const
01401 {
01402   ReturnCode Ret = SDC_RET_OK;
01403   uint32_t status = 0;
01404   SDMMC_STATE_T state;
01405 
01406   /* get current state of the card */
01407   Ret = mci_GetStatus(rca, &status);
01408   if (Ret != SDC_RET_OK) {
01409     /* unable to get the card state. So return immediatly. */
01410     return Ret;
01411   }
01412 
01413   /* check card state in response */
01414   state = (SDMMC_STATE_T) R1_CURRENT_STATE(status);
01415   switch (state) {
01416   case SDMMC_STBY_ST:
01417     /* put card in 'Trans' state */
01418     Ret = mci_SelectCard(rca);
01419     if (Ret != SDC_RET_OK) {
01420       /* unable to put the card in Trans state. So return immediatly. */
01421       return Ret;
01422     }
01423     mci_GetStatus(rca, &status);
01424     if (((SDMMC_STATE_T) R1_CURRENT_STATE(status)) != ::SDMMC_TRAN_ST) {
01425       return SDC_RET_ERR_STATE;
01426     }
01427     break;
01428 
01429   case SDMMC_TRAN_ST:
01430     /*do nothing */
01431     break;
01432 
01433   default:
01434     /* card shouldn't be in other states so return */
01435     return SDC_RET_ERR_STATE;
01436   }
01437 
01438   return SDC_RET_OK;
01439 }
01440 
01441 MCIFileSystem::ReturnCode MCIFileSystem::mci_SetBlockLength(uint32_t rca, uint32_t block_len) const
01442 {
01443   ReturnCode Ret = SDC_RET_FAILED;
01444   response_t Response;
01445   uint8_t RetryCnt =  0x20;
01446 
01447   while (RetryCnt > 0) {
01448     Ret = mci_ExecuteCmd(SD_CMD16_SET_BLOCKLEN, block_len, &Response);
01449     if (Ret == SDC_RET_OK) {
01450       if (mci_CheckR1Response(Response.Data[0], &Ret)) {
01451         return Ret;
01452       }
01453     }
01454     RetryCnt--;
01455   }
01456   return SDC_RET_FAILED;
01457 }
01458 
01459 MCIFileSystem::ReturnCode MCIFileSystem::mci_SetCardParams() const
01460 {
01461   ReturnCode Ret;
01462 
01463   mci_SetClock(SDC_TRAN_CLOCK_RATE);
01464   if (_sdCardInfo.card_type & CARD_TYPE_SD) {
01465     mci_ClockControl(SDC_CLOCK_WIDEBUS_MODE, true);
01466     Ret = mci_SetBusWidth(_sdCardInfo.rca, ACMD6_BUS_WIDTH_4);
01467     if (Ret != SDC_RET_OK) {
01468       return Ret;
01469     }
01470   }
01471   else {
01472     mci_ClockControl(SDC_CLOCK_WIDEBUS_MODE, false);
01473   }
01474 
01475   /* set block length */
01476   Ret = mci_SetBlockLength(_sdCardInfo.rca, MMC_SECTOR_SIZE);
01477   return Ret;
01478 }
01479 
01480 bool MCIFileSystem::mci_CheckR1Response(uint32_t resp, ReturnCode* pCheckResult) const
01481 {
01482   bool Ret = true;
01483 
01484   if (!(resp & R1_READY_FOR_DATA)) {
01485     *pCheckResult = SDC_RET_NOT_READY;
01486     Ret = false;
01487   }
01488   else if (R1_STATUS(resp)) {
01489     *pCheckResult =  SDC_RET_FAILED;
01490   }
01491   else {
01492     *pCheckResult =  SDC_RET_OK;
01493   }
01494   return Ret;
01495 }
01496 
01497 void MCIFileSystem::mci_WriteDelay() const
01498 {
01499 //  volatile uint8_t i;
01500 //  for ( i = 0; i < 0x10; i++ ) {  /* delay 3MCLK + 2PCLK  */
01501 //  }
01502   wait(0.00001f); /* delay 10 us */
01503 }
01504 
01505 MCIFileSystem::ReturnCode MCIFileSystem::mci_SendCmd(uint32_t Command, uint32_t Arg, uint32_t timeout) const
01506 {
01507   ReturnCode ret = SDC_RET_TIMEOUT;
01508   uint32_t Status;
01509 
01510   /* Set Command Info */
01511   mci_SetCommand(Command, Arg);
01512 
01513   while (timeout) {
01514 
01515     Status = LPC_MCI->STATUS;
01516 
01517     /* check if command was sent */
01518     if (((Command & SDC_COMMAND_RSP_BITMASK) == SDC_COMMAND_NO_RSP) && (Status & SDC_STATUS_CMDSENT)) {
01519       ret =  SDC_RET_OK;
01520       break;
01521     }
01522     /* check if response was received */
01523     if (Status & SDC_STATUS_CMDRESPEND) {
01524       ret = SDC_RET_OK;
01525       break;
01526     }
01527 
01528     /* check command sending status */
01529     if (Status & SDC_STATUS_CMDERR) {
01530       if (Status & SDC_STATUS_CMDCRCFAIL) {
01531         if ((SDC_COMMAND_INDEX(Command) == MMC_SEND_OP_COND) ||
01532             (SDC_COMMAND_INDEX(Command) == SD_APP_OP_COND) ||
01533             (SDC_COMMAND_INDEX(Command) == MMC_STOP_TRANSMISSION)) {
01534           ret = SDC_RET_OK;  /* ignore CRC error if it's a resp for SEND_OP_COND  or STOP_TRANSMISSION. */
01535           break;
01536         }
01537       }
01538       ret = SDC_RET_CMD_FAILED;
01539       break;
01540     }
01541 
01542     timeout--;
01543   }
01544 
01545   mci_ResetCommand();
01546 
01547   return ret;
01548 }
01549 
01550 MCIFileSystem::ReturnCode MCIFileSystem::mci_SendAppCmd(uint16_t rca) const
01551 {
01552   ReturnCode Ret = SDC_RET_FAILED;
01553   response_t Response;
01554   uint32_t RetryCnt =  20;
01555 
01556   while (RetryCnt > 0) {
01557     Ret = mci_ExecuteCmd(SD_CMD55_APP_CMD, CMD55_RCA(rca), &Response);
01558     if (Ret == SDC_RET_OK) {
01559       if (mci_CheckR1Response(Response.Data[0], &Ret)) {
01560         if (Ret != SDC_RET_OK) {
01561           return Ret;
01562         }
01563         if (Response.Data[0] & R1_APP_CMD) {
01564           return SDC_RET_OK;
01565         }
01566         else {
01567           Ret = SDC_RET_FAILED;
01568         }
01569       }
01570     }
01571     RetryCnt--;
01572   }
01573   return SDC_RET_FAILED;
01574 }
01575 
01576 void MCIFileSystem::mci_SetDataTransfer(uint16_t BlockNum, bool DirFromCard, uint32_t Timeout) const
01577 {
01578   uint32_t DataCtrl = 0;
01579   LPC_MCI->DATATMR = Timeout;
01580   LPC_MCI->DATALEN = BlockNum * 512;
01581 
01582   DataCtrl = SDC_DATACTRL_ENABLE;
01583   // DataCtrl mode=block, block size=512byte
01584   DataCtrl |= (0x9 << 4);
01585   if (DirFromCard) {
01586     DataCtrl |= (0x1 << 1);
01587   }
01588   DataCtrl |= SDC_DATACTRL_DMA_ENABLE;
01589   LPC_MCI->DATACTRL = DataCtrl;
01590   mci_WriteDelay();
01591 }
01592 
01593 void MCIFileSystem::mci_GetResp(response_t* pResp) const
01594 {
01595   pResp->CmdIndex = SDC_RESPCOMMAND_VAL(LPC_MCI->RESP_CMD);
01596   pResp->Data[0] = LPC_MCI->RESP0;
01597   if (CardStatusNumBytes == 4) {
01598     pResp->Data[1] = LPC_MCI->RESP1;
01599     pResp->Data[2] = LPC_MCI->RESP2;
01600     pResp->Data[3] = LPC_MCI->RESP3;
01601   }
01602 }
01603 
01604 uint32_t MCIFileSystem::mci_GetBits(uint32_t start, uint32_t end, uint32_t *data) const
01605 {
01606   uint32_t v;
01607   uint32_t i = end >> 5;
01608   uint32_t j = start & 0x1f;
01609 
01610   if (i == (start >> 5)) {
01611     v = (data[i] >> j);
01612   }
01613   else {
01614     v = ((data[i] << (32 - j)) | (data[start >> 5] >> j));
01615   }
01616 
01617   return v & ((1 << (end - start + 1)) - 1);
01618 }
01619 
01620 void MCIFileSystem::mci_SetCommand(uint32_t Cmd, uint32_t Arg) const
01621 {
01622   /* Clear status register */
01623   LPC_MCI->CLEAR = SDC_CLEAR_ALL;
01624 
01625   /* Set the argument first, finally command */
01626   LPC_MCI->ARGUMENT = Arg;
01627 
01628   /* Write command value, enable the command */
01629   LPC_MCI->COMMAND = Cmd | SDC_COMMAND_ENABLE;
01630 
01631   mci_WriteDelay();
01632 }
01633 
01634 void MCIFileSystem::mci_ResetCommand() const
01635 {
01636   LPC_MCI->CLEAR = SDC_CLEAR_ALL;
01637 
01638   LPC_MCI->ARGUMENT = 0xFFFFFFFF;
01639 
01640   LPC_MCI->COMMAND = 0;
01641 
01642   mci_WriteDelay();
01643 }
01644 
01645 int32_t MCIFileSystem::mci_IRQHandler(uint8_t *txBuf, uint32_t *txCnt, uint8_t *rxBuf, uint32_t *rxCnt)
01646 {
01647   uint32_t Status;
01648 
01649   Status = LPC_MCI->STATUS;
01650 
01651   if ( Status & SDC_STATUS_DATAERR) {
01652     LPC_MCI->CLEAR = SDC_STATUS_DATAERR;
01653     return -1;  /* Data transfer error */
01654   }
01655 
01656   if ( Status & SDC_STATUS_DATAEND) {
01657     LPC_MCI->CLEAR = SDC_STATUS_DATAEND;
01658     LPC_MCI->MASK0 = 0;
01659     return 0;
01660   }
01661 
01662   if ( Status & SDC_STATUS_DATABLOCKEND) {
01663     LPC_MCI->CLEAR = SDC_STATUS_DATABLOCKEND;
01664     return 1;
01665   }
01666 
01667   if (Status & SDC_STATUS_FIFO) {
01668     return mci_FIFOIRQHandler(txBuf, txCnt, rxBuf, rxCnt);
01669   }
01670 
01671   return 1;
01672 }
01673 
01674 int32_t MCIFileSystem::mci_FIFOIRQHandler(uint8_t *txBuf, uint32_t *txCnt, uint8_t *rxBuf, uint32_t *rxCnt)
01675 {
01676   uint32_t Status;
01677   Status = LPC_MCI->STATUS;
01678 
01679   if (txBuf) {
01680     if (Status & SDC_STATUS_TXFIFOHALFEMPTY) {
01681       if (*txCnt % 64) {
01682         mci_WriteFIFO((uint32_t *) &txBuf[*txCnt], false);
01683       }
01684       else {
01685         mci_WriteFIFO((uint32_t *) &txBuf[*txCnt], true);
01686       }
01687       *txCnt += 32;
01688     }
01689   }
01690 
01691   if (rxBuf) {
01692     if (Status & SDC_STATUS_RXFIFOHALFFULL) {
01693       if (*rxCnt % 64) {
01694         mci_ReadFIFO((uint32_t *) &rxBuf[*rxCnt], false);
01695       }
01696       else {
01697         mci_ReadFIFO((uint32_t *) &rxBuf[*rxCnt], true);
01698       }
01699       *rxCnt += 32;
01700     }
01701   }
01702 
01703   LPC_MCI->CLEAR = SDC_STATUS_FIFO;
01704 
01705   return 1;
01706 }
01707 
01708 void MCIFileSystem::mci_ReadFIFO(uint32_t *pDst, bool bFirstHalf) const
01709 {
01710   uint8_t start = 0, end = 7;
01711 
01712   if (!bFirstHalf) {
01713     start += 8;
01714     end += 8;
01715   }
01716   for (; start <= end; start++) {
01717     *pDst = LPC_MCI->FIFO[start];
01718     pDst++;
01719   }
01720 }
01721 
01722 void MCIFileSystem::mci_WriteFIFO(uint32_t *pSrc, bool bFirstHalf) const
01723 {
01724   uint8_t start = 0, end = 7;
01725   if (!bFirstHalf) {
01726     start += 8;
01727     end += 8;
01728   }
01729   for (; start <= end; start++) {
01730     LPC_MCI->FIFO[start] = *pSrc;
01731     pSrc++;
01732   }
01733 }
01734 
01735 void MCIFileSystem::mci_SetupEventWakeup(uint8_t dmaChannel)
01736 {
01737   /* Wait for IRQ - for an RTOS, you would pend on an event here with a IRQ based wakeup. */
01738   NVIC_ClearPendingIRQ(DMA_IRQn);
01739 
01740   _eventDmaChannel = dmaChannel;
01741   _eventReceived = false;
01742   _eventSuccess = false;
01743 
01744   NVIC_EnableIRQ(DMA_IRQn);
01745 }
01746 
01747 uint32_t MCIFileSystem::mci_WaitForEvent() const
01748 {
01749   /* Wait for the event (DMA or MCI interrupt) for a maximum of 2 seconds */
01750   uint32_t end = us_ticker_read() + 2*1000*1000;
01751   while ((us_ticker_read() < end) && (!_eventReceived))
01752   {
01753     // If the driver is having problems reading the card, adding a delay here
01754     // might help.
01755     //wait(0.01);
01756   }
01757   
01758   if (_eventReceived && _eventSuccess) {
01759     return 0;
01760   }
01761 
01762   return 1;
01763 }
01764 
01765 MCIFileSystem::ReturnCode MCIFileSystem::_readBlocks(uint32_t card_type, uint32_t startBlock, uint32_t blockNum) const
01766 {
01767   ReturnCode Ret = SDC_RET_FAILED;
01768   response_t Response;
01769   uint32_t Command, Argument;
01770   uint8_t RetryCnt =  0x20;
01771 
01772   if (blockNum == 1) {
01773     Command = SD_CMD17_READ_SINGLE_BLOCK;
01774   }
01775   else {
01776     Command = SD_CMD18_READ_MULTIPLE_BLOCK;
01777   }
01778 
01779   /* Select single or multiple read based on number of blocks */
01780   /* if high capacity card use block indexing */
01781   if (card_type & CARD_TYPE_HC) {
01782     Argument = startBlock;
01783   }
01784   else {  /*fix at 512 bytes*/
01785     Argument = startBlock << 9;
01786   }
01787 
01788   while (RetryCnt > 0) {
01789     Ret = mci_ExecuteCmd(Command, Argument, &Response);
01790     if (Ret == SDC_RET_OK) {
01791       if (mci_CheckR1Response(Response.Data[0], &Ret)) {
01792         return Ret;
01793       }
01794     }
01795     RetryCnt--;
01796   }
01797   return Ret;
01798 }
01799 
01800 MCIFileSystem::ReturnCode MCIFileSystem::_writeBlocks(uint32_t card_type, uint32_t startBlock, uint32_t blockNum) const
01801 {
01802   ReturnCode Ret = SDC_RET_FAILED;
01803   response_t Response;
01804   uint32_t Command, Argument;
01805   uint8_t RetryCnt =  0x20;
01806 
01807   if (blockNum == 1) {
01808     Command = SD_CMD24_WRITE_BLOCK;
01809   }
01810   else {
01811     Command = SD_CMD25_WRITE_MULTIPLE_BLOCK;
01812   }
01813 
01814   /* if high capacity card use block indexing */
01815   if (card_type & CARD_TYPE_HC) {
01816     Argument = startBlock;
01817   }
01818   else {  /*fix at 512 bytes*/
01819     Argument = startBlock << 9;
01820 
01821   }
01822 
01823   while (RetryCnt > 0) {
01824     Ret = mci_ExecuteCmd(Command, Argument, &Response);
01825     if (Ret == SDC_RET_OK) {
01826       if (mci_CheckR1Response(Response.Data[0], &Ret)) {
01827         return Ret;
01828       }
01829     }
01830     RetryCnt--;
01831   }
01832   return Ret;
01833 }
01834