![](/media/cache/group/logo.png.50x50_q85.jpg)
A board support package for the LPC4088 Display Module.
Dependencies: DM_HttpServer DM_USBHost
Dependents: lpc4088_displaymodule_emwin lpc4088_displaymodule_demo_sphere sampleGUI sampleEmptyGUI ... more
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 SD/MMC commands, arguments and responses 00349 * Standard SD/MMC commands (3.1) type argument response 00350 */ 00351 /* class 1 */ 00352 #define MMC_GO_IDLE_STATE 0 /* bc */ 00353 #define MMC_SEND_OP_COND 1 /* bcr [31:0] OCR R3 */ 00354 #define MMC_ALL_SEND_CID 2 /* bcr R2 */ 00355 #define MMC_SET_RELATIVE_ADDR 3 /* ac [31:16] RCA R1 */ 00356 #define MMC_SET_DSR 4 /* bc [31:16] RCA */ 00357 #define MMC_SELECT_CARD 7 /* ac [31:16] RCA R1 */ 00358 #define MMC_SEND_EXT_CSD 8 /* bc R1 */ 00359 #define MMC_SEND_CSD 9 /* ac [31:16] RCA R2 */ 00360 #define MMC_SEND_CID 10 /* ac [31:16] RCA R2 */ 00361 #define MMC_STOP_TRANSMISSION 12 /* ac R1b */ 00362 #define MMC_SEND_STATUS 13 /* ac [31:16] RCA R1 */ 00363 #define MMC_GO_INACTIVE_STATE 15 /* ac [31:16] RCA */ 00364 00365 /* class 2 */ 00366 #define MMC_SET_BLOCKLEN 16 /* ac [31:0] block len R1 */ 00367 #define MMC_READ_SINGLE_BLOCK 17 /* adtc [31:0] data addr R1 */ 00368 #define MMC_READ_MULTIPLE_BLOCK 18 /* adtc [31:0] data addr R1 */ 00369 00370 /* class 3 */ 00371 #define MMC_WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 */ 00372 00373 /* class 4 */ 00374 #define MMC_SET_BLOCK_COUNT 23 /* adtc [31:0] data addr R1 */ 00375 #define MMC_WRITE_BLOCK 24 /* adtc [31:0] data addr R1 */ 00376 #define MMC_WRITE_MULTIPLE_BLOCK 25 /* adtc R1 */ 00377 #define MMC_PROGRAM_CID 26 /* adtc R1 */ 00378 #define MMC_PROGRAM_CSD 27 /* adtc R1 */ 00379 00380 /* class 6 */ 00381 #define MMC_SET_WRITE_PROT 28 /* ac [31:0] data addr R1b */ 00382 #define MMC_CLR_WRITE_PROT 29 /* ac [31:0] data addr R1b */ 00383 #define MMC_SEND_WRITE_PROT 30 /* adtc [31:0] wpdata addr R1 */ 00384 00385 /* class 5 */ 00386 #define MMC_ERASE_GROUP_START 35 /* ac [31:0] data addr R1 */ 00387 #define MMC_ERASE_GROUP_END 36 /* ac [31:0] data addr R1 */ 00388 #define MMC_ERASE 37 /* ac R1b */ 00389 #define SD_ERASE_WR_BLK_START 32 /* ac [31:0] data addr R1 */ 00390 #define SD_ERASE_WR_BLK_END 33 /* ac [31:0] data addr R1 */ 00391 #define SD_ERASE 38 /* ac R1b */ 00392 00393 /* class 9 */ 00394 #define MMC_FAST_IO 39 /* ac <Complex> R4 */ 00395 #define MMC_GO_IRQ_STATE 40 /* bcr R5 */ 00396 00397 /* class 7 */ 00398 #define MMC_LOCK_UNLOCK 42 /* adtc R1b */ 00399 00400 /* class 8 */ 00401 #define MMC_APP_CMD 55 /* ac [31:16] RCA R1 */ 00402 #define MMC_GEN_CMD 56 /* adtc [0] RD/WR R1b */ 00403 00404 /* SD commands type argument response */ 00405 /* class 8 */ 00406 /* This is basically the same command as for MMC with some quirks. */ 00407 #define SD_SEND_RELATIVE_ADDR 3 /* ac R6 */ 00408 #define SD_CMD8 8 /* bcr [31:0] OCR R3 */ 00409 00410 /* Application commands */ 00411 #define SD_APP_SET_BUS_WIDTH 6 /* ac [1:0] bus width R1 */ 00412 #define SD_APP_OP_COND 41 /* bcr [31:0] OCR R1 (R4) */ 00413 #define SD_APP_SEND_SCR 51 /* adtc R1 */ 00414 00415 00416 /** 00417 * @brief MMC status in R1<br> 00418 * Type<br> 00419 * e : error bit<br> 00420 * s : status bit<br> 00421 * r : detected and set for the actual command response<br> 00422 * x : detected and set during command execution. the host must poll 00423 * the card by sending status command in order to read these bits. 00424 * Clear condition<br> 00425 * a : according to the card state<br> 00426 * b : always related to the previous command. Reception of 00427 * a valid command will clear it (with a delay of one command)<br> 00428 * c : clear by read<br> 00429 */ 00430 00431 #define R1_OUT_OF_RANGE (1UL << 31) /* er, c */ 00432 #define R1_ADDRESS_ERROR (1 << 30) /* erx, c */ 00433 #define R1_BLOCK_LEN_ERROR (1 << 29) /* er, c */ 00434 #define R1_ERASE_SEQ_ERROR (1 << 28) /* er, c */ 00435 #define R1_ERASE_PARAM (1 << 27) /* ex, c */ 00436 #define R1_WP_VIOLATION (1 << 26) /* erx, c */ 00437 #define R1_CARD_IS_LOCKED (1 << 25) /* sx, a */ 00438 #define R1_LOCK_UNLOCK_FAILED (1 << 24) /* erx, c */ 00439 #define R1_COM_CRC_ERROR (1 << 23) /* er, b */ 00440 #define R1_ILLEGAL_COMMAND (1 << 22) /* er, b */ 00441 #define R1_CARD_ECC_FAILED (1 << 21) /* ex, c */ 00442 #define R1_CC_ERROR (1 << 20) /* erx, c */ 00443 #define R1_ERROR (1 << 19) /* erx, c */ 00444 #define R1_UNDERRUN (1 << 18) /* ex, c */ 00445 #define R1_OVERRUN (1 << 17) /* ex, c */ 00446 #define R1_CID_CSD_OVERWRITE (1 << 16) /* erx, c, CID/CSD overwrite */ 00447 #define R1_WP_ERASE_SKIP (1 << 15) /* sx, c */ 00448 #define R1_CARD_ECC_DISABLED (1 << 14) /* sx, a */ 00449 #define R1_ERASE_RESET (1 << 13) /* sr, c */ 00450 #define R1_STATUS(x) (x & 0xFFFFE000) 00451 #define R1_CURRENT_STATE(x) ((x & 0x00001E00) >> 9) /* sx, b (4 bits) */ 00452 #define R1_READY_FOR_DATA (1 << 8) /* sx, a */ 00453 #define R1_APP_CMD (1 << 5) /* sr, c */ 00454 00455 00456 /** 00457 * @brief SD/MMC card OCR register bits 00458 */ 00459 #define OCR_ALL_READY (1UL << 31) /* Card Power up status bit */ 00460 #define OCR_HC_CCS (1 << 30) /* High capacity card */ 00461 #define OCR_VOLTAGE_RANGE_MSK (0x00FF8000) 00462 00463 #define SD_SEND_IF_ARG 0x000001AA 00464 #define SD_SEND_IF_ECHO_MSK 0x000000FF 00465 #define SD_SEND_IF_RESP 0x000000AA 00466 00467 /** 00468 * @brief R3 response definitions 00469 */ 00470 #define CMDRESP_R3_OCR_VAL(n) (((uint32_t) n) & 0xFFFFFF) 00471 #define CMDRESP_R3_S18A (((uint32_t) 1 ) << 24) 00472 #define CMDRESP_R3_HC_CCS (((uint32_t) 1 ) << 30) 00473 #define CMDRESP_R3_INIT_COMPLETE (((uint32_t) 1 ) << 31) 00474 00475 /** 00476 * @brief R6 response definitions 00477 */ 00478 #define CMDRESP_R6_RCA_VAL(n) (((uint32_t) (n >> 16)) & 0xFFFF) 00479 #define CMDRESP_R6_CARD_STATUS(n) (((uint32_t) (n & 0x1FFF)) | \ 00480 ((n & (1 << 13)) ? (1 << 19) : 0) | \ 00481 ((n & (1 << 14)) ? (1 << 22) : 0) | \ 00482 ((n & (1 << 15)) ? (1 << 23) : 0)) 00483 00484 /** 00485 * @brief R7 response definitions 00486 */ 00487 /** Echo-back of check-pattern */ 00488 #define CMDRESP_R7_CHECK_PATTERN(n) (((uint32_t) n ) & 0xFF) 00489 /** Voltage accepted */ 00490 #define CMDRESP_R7_VOLTAGE_ACCEPTED (((uint32_t) 1 ) << 8) 00491 00492 /** 00493 * @brief CMD3 command definitions 00494 */ 00495 /** Card Address */ 00496 #define CMD3_RCA(n) (((uint32_t) (n & 0xFFFF) ) << 16) 00497 00498 /** 00499 * @brief CMD7 command definitions 00500 */ 00501 /** Card Address */ 00502 #define CMD7_RCA(n) (((uint32_t) (n & 0xFFFF) ) << 16) 00503 00504 /** 00505 * @brief CMD8 command definitions 00506 */ 00507 /** Check pattern */ 00508 #define CMD8_CHECKPATTERN(n) (((uint32_t) (n & 0xFF) ) << 0) 00509 /** Recommended pattern */ 00510 #define CMD8_DEF_PATTERN (0xAA) 00511 /** Voltage supplied.*/ 00512 #define CMD8_VOLTAGESUPPLIED_27_36 (((uint32_t) 1 ) << 8) 00513 00514 /** 00515 * @brief CMD9 command definitions 00516 */ 00517 #define CMD9_RCA(n) (((uint32_t) (n & 0xFFFF) ) << 16) 00518 00519 /** 00520 * @brief CMD13 command definitions 00521 */ 00522 #define CMD13_RCA(n) (((uint32_t) (n & 0xFFFF) ) << 16) 00523 00524 /** 00525 * @brief APP_CMD command definitions 00526 */ 00527 #define CMD55_RCA(n) (((uint32_t) (n & 0xFFFF) ) << 16) 00528 00529 /** 00530 * @brief ACMD41 command definitions 00531 */ 00532 #define ACMD41_OCR(n) (((uint32_t) n) & 0xFFFFFF) 00533 #define ACMD41_S18R (((uint32_t) 1 ) << 24) 00534 #define ACMD41_XPC (((uint32_t) 1 ) << 28) 00535 #define ACMD41_HCS (((uint32_t) 1 ) << 30) 00536 00537 /** 00538 * @brief ACMD6 command definitions 00539 */ 00540 #define ACMD6_BUS_WIDTH(n) ((uint32_t) n & 0x03) 00541 #define ACMD6_BUS_WIDTH_1 (0) 00542 #define ACMD6_BUS_WIDTH_4 (2) 00543 00544 /** @brief Card type defines 00545 */ 00546 #define CARD_TYPE_SD (1 << 0) 00547 #define CARD_TYPE_4BIT (1 << 1) 00548 #define CARD_TYPE_8BIT (1 << 2) 00549 #define CARD_TYPE_HC (OCR_HC_CCS)/*!< high capacity card > 2GB */ 00550 00551 /** 00552 * @brief SD/MMC sector size in bytes 00553 */ 00554 #define MMC_SECTOR_SIZE 512 00555 00556 /****************************************************************************** 00557 * External global variables 00558 *****************************************************************************/ 00559 00560 /****************************************************************************** 00561 * Local variables 00562 *****************************************************************************/ 00563 00564 static MCIFileSystem* pUglyForIRQ = NULL; 00565 00566 /****************************************************************************** 00567 * Local Functions 00568 *****************************************************************************/ 00569 00570 static void mymciirq() 00571 { 00572 pUglyForIRQ->mci_MCIIRQHandler(); 00573 } 00574 00575 static void mydmairq() 00576 { 00577 pUglyForIRQ->mci_DMAIRQHandler(); 00578 } 00579 00580 /****************************************************************************** 00581 * Public Functions 00582 *****************************************************************************/ 00583 00584 MCIFileSystem::MCIFileSystem(PinName cd) : 00585 _init_ref_count(0), _is_initialized(false) 00586 { 00587 pUglyForIRQ = this; 00588 00589 memset(&_sdCardInfo, 0, sizeof(SDMMC_CARD_T)); 00590 _eventReceived = false; 00591 _eventSuccess = false; 00592 00593 initMCI(); 00594 00595 if (cd == NC) 00596 { 00597 _cardDetect = NULL; 00598 } 00599 else 00600 { 00601 _cardDetect = new DigitalIn(cd); 00602 _cardDetect->mode(PullUp); 00603 } 00604 } 00605 00606 MCIFileSystem::~MCIFileSystem() 00607 { 00608 if (_cardDetect != NULL) 00609 { 00610 delete _cardDetect; 00611 } 00612 } 00613 void MCIFileSystem::initMCI() 00614 { 00615 // Pinsel for MCI 00616 LPC_IOCON->P1_2 = 2; /* SD_CLK @ P1.2 */ 00617 LPC_IOCON->P1_3 = 2; /* SD_CMD @ P1.3 */ 00618 LPC_IOCON->P1_5 = 2 | (1<<7); /* SD_PWR @ P1.5 - digital mode */ 00619 LPC_IOCON->P1_6 = 2 | (1<<7); /* SD_DAT[0] @ P1.6 - digital mode */ 00620 LPC_IOCON->P1_7 = 2 | (1<<7); /* SD_DAT[1] @ P1.7 - digital mode */ 00621 LPC_IOCON->P1_11 = 2; /* SD_DAT[2] @ P1.11 */ 00622 LPC_IOCON->P1_12 = 2; /* SD_DAT[3] @ P1.12 */ 00623 00624 LPC_SC->PCONP |= SYSCTL_CLOCK_SDC; 00625 LPC_SC->RSTCON0 = (1<<28); 00626 LPC_SC->RSTCON0 &= ~(1<<28); 00627 00628 /* Initialize SDC peripheral */ 00629 LPC_SC->PCONP |= SYSCTL_CLOCK_SDC; 00630 00631 /* Disable SD_CLK */ 00632 mci_ClockControl(SDC_CLOCK_ENABLE, false); 00633 00634 /* Power-off */ 00635 mci_PowerControl(PowerOff, 0); 00636 mci_WriteDelay(); 00637 00638 /* Disable all interrupts */ 00639 LPC_MCI->MASK0 = 0; 00640 00641 /*Setting for timeout problem */ 00642 LPC_MCI->DATATMR = 0x1FFFFFFF; 00643 00644 LPC_MCI->COMMAND = 0; 00645 mci_WriteDelay(); 00646 00647 LPC_MCI->DATACTRL = 0; 00648 mci_WriteDelay(); 00649 00650 /* clear all pending interrupts */ 00651 LPC_MCI->CLEAR = SDC_CLEAR_ALL; 00652 00653 /* Power-up SDC Peripheral */ 00654 mci_PowerControl(PowerUp, 0); 00655 00656 /* delays for the supply output is stable*/ 00657 for (uint32_t i = 0; i < 0x80000; i++ ) {} 00658 00659 mci_SetClock(SDC_IDENT_CLOCK_RATE); 00660 mci_ClockControl(SDC_CLOCK_ENABLE, true); 00661 00662 /* Power-on SDC Interface */ 00663 mci_PowerControl(PowerOn, 0); 00664 00665 NVIC_SetVector(MCI_IRQn, (uint32_t) mymciirq); 00666 NVIC_EnableIRQ(MCI_IRQn); 00667 00668 /* Initialize GPDMA controller */ 00669 _eventDmaChannel = GPDMA::instance().acquireChannel(mydmairq); 00670 } 00671 00672 int MCIFileSystem::init() { 00673 uint32_t val = core_util_atomic_incr_u32(&_init_ref_count, 1); 00674 00675 if (val != 1) { 00676 return BD_ERROR_OK; 00677 } 00678 00679 debug_if(MCI_DBG, "mcifs:disk_initialize()\n"); 00680 00681 if (!cardInserted()) { 00682 debug("No card detected\r\n"); 00683 return BD_ERROR_DEVICE_ERROR; 00684 } 00685 00686 /* Initialize the Card Data Strucutre */ 00687 memset(&_sdCardInfo, 0, sizeof(SDMMC_CARD_T)); 00688 00689 /* Enumerate the card once detected. Note this function may block for a little while. */ 00690 int ret = mci_Acquire(); 00691 if (ret != 1) { 00692 debug("Card Acquire failed... got %d, but expected 1\r\n", ret); 00693 return BD_ERROR_DEVICE_ERROR; 00694 } 00695 00696 _is_initialized = true; 00697 return BD_ERROR_OK; 00698 } 00699 00700 int MCIFileSystem::deinit() { 00701 00702 if (!_is_initialized) { 00703 return BD_ERROR_OK; 00704 } 00705 00706 uint32_t val = core_util_atomic_decr_u32(&_init_ref_count, 1); 00707 00708 if (val) { 00709 return BD_ERROR_OK; 00710 } 00711 00712 _is_initialized = false; 00713 return BD_ERROR_OK; 00714 } 00715 00716 int MCIFileSystem::program(const void *buffer, bd_addr_t addr, bd_size_t size) { 00717 ReturnCode status; 00718 00719 debug_if(MCI_DBG, "mcifs:disk_write(%#x, %llu, %llu)\n", (uint32_t)buffer, addr, size); 00720 00721 if (!_is_initialized) { 00722 return BD_ERROR_DEVICE_ERROR; 00723 } 00724 00725 /* need to convert from number of bytes to blocks */ 00726 addr = addr / MMC_SECTOR_SIZE; 00727 size = size / MMC_SECTOR_SIZE; 00728 00729 status = mci_WriteBlocks((void*)buffer, addr, size); 00730 if (status != SDC_RET_OK) { 00731 return status; 00732 } 00733 00734 return BD_ERROR_OK; 00735 } 00736 00737 int MCIFileSystem::read(void *buffer, bd_addr_t addr, bd_size_t size) { 00738 ReturnCode status; 00739 debug_if(MCI_DBG, "mcifs:disk_read(%#x, %llu, %llu)\n", (uint32_t)buffer, addr, size); 00740 00741 if (!_is_initialized) { 00742 return BD_ERROR_DEVICE_ERROR; 00743 } 00744 00745 /* need to convert from number of bytes to blocks */ 00746 addr = addr / MMC_SECTOR_SIZE; 00747 size = size / MMC_SECTOR_SIZE; 00748 00749 status = mci_ReadBlocks(buffer, addr, size); 00750 if (status != SDC_RET_OK) { 00751 return status; 00752 } 00753 00754 return BD_ERROR_OK; 00755 } 00756 00757 int MCIFileSystem::sync() 00758 { 00759 debug_if(MCI_DBG, "mcifs:disk_sync()\n"); 00760 00761 if (!_is_initialized) { 00762 return BD_ERROR_OK; 00763 } 00764 00765 uint32_t end = us_ticker_read() + 50*1000; // 50ms 00766 while (us_ticker_read() < end) 00767 { 00768 if (mci_GetCardStatus() & R1_READY_FOR_DATA) 00769 { 00770 // card is ready 00771 return BD_ERROR_OK; 00772 } 00773 } 00774 00775 // timeout while waiting for card to get ready 00776 return SDC_RET_TIMEOUT; 00777 } 00778 00779 bd_size_t MCIFileSystem::get_read_size() const 00780 { 00781 return MMC_SECTOR_SIZE; 00782 } 00783 00784 bd_size_t MCIFileSystem::get_program_size() const 00785 { 00786 return MMC_SECTOR_SIZE; 00787 } 00788 00789 bd_size_t MCIFileSystem::size() const 00790 { 00791 return _sdCardInfo.block_len * MMC_SECTOR_SIZE; 00792 } 00793 00794 const char *MCIFileSystem::get_type() const 00795 { 00796 return "MCI"; 00797 } 00798 00799 void MCIFileSystem::mci_MCIIRQHandler() 00800 { 00801 int32_t Ret; 00802 00803 Ret = mci_IRQHandler(NULL, 0, NULL, 0); 00804 if(Ret < 0) { 00805 _eventSuccess = false; 00806 _eventReceived = true; 00807 } 00808 } 00809 00810 void MCIFileSystem::mci_DMAIRQHandler() 00811 { 00812 _eventSuccess = LPC_GPDMA->IntTCStat & (1<<_eventDmaChannel); 00813 _eventReceived = true; 00814 LPC_GPDMA->IntTCClear = (1<<_eventDmaChannel); 00815 LPC_GPDMA->IntErrClr = (1<<_eventDmaChannel); 00816 } 00817 00818 /****************************************************************************** 00819 * Private Functions 00820 *****************************************************************************/ 00821 00822 static bool gpdma_transfer_to_mci(GPDMA::DMAChannels ChannelNum, 00823 uint32_t src, 00824 uint32_t Size) 00825 { 00826 GPDMA::GPDMA_Channel_CFG_T cfg; 00827 cfg.ChannelNum = ChannelNum; 00828 cfg.TransferType = GPDMA::FlowControl_M2P_Ctrl_Periph; 00829 cfg.TransferSize = Size; 00830 cfg.TransferWidth = 0; 00831 cfg.SrcAddr = src; 00832 cfg.DstAddr = (uint32_t) (&LPC_MCI->FIFO); 00833 00834 uint32_t ctrl_word = 00835 GPDMA_DMACCxControl_TransferSize((uint32_t) cfg.TransferSize) 00836 | GPDMA_DMACCxControl_SBSize(GPDMA_BSIZE_8) 00837 | GPDMA_DMACCxControl_DBSize(GPDMA_BSIZE_8) 00838 | GPDMA_DMACCxControl_SWidth(GPDMA_WIDTH_WORD) 00839 | GPDMA_DMACCxControl_DWidth(GPDMA_WIDTH_WORD) 00840 | GPDMA_DMACCxControl_DestTransUseAHBMaster1 00841 | GPDMA_DMACCxControl_SI 00842 | GPDMA_DMACCxControl_I; 00843 00844 /* Select SD card interface in the DMA MUX*/ 00845 LPC_SC->DMAREQSEL &= ~(1 << 1); 00846 00847 return GPDMA::instance().transfer(&cfg, ctrl_word, 0, GPDMA_CONN_MEMORY, GPDMA_CONN_SDC); 00848 } 00849 00850 static bool gpdma_transfer_from_mci(GPDMA::DMAChannels ChannelNum, 00851 uint32_t dst, 00852 uint32_t Size) 00853 { 00854 GPDMA::GPDMA_Channel_CFG_T cfg; 00855 cfg.ChannelNum = ChannelNum; 00856 cfg.TransferType = GPDMA::FlowControl_P2M_Ctrl_Periph; 00857 cfg.TransferSize = Size; 00858 cfg.TransferWidth = 0; 00859 cfg.SrcAddr = (uint32_t) (&LPC_MCI->FIFO); 00860 cfg.DstAddr = dst; 00861 00862 uint32_t ctrl_word = 00863 GPDMA_DMACCxControl_TransferSize((uint32_t) cfg.TransferSize) 00864 | GPDMA_DMACCxControl_SBSize(GPDMA_BSIZE_8) 00865 | GPDMA_DMACCxControl_DBSize(GPDMA_BSIZE_8) 00866 | GPDMA_DMACCxControl_SWidth(GPDMA_WIDTH_WORD) 00867 | GPDMA_DMACCxControl_DWidth(GPDMA_WIDTH_WORD) 00868 | GPDMA_DMACCxControl_SrcTransUseAHBMaster1 00869 | GPDMA_DMACCxControl_DI 00870 | GPDMA_DMACCxControl_I; 00871 00872 /* Select SD card interface in the DMA MUX*/ 00873 LPC_SC->DMAREQSEL &= ~(1 << 1); 00874 00875 return GPDMA::instance().transfer(&cfg, ctrl_word, 0, GPDMA_CONN_SDC, GPDMA_CONN_MEMORY); 00876 } 00877 00878 bool MCIFileSystem::cardInserted() const 00879 { 00880 // If no card detect pin is given, then assume that a card is inserted. 00881 // If a pin is specified then use that to determing the presence of a card. 00882 return ((_cardDetect == NULL) || (_cardDetect->read() == 0)); 00883 } 00884 00885 00886 00887 int32_t MCIFileSystem::mci_Acquire() 00888 { 00889 int32_t Ret; 00890 00891 /* Initialize card info */ 00892 _sdCardInfo.speed = SDC_TRAN_CLOCK_RATE; 00893 _sdCardInfo.card_type = 0; 00894 00895 /* During identification phase, the clock should be less than 00896 400Khz. Once we pass this phase, the normal clock can be set up 00897 to 25Mhz on SD card and 20Mhz on MMC card. */ 00898 mci_SetClock(SDC_IDENT_CLOCK_RATE); 00899 00900 /* Clear Open Drain output control for SD */ 00901 mci_PowerControl(PowerOn, 0); 00902 00903 /* Card Reset */ 00904 Ret = mci_ExecuteCmd(SD_GO_IDLE_STATE, 0, NULL); 00905 if (Ret != 0) { 00906 return Ret; 00907 } 00908 00909 ThisThread::sleep_for(ACQUIRE_DELAY); 00910 00911 /* Send interface operation condiftion */ 00912 Ret = mci_SendIfCond(); 00913 if (Ret == SDC_RET_BAD_PARAMETERS) { 00914 return Ret; /* Non-compatible voltage range or check pattern is not correct */ 00915 00916 } 00917 /* Get Card Type */ 00918 if (Ret == SDC_RET_OK) {/* Ver2.00 or later SD Memory Card*/ 00919 bool CCS; 00920 uint32_t OCR = SDC_OCR_27_36; 00921 _sdCardInfo.card_type |= CARD_TYPE_SD; 00922 Ret = mci_SendAppOpCond(0, true, &OCR, &CCS); 00923 if (CCS) { /* High Capacity or Extended Capacity SD Memory Card */ 00924 _sdCardInfo.card_type |= CARD_TYPE_HC; 00925 } 00926 } 00927 else { /*Ver2.00 or later SD Memory Card(voltage mismatch) or Ver1.X SD Memory Card 00928 or not SD Memory Card*/ 00929 bool CCS; 00930 uint32_t OCR = SDC_OCR_27_36; 00931 Ret = mci_SendAppOpCond(0, false, &OCR, &CCS); 00932 if (Ret == SDC_RET_OK) { 00933 _sdCardInfo.card_type |= CARD_TYPE_SD; 00934 } 00935 else if (Ret == SDC_RET_BAD_PARAMETERS) { 00936 return Ret; 00937 } 00938 else { /* MMC Card setup */ 00939 uint32_t OCR; 00940 /* Enter to Open Drain mode */ 00941 mci_PowerControl(PowerOn, SDC_PWR_OPENDRAIN); 00942 ThisThread::sleep_for(ACQUIRE_DELAY); 00943 Ret = mci_SendOpCond(&OCR); 00944 if (Ret != SDC_RET_OK) { 00945 return Ret; 00946 } 00947 00948 } 00949 } 00950 00951 /* Read CID */ 00952 mci_GetCID(_sdCardInfo.cid); 00953 00954 /* RCA send, for SD get RCA */ 00955 if (_sdCardInfo.card_type & CARD_TYPE_SD) { 00956 mci_GetAddr(&_sdCardInfo.rca); 00957 } 00958 else { 00959 _sdCardInfo.rca = 1; 00960 mci_SetAddr(_sdCardInfo.rca); 00961 mci_PowerControl(PowerOn, 0); /* enter to push-pull mode */ 00962 } 00963 00964 /* Get CSD */ 00965 mci_GetCSD(_sdCardInfo.rca, _sdCardInfo.csd); 00966 00967 /* Compute card size, block size and no. of blocks based on CSD response recived. */ 00968 if (_sdCardInfo.cid[0]) { 00969 mci_ProcessCSD(); 00970 00971 if (mci_SetTranState(_sdCardInfo.rca) != SDC_RET_OK) { 00972 return 0; 00973 } 00974 00975 if (mci_GetCardState() != SDMMC_TRAN_ST) { 00976 return 0; 00977 } 00978 00979 if (mci_SetCardParams() != 0) { 00980 return 0; 00981 } 00982 } 00983 00984 return (_sdCardInfo.cid[0]) ? 1 : 0; 00985 } 00986 00987 uint32_t MCIFileSystem::mci_GetCardStatus() const 00988 { 00989 uint32_t Status; 00990 mci_GetStatus(_sdCardInfo.rca, &Status); 00991 return Status; 00992 } 00993 00994 MCIFileSystem::CardState MCIFileSystem::mci_GetCardState() const 00995 { 00996 uint32_t Status; 00997 volatile int32_t Ret; 00998 00999 /* get current state of the card */ 01000 Ret = mci_GetStatus(_sdCardInfo.rca, &Status); 01001 01002 /* check card state in response */ 01003 return (CardState) R1_CURRENT_STATE(Status); 01004 } 01005 01006 MCIFileSystem::ReturnCode MCIFileSystem::mci_StopTransmission(uint32_t rca) const 01007 { 01008 uint32_t Status; 01009 ReturnCode Ret = SDC_RET_FAILED; 01010 response_t Response; 01011 uint32_t RetryCnt = 20; 01012 01013 Ret = mci_GetStatus(rca, &Status); 01014 if (Ret != SDC_RET_OK) { 01015 return SDC_RET_ERR_STATE; 01016 } 01017 01018 if (R1_CURRENT_STATE(Status) == SDMMC_TRAN_ST) { 01019 return SDC_RET_OK; 01020 } 01021 01022 if ((R1_CURRENT_STATE(Status) != SDMMC_DATA_ST) && 01023 (R1_CURRENT_STATE(Status) != SDMMC_RCV_ST)) { 01024 return SDC_RET_ERR_STATE; 01025 } 01026 01027 while (RetryCnt > 0) { 01028 Ret = mci_ExecuteCmd(SD_CMD12_STOP_TRANSMISSION, 0, &Response); 01029 if (Ret == SDC_RET_OK) { 01030 if (mci_CheckR1Response(Response.Data[0], &Ret)) { 01031 if (Ret != SDC_RET_OK) { 01032 return Ret; 01033 } 01034 Ret = mci_GetStatus(rca, &Status); 01035 if ((R1_CURRENT_STATE(Status) == SDMMC_TRAN_ST) || (R1_CURRENT_STATE(Status) == SDMMC_PRG_ST)) { 01036 return SDC_RET_OK; 01037 } 01038 return SDC_RET_ERR_STATE; 01039 } 01040 } 01041 RetryCnt--; 01042 } 01043 return Ret; 01044 } 01045 01046 MCIFileSystem::ReturnCode MCIFileSystem::mci_ReadBlocks(void *buffer, int32_t startBlock, int32_t blockNum) 01047 { 01048 ReturnCode Ret = SDC_RET_FAILED; 01049 int32_t ByteNum = blockNum * MMC_SECTOR_SIZE; 01050 01051 do 01052 { 01053 /* if card is not acquired return immediately */ 01054 if (( startBlock < 0) || ( (startBlock + blockNum) > _sdCardInfo.blocknr) ) { 01055 Ret = SDC_RET_NOT_READY; 01056 break; 01057 } 01058 01059 /* Put to tran state */ 01060 Ret = mci_SetTranState(_sdCardInfo.rca); 01061 if (Ret != SDC_RET_OK) { 01062 break; 01063 } 01064 01065 LPC_MCI->MASK0 = SDC_MASK0_DATA | SDC_MASK0_RXDATAERR; 01066 01067 /* DMA Setup */ 01068 mci_SetupEventWakeup(); 01069 gpdma_transfer_from_mci(_eventDmaChannel, (uint32_t)buffer, ByteNum); 01070 01071 /* set transfer information */ 01072 mci_SetDataTransfer(blockNum, true, DATA_TIMER_VALUE_R); 01073 01074 Ret = _readBlocks(_sdCardInfo.card_type, startBlock, blockNum); 01075 if (Ret == SDC_RET_OK) { 01076 /* Wait for transfer Finish */ 01077 if (mci_WaitForEvent() != 0) { 01078 Ret = SDC_RET_FAILED; 01079 } 01080 } else { 01081 Ret = SDC_RET_FAILED; 01082 } 01083 01084 GPDMA::instance().stopTransfer(_eventDmaChannel); 01085 01086 if ((blockNum > 1) || (mci_GetCardState() == SDMMC_DATA_ST)) { 01087 /* Send Stop transmission command */ 01088 mci_StopTransmission(_sdCardInfo.rca); 01089 } 01090 01091 /* Wait for card to enter tran state */ 01092 while (mci_GetCardState() != SDMMC_TRAN_ST) {} 01093 01094 } while(false); 01095 01096 return Ret; 01097 } 01098 01099 MCIFileSystem::ReturnCode MCIFileSystem::mci_WriteBlocks(void *buffer, int32_t startBlock, int32_t blockNum) 01100 { 01101 ReturnCode Ret = SDC_RET_FAILED; 01102 01103 do 01104 { 01105 /* if card is not acquired return immediately */ 01106 if (( startBlock < 0) || ( (startBlock + blockNum) > _sdCardInfo.blocknr) ) { 01107 Ret = SDC_RET_NOT_READY; 01108 break; 01109 } 01110 01111 /* Put to tran state */ 01112 Ret = mci_SetTranState(_sdCardInfo.rca); 01113 if (Ret != SDC_RET_OK) { 01114 break; 01115 } 01116 01117 Ret = _writeBlocks(_sdCardInfo.card_type, startBlock, blockNum); 01118 if (Ret != SDC_RET_OK) { 01119 break; 01120 } 01121 01122 /*Wait for card enter to rcv state*/ 01123 while (mci_GetCardState() != SDMMC_RCV_ST) {} 01124 01125 LPC_MCI->MASK0 = SDC_MASK0_DATA | SDC_MASK0_TXDATAERR; 01126 01127 /* DMA Setup */ 01128 mci_SetupEventWakeup(); 01129 gpdma_transfer_to_mci(_eventDmaChannel, (uint32_t)buffer, blockNum*MMC_SECTOR_SIZE); 01130 01131 /* set transfer information */ 01132 mci_SetDataTransfer(blockNum, false, DATA_TIMER_VALUE_W); 01133 01134 /* Wait for transfer done */ 01135 if (mci_WaitForEvent() != 0) { 01136 Ret = SDC_RET_FAILED; 01137 } 01138 01139 if ((blockNum > 1) || (mci_GetCardState() == SDMMC_RCV_ST)) { 01140 /* Send Stop transmission command */ 01141 mci_StopTransmission(_sdCardInfo.rca); 01142 } 01143 01144 /* Wait for card to enter tran state */ 01145 while (mci_GetCardState() != SDMMC_TRAN_ST) {} 01146 01147 } while (false); 01148 01149 return Ret; 01150 } 01151 01152 void MCIFileSystem::mci_SetClock(uint32_t freq) const 01153 { 01154 uint32_t PClk; 01155 uint32_t ClkValue = 0; 01156 01157 PClk = PeripheralClock; 01158 01159 ClkValue = (PClk + 2 * freq - 1) / (2 * freq); 01160 if (ClkValue > 0) { 01161 ClkValue -= 1; 01162 } 01163 uint32_t temp; 01164 temp = (LPC_MCI->CLOCK & (~SDC_CLOCK_CLKDIV_BITMASK)); 01165 LPC_MCI->CLOCK = temp | (SDC_CLOCK_CLKDIV(ClkValue)); 01166 mci_WriteDelay(); 01167 } 01168 01169 void MCIFileSystem::mci_ClockControl(ClockControl ctrlType, bool enable) const 01170 { 01171 if (enable) { 01172 LPC_MCI->CLOCK |= (1 << ctrlType); 01173 } 01174 else { 01175 LPC_MCI->CLOCK &= (~(1 << ctrlType)); 01176 } 01177 mci_WriteDelay(); 01178 } 01179 01180 void MCIFileSystem::mci_PowerControl(power_ctrl_t powerMode, uint32_t flag) const 01181 { 01182 LPC_MCI->POWER = (powerMode & 0x3) | flag; 01183 mci_WriteDelay(); 01184 } 01185 01186 MCIFileSystem::ReturnCode MCIFileSystem::mci_ExecuteCmd(uint32_t Command, uint32_t Arg, response_t* pResp) const 01187 { 01188 ReturnCode Ret = SDC_RET_FAILED; 01189 01190 /* Send Command to card */ 01191 Ret = mci_SendCmd(Command, Arg, CMD_TIMEOUT); 01192 if (Ret != SDC_RET_OK) { 01193 return Ret; 01194 } 01195 01196 /* Get response (if any) */ 01197 if ((Command & SDC_COMMAND_RSP_BITMASK) != SDC_COMMAND_NO_RSP) { 01198 01199 mci_GetResp(pResp); 01200 01201 /* If the response is not R1, in the response field, the Expected Cmd data 01202 won't be the same as the CMD data in SendCmd(). Below four cmds have 01203 R2 or R3 response. We don't need to check if MCI_RESP_CMD is the same 01204 as the Expected or not. */ 01205 if ((SDC_COMMAND_INDEX(Command) != MMC_SEND_OP_COND) && 01206 (SDC_COMMAND_INDEX(Command) != SD_APP_OP_COND) && 01207 (SDC_COMMAND_INDEX(Command) != MMC_ALL_SEND_CID) && 01208 (SDC_COMMAND_INDEX(Command) != MMC_SEND_CSD) && 01209 (pResp->CmdIndex != SDC_COMMAND_INDEX(Command))) { 01210 return SDC_RET_CMD_FAILED; 01211 } 01212 } 01213 01214 return SDC_RET_OK; 01215 } 01216 01217 MCIFileSystem::ReturnCode MCIFileSystem::mci_SendIfCond() const 01218 { 01219 ReturnCode Ret = SDC_RET_FAILED; 01220 response_t Response; 01221 uint32_t RetryCnt = 20; 01222 01223 while (RetryCnt > 0) { 01224 Ret = mci_ExecuteCmd(SD_CMD8_SEND_IF_COND, (CMD8_VOLTAGESUPPLIED_27_36 | CMD8_CHECKPATTERN( 01225 CMD8_DEF_PATTERN)), &Response); 01226 if (Ret == SDC_RET_OK) { 01227 if ((Response.Data[0] & CMDRESP_R7_VOLTAGE_ACCEPTED) && 01228 (CMDRESP_R7_CHECK_PATTERN(Response.Data[0]) == CMD8_DEF_PATTERN)) { 01229 return SDC_RET_OK; 01230 } 01231 return SDC_RET_BAD_PARAMETERS; 01232 } 01233 RetryCnt--; 01234 } 01235 return Ret; 01236 } 01237 01238 MCIFileSystem::ReturnCode MCIFileSystem::mci_SendOpCond(uint32_t *pOCR) const 01239 { 01240 ReturnCode Ret = SDC_RET_FAILED; 01241 response_t Response; 01242 uint32_t RetryCnt = 0x200; 01243 01244 while (RetryCnt > 0) { 01245 Ret = mci_ExecuteCmd(SD_CMD1_SEND_OP_COND, SDC_OCR_27_36, &Response); 01246 if (Ret == SDC_RET_OK) { 01247 *pOCR = Response.Data[0]; 01248 if (*pOCR & SDC_OCR_IDLE) { 01249 if ((Response.Data[0] & SDC_OCR_27_36) != SDC_OCR_27_36) { 01250 return SDC_RET_BAD_PARAMETERS; 01251 } 01252 return SDC_RET_OK; 01253 } 01254 } 01255 RetryCnt--; 01256 } 01257 return SDC_RET_FAILED; 01258 } 01259 01260 MCIFileSystem::ReturnCode MCIFileSystem::mci_SendAppOpCond(uint16_t rca, bool hcs, uint32_t *pOcr, bool *pCCS) const 01261 { 01262 ReturnCode Ret = SDC_RET_FAILED; 01263 response_t Response; 01264 uint32_t Argument; 01265 uint32_t RetryCnt = 0x2000; /* The host repeatedly issues ACMD41 for at least 1 second or 01266 until the busy bit are set to 1 */ 01267 01268 Argument = ACMD41_OCR(*pOcr); 01269 if (hcs) { 01270 Argument |= ACMD41_HCS; 01271 } 01272 01273 while (RetryCnt > 0) { 01274 Ret = mci_SendAppCmd(rca); 01275 if (Ret == SDC_RET_OK) { 01276 Ret = mci_ExecuteCmd(SD_ACMD41_SD_SEND_OP_COND, Argument, &Response); 01277 if (Ret == SDC_RET_OK) { 01278 if (Response.Data[0] & CMDRESP_R3_INIT_COMPLETE) { 01279 if (*pOcr == 0) { 01280 *pOcr = CMDRESP_R3_OCR_VAL(Response.Data[0]); 01281 return SDC_RET_OK; 01282 } 01283 if ((CMDRESP_R3_OCR_VAL(Response.Data[0]) & *pOcr) != *pOcr) { 01284 return SDC_RET_BAD_PARAMETERS; 01285 } 01286 *pCCS = (Response.Data[0] & CMDRESP_R3_HC_CCS) ? true : false; 01287 return SDC_RET_OK; 01288 } 01289 } 01290 } 01291 else { 01292 //If we abort here then some cards will go undetected, better to keep retrying 01293 //return Ret; 01294 } 01295 RetryCnt--; 01296 } 01297 return SDC_RET_FAILED; 01298 } 01299 01300 MCIFileSystem::ReturnCode MCIFileSystem::mci_GetCID(uint32_t *pCID) const 01301 { 01302 ReturnCode Ret = SDC_RET_FAILED; 01303 response_t Response; 01304 uint32_t RetryCnt = 20; 01305 01306 while (RetryCnt > 0) { 01307 Ret = mci_ExecuteCmd(SD_CMD2_ALL_SEND_CID, 0, &Response); 01308 if (Ret == SDC_RET_OK) { 01309 pCID[3] = Response.Data[0]; 01310 pCID[2] = Response.Data[1]; 01311 pCID[1] = Response.Data[2]; 01312 pCID[0] = Response.Data[3]; 01313 return SDC_RET_OK; 01314 } 01315 RetryCnt--; 01316 } 01317 return Ret; 01318 } 01319 01320 MCIFileSystem::ReturnCode MCIFileSystem::mci_SetAddr(uint16_t addr) const 01321 { 01322 ReturnCode Ret = SDC_RET_FAILED; 01323 response_t Response; 01324 uint32_t RetryCnt = 20; 01325 01326 while (RetryCnt > 0) { 01327 Ret = mci_ExecuteCmd(SD_CMD3_SET_RELATIVE_ADDR, CMD3_RCA(addr), &Response); 01328 if (Ret == SDC_RET_OK) { 01329 if (mci_CheckR1Response(Response.Data[0], &Ret)) { 01330 return Ret; 01331 } 01332 } 01333 RetryCnt--; 01334 } 01335 return Ret; 01336 } 01337 01338 MCIFileSystem::ReturnCode MCIFileSystem::mci_GetAddr(uint16_t *pRCA) const 01339 { 01340 ReturnCode Ret = SDC_RET_FAILED; 01341 response_t Response; 01342 uint32_t RetryCnt = 20; 01343 01344 *pRCA = 0; 01345 while (RetryCnt > 0) { 01346 Ret = mci_ExecuteCmd(SD_CMD3_SEND_RELATIVE_ADDR, 0, &Response); 01347 if (Ret == SDC_RET_OK) { 01348 if (!(CMDRESP_R6_CARD_STATUS(Response.Data[0]) & R1_READY_FOR_DATA)) { 01349 Ret = SDC_RET_NOT_READY; 01350 } 01351 else if (R1_CURRENT_STATE(CMDRESP_R6_CARD_STATUS(Response.Data[0])) != SDMMC_STBY_ST) { 01352 Ret = SDC_RET_ERR_STATE; 01353 } 01354 else { 01355 *pRCA = CMDRESP_R6_RCA_VAL(Response.Data[0]); 01356 return SDC_RET_OK; 01357 } 01358 } 01359 RetryCnt--; 01360 } 01361 return Ret; 01362 } 01363 01364 MCIFileSystem::ReturnCode MCIFileSystem::mci_GetCSD(uint16_t rca, uint32_t *pCSD) const 01365 { 01366 ReturnCode Ret = SDC_RET_FAILED; 01367 response_t Response; 01368 uint32_t RetryCnt = 20; 01369 01370 while (RetryCnt > 0) { 01371 Ret = mci_ExecuteCmd(SD_CMD9_SEND_CSD, CMD9_RCA(rca), &Response); 01372 if (Ret == SDC_RET_OK) { 01373 pCSD[3] = Response.Data[0]; 01374 pCSD[2] = Response.Data[1]; 01375 pCSD[1] = Response.Data[2]; 01376 pCSD[0] = Response.Data[3]; 01377 return Ret; 01378 } 01379 RetryCnt--; 01380 } 01381 return Ret; 01382 } 01383 01384 MCIFileSystem::ReturnCode MCIFileSystem::mci_SelectCard(uint16_t addr) const 01385 { 01386 ReturnCode Ret = SDC_RET_FAILED; 01387 response_t Response; 01388 uint32_t RetryCnt = 20; 01389 01390 while (RetryCnt > 0) { 01391 Ret = mci_ExecuteCmd(SD_CMD7_SELECT_CARD, CMD7_RCA(addr), &Response); 01392 if (Ret == SDC_RET_OK) { 01393 if (mci_CheckR1Response(Response.Data[0], &Ret)) { 01394 return Ret; 01395 } 01396 } 01397 RetryCnt--; 01398 } 01399 return Ret; 01400 } 01401 01402 MCIFileSystem::ReturnCode MCIFileSystem::mci_GetStatus(uint16_t rca, uint32_t *pStatus) const 01403 { 01404 ReturnCode Ret = SDC_RET_FAILED; 01405 response_t Response; 01406 uint32_t RetryCnt = 20; 01407 01408 *pStatus = (uint32_t) -1; 01409 while (RetryCnt > 0) { 01410 Ret = mci_ExecuteCmd(SD_CMD13_SEND_STATUS, CMD13_RCA(rca), &Response); 01411 if (Ret == SDC_RET_OK) { 01412 mci_CheckR1Response(Response.Data[0], &Ret); 01413 *pStatus = Response.Data[0]; 01414 return Ret; 01415 } 01416 RetryCnt--; 01417 } 01418 return Ret; 01419 } 01420 01421 void MCIFileSystem::mci_ProcessCSD() 01422 { 01423 int32_t CSize = 0; 01424 int32_t CSizeMult = 0; 01425 int32_t Mult = 0; 01426 01427 /* compute block length based on CSD response */ 01428 _sdCardInfo.block_len = 1 << mci_GetBits(80, 83, _sdCardInfo.csd); 01429 if ((_sdCardInfo.card_type & CARD_TYPE_HC) && (_sdCardInfo.card_type & CARD_TYPE_SD)) { 01430 /* See section 5.3.3 CSD Register (CSD Version 2.0) of SD2.0 spec an explanation for the calculation of these values */ 01431 CSize = mci_GetBits(48, 63, (uint32_t *) _sdCardInfo.csd) + 1; 01432 _sdCardInfo.blocknr = CSize << 10; /* 512 byte blocks */ 01433 } 01434 else { 01435 /* See section 5.3 of the 4.1 revision of the MMC specs for an explanation for the calculation of these values */ 01436 CSize = mci_GetBits(62, 73, (uint32_t *) _sdCardInfo.csd); 01437 CSizeMult = mci_GetBits(47, 49, (uint32_t *) _sdCardInfo.csd); 01438 Mult = 1 << (CSizeMult + 2); 01439 _sdCardInfo.blocknr = (CSize + 1) * Mult; 01440 01441 /* adjust blocknr to 512/block */ 01442 if (_sdCardInfo.block_len > MMC_SECTOR_SIZE) { 01443 _sdCardInfo.blocknr = _sdCardInfo.blocknr * (_sdCardInfo.block_len >> 9); 01444 } 01445 } 01446 01447 _sdCardInfo.device_size = _sdCardInfo.blocknr << 9; /* blocknr * 512 */ 01448 } 01449 01450 MCIFileSystem::ReturnCode MCIFileSystem::mci_SetBusWidth(uint16_t rca, uint8_t width) const 01451 { 01452 ReturnCode Ret = SDC_RET_FAILED; 01453 response_t Response; 01454 uint8_t RetryCnt = 0x20; 01455 01456 while (RetryCnt > 0) { 01457 Ret = mci_SendAppCmd(rca); 01458 if (Ret == SDC_RET_OK) { 01459 Ret = mci_ExecuteCmd(SD_ACMD6_SET_BUS_WIDTH, ACMD6_BUS_WIDTH(width), &Response); 01460 if (Ret == SDC_RET_OK) { 01461 if (mci_CheckR1Response(Response.Data[0], &Ret)) { 01462 return Ret; 01463 } 01464 } 01465 } 01466 RetryCnt--; 01467 } 01468 return SDC_RET_FAILED; 01469 } 01470 01471 MCIFileSystem::ReturnCode MCIFileSystem::mci_SetTranState(uint16_t rca) const 01472 { 01473 ReturnCode Ret = SDC_RET_OK; 01474 uint32_t status = 0; 01475 CardState state; 01476 01477 /* get current state of the card */ 01478 Ret = mci_GetStatus(rca, &status); 01479 if (Ret != SDC_RET_OK) { 01480 /* unable to get the card state. So return immediatly. */ 01481 return Ret; 01482 } 01483 01484 /* check card state in response */ 01485 state = (CardState) R1_CURRENT_STATE(status); 01486 switch (state) { 01487 case SDMMC_STBY_ST: 01488 /* put card in 'Trans' state */ 01489 Ret = mci_SelectCard(rca); 01490 if (Ret != SDC_RET_OK) { 01491 /* unable to put the card in Trans state. So return immediatly. */ 01492 return Ret; 01493 } 01494 mci_GetStatus(rca, &status); 01495 if (((CardState) R1_CURRENT_STATE(status)) != SDMMC_TRAN_ST) { 01496 return SDC_RET_ERR_STATE; 01497 } 01498 break; 01499 01500 case SDMMC_TRAN_ST: 01501 /*do nothing */ 01502 break; 01503 01504 default: 01505 /* card shouldn't be in other states so return */ 01506 return SDC_RET_ERR_STATE; 01507 } 01508 01509 return SDC_RET_OK; 01510 } 01511 01512 MCIFileSystem::ReturnCode MCIFileSystem::mci_SetBlockLength(uint32_t rca, uint32_t block_len) const 01513 { 01514 ReturnCode Ret = SDC_RET_FAILED; 01515 response_t Response; 01516 uint8_t RetryCnt = 0x20; 01517 01518 while (RetryCnt > 0) { 01519 Ret = mci_ExecuteCmd(SD_CMD16_SET_BLOCKLEN, block_len, &Response); 01520 if (Ret == SDC_RET_OK) { 01521 if (mci_CheckR1Response(Response.Data[0], &Ret)) { 01522 return Ret; 01523 } 01524 } 01525 RetryCnt--; 01526 } 01527 return SDC_RET_FAILED; 01528 } 01529 01530 MCIFileSystem::ReturnCode MCIFileSystem::mci_SetCardParams() const 01531 { 01532 ReturnCode Ret; 01533 01534 mci_SetClock(SDC_TRAN_CLOCK_RATE); 01535 if (_sdCardInfo.card_type & CARD_TYPE_SD) { 01536 mci_ClockControl(SDC_CLOCK_WIDEBUS_MODE, true); 01537 Ret = mci_SetBusWidth(_sdCardInfo.rca, ACMD6_BUS_WIDTH_4); 01538 if (Ret != SDC_RET_OK) { 01539 return Ret; 01540 } 01541 } 01542 else { 01543 mci_ClockControl(SDC_CLOCK_WIDEBUS_MODE, false); 01544 } 01545 01546 /* set block length */ 01547 Ret = mci_SetBlockLength(_sdCardInfo.rca, MMC_SECTOR_SIZE); 01548 return Ret; 01549 } 01550 01551 bool MCIFileSystem::mci_CheckR1Response(uint32_t resp, ReturnCode* pCheckResult) const 01552 { 01553 bool Ret = true; 01554 01555 if (!(resp & R1_READY_FOR_DATA)) { 01556 *pCheckResult = SDC_RET_NOT_READY; 01557 Ret = false; 01558 } 01559 else if (R1_STATUS(resp)) { 01560 *pCheckResult = SDC_RET_FAILED; 01561 } 01562 else { 01563 *pCheckResult = SDC_RET_OK; 01564 } 01565 return Ret; 01566 } 01567 01568 void MCIFileSystem::mci_WriteDelay() const 01569 { 01570 wait_us(10); 01571 } 01572 01573 MCIFileSystem::ReturnCode MCIFileSystem::mci_SendCmd(uint32_t Command, uint32_t Arg, uint32_t timeout) const 01574 { 01575 ReturnCode ret = SDC_RET_TIMEOUT; 01576 uint32_t Status; 01577 01578 /* Set Command Info */ 01579 mci_SetCommand(Command, Arg); 01580 01581 while (timeout) { 01582 01583 Status = LPC_MCI->STATUS; 01584 01585 /* check if command was sent */ 01586 if (((Command & SDC_COMMAND_RSP_BITMASK) == SDC_COMMAND_NO_RSP) && (Status & SDC_STATUS_CMDSENT)) { 01587 ret = SDC_RET_OK; 01588 break; 01589 } 01590 /* check if response was received */ 01591 if (Status & SDC_STATUS_CMDRESPEND) { 01592 ret = SDC_RET_OK; 01593 break; 01594 } 01595 01596 /* check command sending status */ 01597 if (Status & SDC_STATUS_CMDERR) { 01598 if (Status & SDC_STATUS_CMDCRCFAIL) { 01599 if ((SDC_COMMAND_INDEX(Command) == MMC_SEND_OP_COND) || 01600 (SDC_COMMAND_INDEX(Command) == SD_APP_OP_COND) || 01601 (SDC_COMMAND_INDEX(Command) == MMC_STOP_TRANSMISSION)) { 01602 ret = SDC_RET_OK; /* ignore CRC error if it's a resp for SEND_OP_COND or STOP_TRANSMISSION. */ 01603 break; 01604 } 01605 } 01606 ret = SDC_RET_CMD_FAILED; 01607 break; 01608 } 01609 01610 timeout--; 01611 } 01612 01613 mci_ResetCommand(); 01614 01615 return ret; 01616 } 01617 01618 MCIFileSystem::ReturnCode MCIFileSystem::mci_SendAppCmd(uint16_t rca) const 01619 { 01620 ReturnCode Ret = SDC_RET_FAILED; 01621 response_t Response; 01622 uint32_t RetryCnt = 20; 01623 01624 while (RetryCnt > 0) { 01625 Ret = mci_ExecuteCmd(SD_CMD55_APP_CMD, CMD55_RCA(rca), &Response); 01626 if (Ret == SDC_RET_OK) { 01627 if (mci_CheckR1Response(Response.Data[0], &Ret)) { 01628 if (Ret != SDC_RET_OK) { 01629 return Ret; 01630 } 01631 if (Response.Data[0] & R1_APP_CMD) { 01632 return SDC_RET_OK; 01633 } 01634 else { 01635 Ret = SDC_RET_FAILED; 01636 } 01637 } 01638 } 01639 RetryCnt--; 01640 } 01641 return SDC_RET_FAILED; 01642 } 01643 01644 void MCIFileSystem::mci_SetDataTransfer(uint16_t BlockNum, bool DirFromCard, uint32_t Timeout) const 01645 { 01646 uint32_t DataCtrl = 0; 01647 LPC_MCI->DATATMR = Timeout; 01648 LPC_MCI->DATALEN = BlockNum * 512; 01649 01650 DataCtrl = SDC_DATACTRL_ENABLE; 01651 // DataCtrl mode=block, block size=512byte 01652 DataCtrl |= (0x9 << 4); 01653 if (DirFromCard) { 01654 DataCtrl |= (0x1 << 1); 01655 } 01656 DataCtrl |= SDC_DATACTRL_DMA_ENABLE; 01657 LPC_MCI->DATACTRL = DataCtrl; 01658 mci_WriteDelay(); 01659 } 01660 01661 void MCIFileSystem::mci_GetResp(response_t* pResp) const 01662 { 01663 pResp->CmdIndex = SDC_RESPCOMMAND_VAL(LPC_MCI->RESP_CMD); 01664 pResp->Data[0] = LPC_MCI->RESP0; 01665 if (CardStatusNumBytes == 4) { 01666 pResp->Data[1] = LPC_MCI->RESP1; 01667 pResp->Data[2] = LPC_MCI->RESP2; 01668 pResp->Data[3] = LPC_MCI->RESP3; 01669 } 01670 } 01671 01672 uint32_t MCIFileSystem::mci_GetBits(int32_t start, int32_t end, uint32_t *data) const 01673 { 01674 uint32_t v; 01675 uint32_t i = end >> 5; 01676 uint32_t j = start & 0x1f; 01677 01678 if (i == (start >> 5)) { 01679 v = (data[i] >> j); 01680 } 01681 else { 01682 v = ((data[i] << (32 - j)) | (data[start >> 5] >> j)); 01683 } 01684 01685 return v & ((1 << (end - start + 1)) - 1); 01686 } 01687 01688 void MCIFileSystem::mci_SetCommand(uint32_t Cmd, uint32_t Arg) const 01689 { 01690 /* Clear status register */ 01691 LPC_MCI->CLEAR = SDC_CLEAR_ALL; 01692 01693 /* Set the argument first, finally command */ 01694 LPC_MCI->ARGUMENT = Arg; 01695 01696 /* Write command value, enable the command */ 01697 LPC_MCI->COMMAND = Cmd | SDC_COMMAND_ENABLE; 01698 01699 mci_WriteDelay(); 01700 } 01701 01702 void MCIFileSystem::mci_ResetCommand() const 01703 { 01704 LPC_MCI->CLEAR = SDC_CLEAR_ALL; 01705 01706 LPC_MCI->ARGUMENT = 0xFFFFFFFF; 01707 01708 LPC_MCI->COMMAND = 0; 01709 01710 mci_WriteDelay(); 01711 } 01712 01713 int32_t MCIFileSystem::mci_IRQHandler(uint8_t *txBuf, uint32_t *txCnt, uint8_t *rxBuf, uint32_t *rxCnt) 01714 { 01715 uint32_t Status; 01716 01717 Status = LPC_MCI->STATUS; 01718 01719 if ( Status & SDC_STATUS_DATAERR) { 01720 LPC_MCI->CLEAR = SDC_STATUS_DATAERR; 01721 return -1; /* Data transfer error */ 01722 } 01723 01724 if ( Status & SDC_STATUS_DATAEND) { 01725 LPC_MCI->CLEAR = SDC_STATUS_DATAEND; 01726 LPC_MCI->MASK0 = 0; 01727 return 0; 01728 } 01729 01730 if ( Status & SDC_STATUS_DATABLOCKEND) { 01731 LPC_MCI->CLEAR = SDC_STATUS_DATABLOCKEND; 01732 return 1; 01733 } 01734 01735 if (Status & SDC_STATUS_FIFO) { 01736 return mci_FIFOIRQHandler(txBuf, txCnt, rxBuf, rxCnt); 01737 } 01738 01739 return 1; 01740 } 01741 01742 int32_t MCIFileSystem::mci_FIFOIRQHandler(uint8_t *txBuf, uint32_t *txCnt, uint8_t *rxBuf, uint32_t *rxCnt) 01743 { 01744 uint32_t Status; 01745 Status = LPC_MCI->STATUS; 01746 01747 if (txBuf) { 01748 if (Status & SDC_STATUS_TXFIFOHALFEMPTY) { 01749 if (*txCnt % 64) { 01750 mci_WriteFIFO((uint32_t *) &txBuf[*txCnt], false); 01751 } 01752 else { 01753 mci_WriteFIFO((uint32_t *) &txBuf[*txCnt], true); 01754 } 01755 *txCnt += 32; 01756 } 01757 } 01758 01759 if (rxBuf) { 01760 if (Status & SDC_STATUS_RXFIFOHALFFULL) { 01761 if (*rxCnt % 64) { 01762 mci_ReadFIFO((uint32_t *) &rxBuf[*rxCnt], false); 01763 } 01764 else { 01765 mci_ReadFIFO((uint32_t *) &rxBuf[*rxCnt], true); 01766 } 01767 *rxCnt += 32; 01768 } 01769 } 01770 01771 LPC_MCI->CLEAR = SDC_STATUS_FIFO; 01772 01773 return 1; 01774 } 01775 01776 void MCIFileSystem::mci_ReadFIFO(uint32_t *pDst, bool bFirstHalf) const 01777 { 01778 uint8_t start = 0, end = 7; 01779 01780 if (!bFirstHalf) { 01781 start += 8; 01782 end += 8; 01783 } 01784 for (; start <= end; start++) { 01785 *pDst = LPC_MCI->FIFO[start]; 01786 pDst++; 01787 } 01788 } 01789 01790 void MCIFileSystem::mci_WriteFIFO(uint32_t *pSrc, bool bFirstHalf) const 01791 { 01792 uint8_t start = 0, end = 7; 01793 if (!bFirstHalf) { 01794 start += 8; 01795 end += 8; 01796 } 01797 for (; start <= end; start++) { 01798 LPC_MCI->FIFO[start] = *pSrc; 01799 pSrc++; 01800 } 01801 } 01802 01803 void MCIFileSystem::mci_SetupEventWakeup() 01804 { 01805 /* Wait for IRQ - for an RTOS, you would pend on an event here with a IRQ based wakeup. */ 01806 01807 _eventReceived = false; 01808 _eventSuccess = false; 01809 } 01810 01811 uint32_t MCIFileSystem::mci_WaitForEvent() const 01812 { 01813 /* Wait for the event (DMA or MCI interrupt) for a maximum of 2 seconds */ 01814 uint32_t end = us_ticker_read() + 2*1000*1000; 01815 while ((us_ticker_read() < end) && (!_eventReceived)) 01816 { 01817 // If the driver is having problems reading the card, adding a delay here 01818 // might help. 01819 //wait(0.01); 01820 ThisThread::sleep_for(10); 01821 } 01822 01823 if (_eventReceived && _eventSuccess) { 01824 return 0; 01825 } 01826 01827 return 1; 01828 } 01829 01830 MCIFileSystem::ReturnCode MCIFileSystem::_readBlocks(uint32_t card_type, uint32_t startBlock, uint32_t blockNum) const 01831 { 01832 ReturnCode Ret = SDC_RET_FAILED; 01833 response_t Response; 01834 uint32_t Command, Argument; 01835 uint8_t RetryCnt = 0x20; 01836 01837 if (blockNum == 1) { 01838 Command = SD_CMD17_READ_SINGLE_BLOCK; 01839 } 01840 else { 01841 Command = SD_CMD18_READ_MULTIPLE_BLOCK; 01842 } 01843 01844 /* Select single or multiple read based on number of blocks */ 01845 /* if high capacity card use block indexing */ 01846 if (card_type & CARD_TYPE_HC) { 01847 Argument = startBlock; 01848 } 01849 else { /*fix at 512 bytes*/ 01850 Argument = startBlock << 9; 01851 } 01852 01853 while (RetryCnt > 0) { 01854 Ret = mci_ExecuteCmd(Command, Argument, &Response); 01855 if (Ret == SDC_RET_OK) { 01856 if (mci_CheckR1Response(Response.Data[0], &Ret)) { 01857 return Ret; 01858 } 01859 } 01860 RetryCnt--; 01861 } 01862 return Ret; 01863 } 01864 01865 MCIFileSystem::ReturnCode MCIFileSystem::_writeBlocks(uint32_t card_type, uint32_t startBlock, uint32_t blockNum) const 01866 { 01867 ReturnCode Ret = SDC_RET_FAILED; 01868 response_t Response; 01869 uint32_t Command, Argument; 01870 uint8_t RetryCnt = 0x20; 01871 01872 if (blockNum == 1) { 01873 Command = SD_CMD24_WRITE_BLOCK; 01874 } 01875 else { 01876 Command = SD_CMD25_WRITE_MULTIPLE_BLOCK; 01877 } 01878 01879 /* if high capacity card use block indexing */ 01880 if (card_type & CARD_TYPE_HC) { 01881 Argument = startBlock; 01882 } 01883 else { /*fix at 512 bytes*/ 01884 Argument = startBlock << 9; 01885 01886 } 01887 01888 while (RetryCnt > 0) { 01889 Ret = mci_ExecuteCmd(Command, Argument, &Response); 01890 if (Ret == SDC_RET_OK) { 01891 if (mci_CheckR1Response(Response.Data[0], &Ret)) { 01892 return Ret; 01893 } 01894 } 01895 RetryCnt--; 01896 } 01897 return Ret; 01898 }
Generated on Tue Jul 12 2022 14:18:31 by
![doxygen](doxygen.png)