Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: FATFileSystem
Fork of EALib by
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
Generated on Thu Jul 14 2022 07:21:53 by
1.7.2
