The wait in mci_WaitForEvent will delay all card transactions.

Dependencies:   FATFileSystem

Fork of EALib by EmbeddedArtists AB

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MCIFileSystem.cpp Source File

MCIFileSystem.cpp

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