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