VZTECH / EALib

Dependencies:   FATFileSystem

Dependents:   main_src

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