A library with drivers for different peripherals on the LPC4088 QuickStart Board or related add-on boards.
Fork of EALib by
MCIFileSystem.cpp
00001 /* 00002 * Copyright 2013 Embedded Artists AB 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 /****************************************************************************** 00018 * Includes 00019 *****************************************************************************/ 00020 00021 #include "MCIFileSystem.h" 00022 #include "mbed_debug.h" 00023 00024 #include "diskio.h" //STA_* defines 00025 #include "gpdma.h" 00026 #include "us_ticker_api.h" 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 (0.100f) /*!< inter-command acquire oper condition delay in seconds */ 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 GPDMA controller */ 00646 gpdma_init(); 00647 00648 /* Initialize SDC peripheral */ 00649 LPC_SC->PCONP |= SYSCTL_CLOCK_SDC; 00650 00651 /* Disable SD_CLK */ 00652 mci_ClockControl(SDC_CLOCK_ENABLE, false); 00653 00654 /* Power-off */ 00655 mci_PowerControl(PowerOff, 0); 00656 mci_WriteDelay(); 00657 00658 /* Disable all interrupts */ 00659 LPC_MCI->MASK0 = 0; 00660 00661 /*Setting for timeout problem */ 00662 LPC_MCI->DATATMR = 0x1FFFFFFF; 00663 00664 LPC_MCI->COMMAND = 0; 00665 mci_WriteDelay(); 00666 00667 LPC_MCI->DATACTRL = 0; 00668 mci_WriteDelay(); 00669 00670 /* clear all pending interrupts */ 00671 LPC_MCI->CLEAR = SDC_CLEAR_ALL; 00672 00673 /* Power-up SDC Peripheral */ 00674 mci_PowerControl(PowerUp, 0); 00675 00676 /* delays for the supply output is stable*/ 00677 for (uint32_t i = 0; i < 0x80000; i++ ) {} 00678 00679 mci_SetClock(SDC_IDENT_CLOCK_RATE); 00680 mci_ClockControl(SDC_CLOCK_ENABLE, true); 00681 00682 /* Power-on SDC Interface */ 00683 mci_PowerControl(PowerOn, 0); 00684 00685 NVIC_SetVector(MCI_IRQn, (uint32_t) mymciirq); 00686 NVIC_EnableIRQ(MCI_IRQn); 00687 00688 NVIC_SetVector(DMA_IRQn, (uint32_t) mydmairq); 00689 NVIC_EnableIRQ(DMA_IRQn); 00690 } 00691 00692 int MCIFileSystem::disk_initialize() { 00693 00694 debug_if(MCI_DBG, "mcifs:disk_initialize(), _Stat = %#x\n", _Stat); 00695 00696 if (!cardInserted()) { 00697 /* No card in the socket */ 00698 _Stat = STA_NODISK | STA_NOINIT; 00699 } 00700 00701 if (_Stat != STA_NOINIT) { 00702 return _Stat; /* card is already enumerated */ 00703 } 00704 00705 //rtc_init(); 00706 00707 /* Initialize the Card Data Strucutre */ 00708 memset(&_sdCardInfo, 0, sizeof(SDMMC_CARD_T)); 00709 00710 /* Reset */ 00711 _Stat = STA_NOINIT; 00712 00713 /* Enumerate the card once detected. Note this function may block for a little while. */ 00714 int ret = mci_Acquire(); 00715 if (ret != 1) { 00716 debug("Card Acquire failed... got %d, but expected 1\r\n", ret); 00717 return 1;//Stat; 00718 } 00719 00720 _Stat &= ~STA_NOINIT; 00721 return _Stat; 00722 } 00723 00724 int MCIFileSystem::disk_write(const uint8_t *buffer, uint64_t block_number) { 00725 debug_if(MCI_DBG, "mcifs:disk_write(%#x, %llu), _Stat = %#x\n", (uint32_t)buffer, block_number, _Stat); 00726 if (_Stat & STA_NOINIT) { 00727 // not ready 00728 return 1; 00729 } 00730 if (mci_WriteBlocks((void*)buffer, block_number, 1) == SDC_RET_OK) { 00731 return 0; 00732 } 00733 00734 return 1; 00735 } 00736 00737 int MCIFileSystem::disk_read(uint8_t *buffer, uint64_t block_number) { 00738 debug_if(MCI_DBG, "mcifs:disk_read(%#x, %llu), _Stat = %#x\n", (uint32_t)buffer, block_number, _Stat); 00739 if (_Stat & STA_NOINIT) { 00740 // not ready 00741 return _Stat; 00742 } 00743 if (mci_ReadBlocks(buffer, block_number, 1) == SDC_RET_OK) { 00744 return 0; 00745 } 00746 00747 return 1; 00748 } 00749 00750 int MCIFileSystem::disk_status() 00751 { 00752 debug_if(MCI_DBG, "mcifs:disk_status(), _Stat = %#x\n", _Stat); 00753 return _Stat; 00754 } 00755 00756 int MCIFileSystem::disk_sync() 00757 { 00758 debug_if(MCI_DBG, "mcifs:disk_sync(), _Stat = %#x\n", _Stat); 00759 uint32_t end = us_ticker_read() + 50*1000; // 50ms 00760 while (us_ticker_read() < end) 00761 { 00762 if (mci_GetCardStatus() & R1_READY_FOR_DATA) 00763 { 00764 // card is ready 00765 return 0; 00766 } 00767 } 00768 // timeout while waiting for card to get ready 00769 return 1; 00770 } 00771 00772 uint64_t MCIFileSystem::disk_sectors() 00773 { 00774 debug_if(MCI_DBG, "mcifs:disk_sectors(), _Stat = %#x, returning %llu\n", _Stat, _sdCardInfo.blocknr); 00775 return _sdCardInfo.blocknr; 00776 } 00777 00778 void MCIFileSystem::mci_MCIIRQHandler() 00779 { 00780 int32_t Ret; 00781 00782 Ret = mci_IRQHandler(NULL, 0, NULL, 0); 00783 if(Ret < 0) { 00784 _eventSuccess = false; 00785 _eventReceived = true; 00786 } 00787 } 00788 00789 void MCIFileSystem::mci_DMAIRQHandler() 00790 { 00791 _eventSuccess = gpdma_interrupt(_eventDmaChannel); 00792 _eventReceived = true; 00793 NVIC_DisableIRQ(DMA_IRQn); 00794 } 00795 00796 /****************************************************************************** 00797 * Private Functions 00798 *****************************************************************************/ 00799 00800 bool MCIFileSystem::cardInserted() const 00801 { 00802 // If no card detect pin is given, then assume that a card is inserted. 00803 // If a pin is specified then use that to determing the presence of a card. 00804 return ((_cardDetect == NULL) || (_cardDetect->read() == 0)); 00805 } 00806 00807 00808 00809 int32_t MCIFileSystem::mci_Acquire() 00810 { 00811 int32_t Ret; 00812 00813 /* Initialize card info */ 00814 _sdCardInfo.speed = SDC_TRAN_CLOCK_RATE; 00815 _sdCardInfo.card_type = 0; 00816 00817 /* During identification phase, the clock should be less than 00818 400Khz. Once we pass this phase, the normal clock can be set up 00819 to 25Mhz on SD card and 20Mhz on MMC card. */ 00820 mci_SetClock(SDC_IDENT_CLOCK_RATE); 00821 00822 /* Clear Open Drain output control for SD */ 00823 mci_PowerControl(PowerOn, 0); 00824 00825 /* Card Reset */ 00826 Ret = mci_ExecuteCmd(SD_GO_IDLE_STATE, 0, NULL); 00827 if (Ret != 0) { 00828 return Ret; 00829 } 00830 00831 wait(ACQUIRE_DELAY); 00832 00833 /* Send interface operation condiftion */ 00834 Ret = mci_SendIfCond(); 00835 if (Ret == SDC_RET_BAD_PARAMETERS) { 00836 return Ret; /* Non-compatible voltage range or check pattern is not correct */ 00837 00838 } 00839 /* Get Card Type */ 00840 if (Ret == SDC_RET_OK) {/* Ver2.00 or later SD Memory Card*/ 00841 bool CCS; 00842 uint32_t OCR = SDC_OCR_27_36; 00843 _sdCardInfo.card_type |= CARD_TYPE_SD; 00844 Ret = mci_SendAppOpCond(0, true, &OCR, &CCS); 00845 if (CCS) { /* High Capacity or Extended Capacity SD Memory Card */ 00846 _sdCardInfo.card_type |= CARD_TYPE_HC; 00847 } 00848 } 00849 else { /*Ver2.00 or later SD Memory Card(voltage mismatch) or Ver1.X SD Memory Card 00850 or not SD Memory Card*/ 00851 bool CCS; 00852 uint32_t OCR = SDC_OCR_27_36; 00853 Ret = mci_SendAppOpCond(0, false, &OCR, &CCS); 00854 if (Ret == SDC_RET_OK) { 00855 _sdCardInfo.card_type |= CARD_TYPE_SD; 00856 } 00857 else if (Ret == SDC_RET_BAD_PARAMETERS) { 00858 return Ret; 00859 } 00860 else { /* MMC Card setup */ 00861 uint32_t OCR; 00862 /* Enter to Open Drain mode */ 00863 mci_PowerControl(PowerOn, SDC_PWR_OPENDRAIN); 00864 wait(ACQUIRE_DELAY); 00865 Ret = mci_SendOpCond(&OCR); 00866 if (Ret != SDC_RET_OK) { 00867 return Ret; 00868 } 00869 00870 } 00871 } 00872 00873 /* Read CID */ 00874 mci_GetCID(_sdCardInfo.cid); 00875 00876 /* RCA send, for SD get RCA */ 00877 if (_sdCardInfo.card_type & CARD_TYPE_SD) { 00878 mci_GetAddr(&_sdCardInfo.rca); 00879 } 00880 else { 00881 _sdCardInfo.rca = 1; 00882 mci_SetAddr(_sdCardInfo.rca); 00883 mci_PowerControl(PowerOn, 0); /* enter to push-pull mode */ 00884 } 00885 00886 /* Get CSD */ 00887 mci_GetCSD(_sdCardInfo.rca, _sdCardInfo.csd); 00888 00889 /* Compute card size, block size and no. of blocks based on CSD response recived. */ 00890 if (_sdCardInfo.cid[0]) { 00891 mci_ProcessCSD(); 00892 00893 if (mci_SetTranState(_sdCardInfo.rca) != SDC_RET_OK) { 00894 return 0; 00895 } 00896 00897 if (mci_GetCardState() != SDMMC_TRAN_ST) { 00898 return 0; 00899 } 00900 00901 if (mci_SetCardParams() != 0) { 00902 return 0; 00903 } 00904 } 00905 00906 return (_sdCardInfo.cid[0]) ? 1 : 0; 00907 } 00908 00909 uint32_t MCIFileSystem::mci_GetCardStatus() const 00910 { 00911 uint32_t Status; 00912 mci_GetStatus(_sdCardInfo.rca, &Status); 00913 return Status; 00914 } 00915 00916 MCIFileSystem::CardState MCIFileSystem::mci_GetCardState() const 00917 { 00918 uint32_t Status; 00919 volatile int32_t Ret; 00920 00921 /* get current state of the card */ 00922 Ret = mci_GetStatus(_sdCardInfo.rca, &Status); 00923 00924 /* check card state in response */ 00925 return (CardState) R1_CURRENT_STATE(Status); 00926 } 00927 00928 MCIFileSystem::ReturnCode MCIFileSystem::mci_StopTransmission(uint32_t rca) const 00929 { 00930 uint32_t Status; 00931 ReturnCode Ret = SDC_RET_FAILED; 00932 response_t Response; 00933 uint32_t RetryCnt = 20; 00934 00935 Ret = mci_GetStatus(rca, &Status); 00936 if (Ret != SDC_RET_OK) { 00937 return SDC_RET_ERR_STATE; 00938 } 00939 00940 if (R1_CURRENT_STATE(Status) == SDMMC_TRAN_ST) { 00941 return SDC_RET_OK; 00942 } 00943 00944 if ((R1_CURRENT_STATE(Status) != SDMMC_DATA_ST) && 00945 (R1_CURRENT_STATE(Status) != SDMMC_RCV_ST)) { 00946 return SDC_RET_ERR_STATE; 00947 } 00948 00949 while (RetryCnt > 0) { 00950 Ret = mci_ExecuteCmd(SD_CMD12_STOP_TRANSMISSION, 0, &Response); 00951 if (Ret == SDC_RET_OK) { 00952 if (mci_CheckR1Response(Response.Data[0], &Ret)) { 00953 if (Ret != SDC_RET_OK) { 00954 return Ret; 00955 } 00956 Ret = mci_GetStatus(rca, &Status); 00957 if ((R1_CURRENT_STATE(Status) == SDMMC_TRAN_ST) || (R1_CURRENT_STATE(Status) == SDMMC_PRG_ST)) { 00958 return SDC_RET_OK; 00959 } 00960 return SDC_RET_ERR_STATE; 00961 } 00962 } 00963 RetryCnt--; 00964 } 00965 return Ret; 00966 } 00967 00968 MCIFileSystem::ReturnCode MCIFileSystem::mci_ReadBlocks(void *buffer, int32_t startBlock, int32_t blockNum) 00969 { 00970 ReturnCode Ret = SDC_RET_FAILED; 00971 uint8_t dmaChannel; 00972 int32_t ByteNum = blockNum * MMC_SECTOR_SIZE; 00973 00974 do 00975 { 00976 /* if card is not acquired return immediately */ 00977 if (( startBlock < 0) || ( (startBlock + blockNum) > _sdCardInfo.blocknr) ) { 00978 Ret = SDC_RET_NOT_READY; 00979 break; 00980 } 00981 00982 /* Put to tran state */ 00983 Ret = mci_SetTranState(_sdCardInfo.rca); 00984 if (Ret != SDC_RET_OK) { 00985 break; 00986 } 00987 00988 LPC_MCI->MASK0 = SDC_MASK0_DATA | SDC_MASK0_RXDATAERR; 00989 00990 /* DMA Setup */ 00991 gpdma_getFreeChannel(&dmaChannel); 00992 gpdma_transfer_from_mci(dmaChannel, (uint32_t)buffer, ByteNum); 00993 mci_SetupEventWakeup(dmaChannel); 00994 00995 /* set transfer information */ 00996 mci_SetDataTransfer(blockNum, true, DATA_TIMER_VALUE_R); 00997 00998 Ret = _readBlocks(_sdCardInfo.card_type, startBlock, blockNum); 00999 if (Ret == SDC_RET_OK) { 01000 /* Wait for transfer Finish */ 01001 if (mci_WaitForEvent() != 0) { 01002 Ret = SDC_RET_FAILED; 01003 } 01004 } else { 01005 Ret = SDC_RET_FAILED; 01006 } 01007 01008 gpdma_stop(dmaChannel); 01009 01010 if ((blockNum > 1) || (mci_GetCardState() == SDMMC_DATA_ST)) { 01011 /* Send Stop transmission command */ 01012 mci_StopTransmission(_sdCardInfo.rca); 01013 } 01014 01015 /* Wait for card to enter tran state */ 01016 while (mci_GetCardState() != SDMMC_TRAN_ST) {} 01017 01018 } while(false); 01019 01020 return Ret; 01021 } 01022 01023 MCIFileSystem::ReturnCode MCIFileSystem::mci_WriteBlocks(void *buffer, int32_t startBlock, int32_t blockNum) 01024 { 01025 ReturnCode Ret = SDC_RET_FAILED; 01026 uint8_t dmaChannel; 01027 01028 do 01029 { 01030 /* if card is not acquired return immediately */ 01031 if (( startBlock < 0) || ( (startBlock + blockNum) > _sdCardInfo.blocknr) ) { 01032 Ret = SDC_RET_NOT_READY; 01033 break; 01034 } 01035 01036 /* Put to tran state */ 01037 Ret = mci_SetTranState(_sdCardInfo.rca); 01038 if (Ret != SDC_RET_OK) { 01039 break; 01040 } 01041 01042 Ret = _writeBlocks(_sdCardInfo.card_type, startBlock, blockNum); 01043 if (Ret != SDC_RET_OK) { 01044 break; 01045 } 01046 01047 /*Wait for card enter to rcv state*/ 01048 while (mci_GetCardState() != SDMMC_RCV_ST) {} 01049 01050 LPC_MCI->MASK0 = SDC_MASK0_DATA | SDC_MASK0_TXDATAERR; 01051 01052 /* DMA Setup */ 01053 gpdma_getFreeChannel(&dmaChannel); 01054 gpdma_transfer_to_mci(dmaChannel, (uint32_t)buffer, blockNum*MMC_SECTOR_SIZE); 01055 mci_SetupEventWakeup(dmaChannel); 01056 01057 /* set transfer information */ 01058 mci_SetDataTransfer(blockNum, false, DATA_TIMER_VALUE_W); 01059 01060 /* Wait for transfer done */ 01061 if (mci_WaitForEvent() != 0) { 01062 Ret = SDC_RET_FAILED; 01063 } 01064 gpdma_stop(dmaChannel); 01065 01066 if ((blockNum > 1) || (mci_GetCardState() == SDMMC_RCV_ST)) { 01067 /* Send Stop transmission command */ 01068 mci_StopTransmission(_sdCardInfo.rca); 01069 } 01070 01071 /* Wait for card to enter tran state */ 01072 while (mci_GetCardState() != SDMMC_TRAN_ST) {} 01073 01074 } while (false); 01075 01076 return Ret; 01077 } 01078 01079 void MCIFileSystem::mci_SetClock(uint32_t freq) const 01080 { 01081 uint32_t PClk; 01082 uint32_t ClkValue = 0; 01083 01084 PClk = PeripheralClock; 01085 01086 ClkValue = (PClk + 2 * freq - 1) / (2 * freq); 01087 if (ClkValue > 0) { 01088 ClkValue -= 1; 01089 } 01090 uint32_t temp; 01091 temp = (LPC_MCI->CLOCK & (~SDC_CLOCK_CLKDIV_BITMASK)); 01092 LPC_MCI->CLOCK = temp | (SDC_CLOCK_CLKDIV(ClkValue)); 01093 mci_WriteDelay(); 01094 } 01095 01096 void MCIFileSystem::mci_ClockControl(ClockControl ctrlType, bool enable) const 01097 { 01098 if (enable) { 01099 LPC_MCI->CLOCK |= (1 << ctrlType); 01100 } 01101 else { 01102 LPC_MCI->CLOCK &= (~(1 << ctrlType)); 01103 } 01104 mci_WriteDelay(); 01105 } 01106 01107 void MCIFileSystem::mci_PowerControl(power_ctrl_t powerMode, uint32_t flag) const 01108 { 01109 LPC_MCI->POWER = (powerMode & 0x3) | flag; 01110 mci_WriteDelay(); 01111 } 01112 01113 MCIFileSystem::ReturnCode MCIFileSystem::mci_ExecuteCmd(uint32_t Command, uint32_t Arg, response_t* pResp) const 01114 { 01115 ReturnCode Ret = SDC_RET_FAILED; 01116 01117 /* Send Command to card */ 01118 Ret = mci_SendCmd(Command, Arg, CMD_TIMEOUT); 01119 if (Ret != SDC_RET_OK) { 01120 return Ret; 01121 } 01122 01123 /* Get response (if any) */ 01124 if ((Command & SDC_COMMAND_RSP_BITMASK) != SDC_COMMAND_NO_RSP) { 01125 01126 mci_GetResp(pResp); 01127 01128 /* If the response is not R1, in the response field, the Expected Cmd data 01129 won't be the same as the CMD data in SendCmd(). Below four cmds have 01130 R2 or R3 response. We don't need to check if MCI_RESP_CMD is the same 01131 as the Expected or not. */ 01132 if ((SDC_COMMAND_INDEX(Command) != MMC_SEND_OP_COND) && 01133 (SDC_COMMAND_INDEX(Command) != SD_APP_OP_COND) && 01134 (SDC_COMMAND_INDEX(Command) != MMC_ALL_SEND_CID) && 01135 (SDC_COMMAND_INDEX(Command) != MMC_SEND_CSD) && 01136 (pResp->CmdIndex != SDC_COMMAND_INDEX(Command))) { 01137 return SDC_RET_CMD_FAILED; 01138 } 01139 } 01140 01141 return SDC_RET_OK; 01142 } 01143 01144 MCIFileSystem::ReturnCode MCIFileSystem::mci_SendIfCond() const 01145 { 01146 ReturnCode Ret = SDC_RET_FAILED; 01147 response_t Response; 01148 uint32_t RetryCnt = 20; 01149 01150 while (RetryCnt > 0) { 01151 Ret = mci_ExecuteCmd(SD_CMD8_SEND_IF_COND, (CMD8_VOLTAGESUPPLIED_27_36 | CMD8_CHECKPATTERN( 01152 CMD8_DEF_PATTERN)), &Response); 01153 if (Ret == SDC_RET_OK) { 01154 if ((Response.Data[0] & CMDRESP_R7_VOLTAGE_ACCEPTED) && 01155 (CMDRESP_R7_CHECK_PATTERN(Response.Data[0]) == CMD8_DEF_PATTERN)) { 01156 return SDC_RET_OK; 01157 } 01158 return SDC_RET_BAD_PARAMETERS; 01159 } 01160 RetryCnt--; 01161 } 01162 return Ret; 01163 } 01164 01165 MCIFileSystem::ReturnCode MCIFileSystem::mci_SendOpCond(uint32_t *pOCR) const 01166 { 01167 ReturnCode Ret = SDC_RET_FAILED; 01168 response_t Response; 01169 uint32_t RetryCnt = 0x200; 01170 01171 while (RetryCnt > 0) { 01172 Ret = mci_ExecuteCmd(SD_CMD1_SEND_OP_COND, SDC_OCR_27_36, &Response); 01173 if (Ret == SDC_RET_OK) { 01174 *pOCR = Response.Data[0]; 01175 if (*pOCR & SDC_OCR_IDLE) { 01176 if ((Response.Data[0] & SDC_OCR_27_36) != SDC_OCR_27_36) { 01177 return SDC_RET_BAD_PARAMETERS; 01178 } 01179 return SDC_RET_OK; 01180 } 01181 } 01182 RetryCnt--; 01183 } 01184 return SDC_RET_FAILED; 01185 } 01186 01187 MCIFileSystem::ReturnCode MCIFileSystem::mci_SendAppOpCond(uint16_t rca, bool hcs, uint32_t *pOcr, bool *pCCS) const 01188 { 01189 ReturnCode Ret = SDC_RET_FAILED; 01190 response_t Response; 01191 uint32_t Argument; 01192 uint32_t RetryCnt = 0x2000; /* The host repeatedly issues ACMD41 for at least 1 second or 01193 until the busy bit are set to 1 */ 01194 01195 Argument = ACMD41_OCR(*pOcr); 01196 if (hcs) { 01197 Argument |= ACMD41_HCS; 01198 } 01199 01200 while (RetryCnt > 0) { 01201 Ret = mci_SendAppCmd(rca); 01202 if (Ret == SDC_RET_OK) { 01203 Ret = mci_ExecuteCmd(SD_ACMD41_SD_SEND_OP_COND, Argument, &Response); 01204 if (Ret == SDC_RET_OK) { 01205 if (Response.Data[0] & CMDRESP_R3_INIT_COMPLETE) { 01206 if (*pOcr == 0) { 01207 *pOcr = CMDRESP_R3_OCR_VAL(Response.Data[0]); 01208 return SDC_RET_OK; 01209 } 01210 if ((CMDRESP_R3_OCR_VAL(Response.Data[0]) & *pOcr) != *pOcr) { 01211 return SDC_RET_BAD_PARAMETERS; 01212 } 01213 *pCCS = (Response.Data[0] & CMDRESP_R3_HC_CCS) ? true : false; 01214 return SDC_RET_OK; 01215 } 01216 } 01217 } 01218 else { 01219 //If we abort here then some cards will go undetected, better to keep retrying 01220 //return Ret; 01221 } 01222 RetryCnt--; 01223 } 01224 return SDC_RET_FAILED; 01225 } 01226 01227 MCIFileSystem::ReturnCode MCIFileSystem::mci_GetCID(uint32_t *pCID) const 01228 { 01229 ReturnCode Ret = SDC_RET_FAILED; 01230 response_t Response; 01231 uint32_t RetryCnt = 20; 01232 01233 while (RetryCnt > 0) { 01234 Ret = mci_ExecuteCmd(SD_CMD2_ALL_SEND_CID, 0, &Response); 01235 if (Ret == SDC_RET_OK) { 01236 pCID[3] = Response.Data[0]; 01237 pCID[2] = Response.Data[1]; 01238 pCID[1] = Response.Data[2]; 01239 pCID[0] = Response.Data[3]; 01240 return SDC_RET_OK; 01241 } 01242 RetryCnt--; 01243 } 01244 return Ret; 01245 } 01246 01247 MCIFileSystem::ReturnCode MCIFileSystem::mci_SetAddr(uint16_t addr) const 01248 { 01249 ReturnCode Ret = SDC_RET_FAILED; 01250 response_t Response; 01251 uint32_t RetryCnt = 20; 01252 01253 while (RetryCnt > 0) { 01254 Ret = mci_ExecuteCmd(SD_CMD3_SET_RELATIVE_ADDR, CMD3_RCA(addr), &Response); 01255 if (Ret == SDC_RET_OK) { 01256 if (mci_CheckR1Response(Response.Data[0], &Ret)) { 01257 return Ret; 01258 } 01259 } 01260 RetryCnt--; 01261 } 01262 return Ret; 01263 } 01264 01265 MCIFileSystem::ReturnCode MCIFileSystem::mci_GetAddr(uint16_t *pRCA) const 01266 { 01267 ReturnCode Ret = SDC_RET_FAILED; 01268 response_t Response; 01269 uint32_t RetryCnt = 20; 01270 01271 *pRCA = 0; 01272 while (RetryCnt > 0) { 01273 Ret = mci_ExecuteCmd(SD_CMD3_SEND_RELATIVE_ADDR, 0, &Response); 01274 if (Ret == SDC_RET_OK) { 01275 if (!(CMDRESP_R6_CARD_STATUS(Response.Data[0]) & R1_READY_FOR_DATA)) { 01276 Ret = SDC_RET_NOT_READY; 01277 } 01278 else if (R1_CURRENT_STATE(CMDRESP_R6_CARD_STATUS(Response.Data[0])) != SDMMC_STBY_ST) { 01279 Ret = SDC_RET_ERR_STATE; 01280 } 01281 else { 01282 *pRCA = CMDRESP_R6_RCA_VAL(Response.Data[0]); 01283 return SDC_RET_OK; 01284 } 01285 } 01286 RetryCnt--; 01287 } 01288 return Ret; 01289 } 01290 01291 MCIFileSystem::ReturnCode MCIFileSystem::mci_GetCSD(uint16_t rca, uint32_t *pCSD) const 01292 { 01293 ReturnCode Ret = SDC_RET_FAILED; 01294 response_t Response; 01295 uint32_t RetryCnt = 20; 01296 01297 while (RetryCnt > 0) { 01298 Ret = mci_ExecuteCmd(SD_CMD9_SEND_CSD, CMD9_RCA(rca), &Response); 01299 if (Ret == SDC_RET_OK) { 01300 pCSD[3] = Response.Data[0]; 01301 pCSD[2] = Response.Data[1]; 01302 pCSD[1] = Response.Data[2]; 01303 pCSD[0] = Response.Data[3]; 01304 return Ret; 01305 } 01306 RetryCnt--; 01307 } 01308 return Ret; 01309 } 01310 01311 MCIFileSystem::ReturnCode MCIFileSystem::mci_SelectCard(uint16_t addr) const 01312 { 01313 ReturnCode Ret = SDC_RET_FAILED; 01314 response_t Response; 01315 uint32_t RetryCnt = 20; 01316 01317 while (RetryCnt > 0) { 01318 Ret = mci_ExecuteCmd(SD_CMD7_SELECT_CARD, CMD7_RCA(addr), &Response); 01319 if (Ret == SDC_RET_OK) { 01320 if (mci_CheckR1Response(Response.Data[0], &Ret)) { 01321 return Ret; 01322 } 01323 } 01324 RetryCnt--; 01325 } 01326 return Ret; 01327 } 01328 01329 MCIFileSystem::ReturnCode MCIFileSystem::mci_GetStatus(uint16_t rca, uint32_t *pStatus) const 01330 { 01331 ReturnCode Ret = SDC_RET_FAILED; 01332 response_t Response; 01333 uint32_t RetryCnt = 20; 01334 01335 *pStatus = (uint32_t) -1; 01336 while (RetryCnt > 0) { 01337 Ret = mci_ExecuteCmd(SD_CMD13_SEND_STATUS, CMD13_RCA(rca), &Response); 01338 if (Ret == SDC_RET_OK) { 01339 mci_CheckR1Response(Response.Data[0], &Ret); 01340 *pStatus = Response.Data[0]; 01341 return Ret; 01342 } 01343 RetryCnt--; 01344 } 01345 return Ret; 01346 } 01347 01348 void MCIFileSystem::mci_ProcessCSD() 01349 { 01350 int32_t CSize = 0; 01351 int32_t CSizeMult = 0; 01352 int32_t Mult = 0; 01353 01354 /* compute block length based on CSD response */ 01355 _sdCardInfo.block_len = 1 << mci_GetBits(80, 83, _sdCardInfo.csd); 01356 01357 if ((_sdCardInfo.card_type & CARD_TYPE_HC) && (_sdCardInfo.card_type & CARD_TYPE_SD)) { 01358 /* See section 5.3.3 CSD Register (CSD Version 2.0) of SD2.0 spec an explanation for the calculation of these values */ 01359 CSize = mci_GetBits(48, 63, (uint32_t *) _sdCardInfo.csd) + 1; 01360 _sdCardInfo.blocknr = CSize << 10; /* 512 byte blocks */ 01361 } 01362 else { 01363 /* See section 5.3 of the 4.1 revision of the MMC specs for an explanation for the calculation of these values */ 01364 CSize = mci_GetBits(62, 73, (uint32_t *) _sdCardInfo.csd); 01365 CSizeMult = mci_GetBits(47, 49, (uint32_t *) _sdCardInfo.csd); 01366 Mult = 1 << (CSizeMult + 2); 01367 _sdCardInfo.blocknr = (CSize + 1) * Mult; 01368 01369 /* adjust blocknr to 512/block */ 01370 if (_sdCardInfo.block_len > MMC_SECTOR_SIZE) { 01371 _sdCardInfo.blocknr = _sdCardInfo.blocknr * (_sdCardInfo.block_len >> 9); 01372 } 01373 } 01374 01375 _sdCardInfo.device_size = _sdCardInfo.blocknr << 9; /* blocknr * 512 */ 01376 } 01377 01378 MCIFileSystem::ReturnCode MCIFileSystem::mci_SetBusWidth(uint16_t rca, uint8_t width) const 01379 { 01380 ReturnCode Ret = SDC_RET_FAILED; 01381 response_t Response; 01382 uint8_t RetryCnt = 0x20; 01383 01384 while (RetryCnt > 0) { 01385 Ret = mci_SendAppCmd(rca); 01386 if (Ret == SDC_RET_OK) { 01387 Ret = mci_ExecuteCmd(SD_ACMD6_SET_BUS_WIDTH, ACMD6_BUS_WIDTH(width), &Response); 01388 if (Ret == SDC_RET_OK) { 01389 if (mci_CheckR1Response(Response.Data[0], &Ret)) { 01390 return Ret; 01391 } 01392 } 01393 } 01394 RetryCnt--; 01395 } 01396 return SDC_RET_FAILED; 01397 } 01398 01399 MCIFileSystem::ReturnCode MCIFileSystem::mci_SetTranState(uint16_t rca) const 01400 { 01401 ReturnCode Ret = SDC_RET_OK; 01402 uint32_t status = 0; 01403 SDMMC_STATE_T state; 01404 01405 /* get current state of the card */ 01406 Ret = mci_GetStatus(rca, &status); 01407 if (Ret != SDC_RET_OK) { 01408 /* unable to get the card state. So return immediatly. */ 01409 return Ret; 01410 } 01411 01412 /* check card state in response */ 01413 state = (SDMMC_STATE_T) R1_CURRENT_STATE(status); 01414 switch (state) { 01415 case SDMMC_STBY_ST: 01416 /* put card in 'Trans' state */ 01417 Ret = mci_SelectCard(rca); 01418 if (Ret != SDC_RET_OK) { 01419 /* unable to put the card in Trans state. So return immediatly. */ 01420 return Ret; 01421 } 01422 mci_GetStatus(rca, &status); 01423 if (((SDMMC_STATE_T) R1_CURRENT_STATE(status)) != SDMMC_TRAN_ST) { 01424 return SDC_RET_ERR_STATE; 01425 } 01426 break; 01427 01428 case SDMMC_TRAN_ST: 01429 /*do nothing */ 01430 break; 01431 01432 default: 01433 /* card shouldn't be in other states so return */ 01434 return SDC_RET_ERR_STATE; 01435 } 01436 01437 return SDC_RET_OK; 01438 } 01439 01440 MCIFileSystem::ReturnCode MCIFileSystem::mci_SetBlockLength(uint32_t rca, uint32_t block_len) const 01441 { 01442 ReturnCode Ret = SDC_RET_FAILED; 01443 response_t Response; 01444 uint8_t RetryCnt = 0x20; 01445 01446 while (RetryCnt > 0) { 01447 Ret = mci_ExecuteCmd(SD_CMD16_SET_BLOCKLEN, block_len, &Response); 01448 if (Ret == SDC_RET_OK) { 01449 if (mci_CheckR1Response(Response.Data[0], &Ret)) { 01450 return Ret; 01451 } 01452 } 01453 RetryCnt--; 01454 } 01455 return SDC_RET_FAILED; 01456 } 01457 01458 MCIFileSystem::ReturnCode MCIFileSystem::mci_SetCardParams() const 01459 { 01460 ReturnCode Ret; 01461 01462 mci_SetClock(SDC_TRAN_CLOCK_RATE); 01463 if (_sdCardInfo.card_type & CARD_TYPE_SD) { 01464 mci_ClockControl(SDC_CLOCK_WIDEBUS_MODE, true); 01465 Ret = mci_SetBusWidth(_sdCardInfo.rca, ACMD6_BUS_WIDTH_4); 01466 if (Ret != SDC_RET_OK) { 01467 return Ret; 01468 } 01469 } 01470 else { 01471 mci_ClockControl(SDC_CLOCK_WIDEBUS_MODE, false); 01472 } 01473 01474 /* set block length */ 01475 Ret = mci_SetBlockLength(_sdCardInfo.rca, MMC_SECTOR_SIZE); 01476 return Ret; 01477 } 01478 01479 bool MCIFileSystem::mci_CheckR1Response(uint32_t resp, ReturnCode* pCheckResult) const 01480 { 01481 bool Ret = true; 01482 01483 if (!(resp & R1_READY_FOR_DATA)) { 01484 *pCheckResult = SDC_RET_NOT_READY; 01485 Ret = false; 01486 } 01487 else if (R1_STATUS(resp)) { 01488 *pCheckResult = SDC_RET_FAILED; 01489 } 01490 else { 01491 *pCheckResult = SDC_RET_OK; 01492 } 01493 return Ret; 01494 } 01495 01496 void MCIFileSystem::mci_WriteDelay() const 01497 { 01498 // volatile uint8_t i; 01499 // for ( i = 0; i < 0x10; i++ ) { /* delay 3MCLK + 2PCLK */ 01500 // } 01501 wait(0.00001f); /* delay 10 us */ 01502 } 01503 01504 MCIFileSystem::ReturnCode MCIFileSystem::mci_SendCmd(uint32_t Command, uint32_t Arg, uint32_t timeout) const 01505 { 01506 ReturnCode ret = SDC_RET_TIMEOUT; 01507 uint32_t Status; 01508 01509 /* Set Command Info */ 01510 mci_SetCommand(Command, Arg); 01511 01512 while (timeout) { 01513 01514 Status = LPC_MCI->STATUS; 01515 01516 /* check if command was sent */ 01517 if (((Command & SDC_COMMAND_RSP_BITMASK) == SDC_COMMAND_NO_RSP) && (Status & SDC_STATUS_CMDSENT)) { 01518 ret = SDC_RET_OK; 01519 break; 01520 } 01521 /* check if response was received */ 01522 if (Status & SDC_STATUS_CMDRESPEND) { 01523 ret = SDC_RET_OK; 01524 break; 01525 } 01526 01527 /* check command sending status */ 01528 if (Status & SDC_STATUS_CMDERR) { 01529 if (Status & SDC_STATUS_CMDCRCFAIL) { 01530 if ((SDC_COMMAND_INDEX(Command) == MMC_SEND_OP_COND) || 01531 (SDC_COMMAND_INDEX(Command) == SD_APP_OP_COND) || 01532 (SDC_COMMAND_INDEX(Command) == MMC_STOP_TRANSMISSION)) { 01533 ret = SDC_RET_OK; /* ignore CRC error if it's a resp for SEND_OP_COND or STOP_TRANSMISSION. */ 01534 break; 01535 } 01536 } 01537 ret = SDC_RET_CMD_FAILED; 01538 break; 01539 } 01540 01541 timeout--; 01542 } 01543 01544 mci_ResetCommand(); 01545 01546 return ret; 01547 } 01548 01549 MCIFileSystem::ReturnCode MCIFileSystem::mci_SendAppCmd(uint16_t rca) const 01550 { 01551 ReturnCode Ret = SDC_RET_FAILED; 01552 response_t Response; 01553 uint32_t RetryCnt = 20; 01554 01555 while (RetryCnt > 0) { 01556 Ret = mci_ExecuteCmd(SD_CMD55_APP_CMD, CMD55_RCA(rca), &Response); 01557 if (Ret == SDC_RET_OK) { 01558 if (mci_CheckR1Response(Response.Data[0], &Ret)) { 01559 if (Ret != SDC_RET_OK) { 01560 return Ret; 01561 } 01562 if (Response.Data[0] & R1_APP_CMD) { 01563 return SDC_RET_OK; 01564 } 01565 else { 01566 Ret = SDC_RET_FAILED; 01567 } 01568 } 01569 } 01570 RetryCnt--; 01571 } 01572 return SDC_RET_FAILED; 01573 } 01574 01575 void MCIFileSystem::mci_SetDataTransfer(uint16_t BlockNum, bool DirFromCard, uint32_t Timeout) const 01576 { 01577 uint32_t DataCtrl = 0; 01578 LPC_MCI->DATATMR = Timeout; 01579 LPC_MCI->DATALEN = BlockNum * 512; 01580 01581 DataCtrl = SDC_DATACTRL_ENABLE; 01582 // DataCtrl mode=block, block size=512byte 01583 DataCtrl |= (0x9 << 4); 01584 if (DirFromCard) { 01585 DataCtrl |= (0x1 << 1); 01586 } 01587 DataCtrl |= SDC_DATACTRL_DMA_ENABLE; 01588 LPC_MCI->DATACTRL = DataCtrl; 01589 mci_WriteDelay(); 01590 } 01591 01592 void MCIFileSystem::mci_GetResp(response_t* pResp) const 01593 { 01594 pResp->CmdIndex = SDC_RESPCOMMAND_VAL(LPC_MCI->RESP_CMD); 01595 pResp->Data[0] = LPC_MCI->RESP0; 01596 if (CardStatusNumBytes == 4) { 01597 pResp->Data[1] = LPC_MCI->RESP1; 01598 pResp->Data[2] = LPC_MCI->RESP2; 01599 pResp->Data[3] = LPC_MCI->RESP3; 01600 } 01601 } 01602 01603 uint32_t MCIFileSystem::mci_GetBits(int32_t start, int32_t end, uint32_t *data) const 01604 { 01605 uint32_t v; 01606 uint32_t i = end >> 5; 01607 uint32_t j = start & 0x1f; 01608 01609 if (i == (start >> 5)) { 01610 v = (data[i] >> j); 01611 } 01612 else { 01613 v = ((data[i] << (32 - j)) | (data[start >> 5] >> j)); 01614 } 01615 01616 return v & ((1 << (end - start + 1)) - 1); 01617 } 01618 01619 void MCIFileSystem::mci_SetCommand(uint32_t Cmd, uint32_t Arg) const 01620 { 01621 /* Clear status register */ 01622 LPC_MCI->CLEAR = SDC_CLEAR_ALL; 01623 01624 /* Set the argument first, finally command */ 01625 LPC_MCI->ARGUMENT = Arg; 01626 01627 /* Write command value, enable the command */ 01628 LPC_MCI->COMMAND = Cmd | SDC_COMMAND_ENABLE; 01629 01630 mci_WriteDelay(); 01631 } 01632 01633 void MCIFileSystem::mci_ResetCommand() const 01634 { 01635 LPC_MCI->CLEAR = SDC_CLEAR_ALL; 01636 01637 LPC_MCI->ARGUMENT = 0xFFFFFFFF; 01638 01639 LPC_MCI->COMMAND = 0; 01640 01641 mci_WriteDelay(); 01642 } 01643 01644 int32_t MCIFileSystem::mci_IRQHandler(uint8_t *txBuf, uint32_t *txCnt, uint8_t *rxBuf, uint32_t *rxCnt) 01645 { 01646 uint32_t Status; 01647 01648 Status = LPC_MCI->STATUS; 01649 01650 if ( Status & SDC_STATUS_DATAERR) { 01651 LPC_MCI->CLEAR = SDC_STATUS_DATAERR; 01652 return -1; /* Data transfer error */ 01653 } 01654 01655 if ( Status & SDC_STATUS_DATAEND) { 01656 LPC_MCI->CLEAR = SDC_STATUS_DATAEND; 01657 LPC_MCI->MASK0 = 0; 01658 return 0; 01659 } 01660 01661 if ( Status & SDC_STATUS_DATABLOCKEND) { 01662 LPC_MCI->CLEAR = SDC_STATUS_DATABLOCKEND; 01663 return 1; 01664 } 01665 01666 if (Status & SDC_STATUS_FIFO) { 01667 return mci_FIFOIRQHandler(txBuf, txCnt, rxBuf, rxCnt); 01668 } 01669 01670 return 1; 01671 } 01672 01673 int32_t MCIFileSystem::mci_FIFOIRQHandler(uint8_t *txBuf, uint32_t *txCnt, uint8_t *rxBuf, uint32_t *rxCnt) 01674 { 01675 uint32_t Status; 01676 Status = LPC_MCI->STATUS; 01677 01678 if (txBuf) { 01679 if (Status & SDC_STATUS_TXFIFOHALFEMPTY) { 01680 if (*txCnt % 64) { 01681 mci_WriteFIFO((uint32_t *) &txBuf[*txCnt], false); 01682 } 01683 else { 01684 mci_WriteFIFO((uint32_t *) &txBuf[*txCnt], true); 01685 } 01686 *txCnt += 32; 01687 } 01688 } 01689 01690 if (rxBuf) { 01691 if (Status & SDC_STATUS_RXFIFOHALFFULL) { 01692 if (*rxCnt % 64) { 01693 mci_ReadFIFO((uint32_t *) &rxBuf[*rxCnt], false); 01694 } 01695 else { 01696 mci_ReadFIFO((uint32_t *) &rxBuf[*rxCnt], true); 01697 } 01698 *rxCnt += 32; 01699 } 01700 } 01701 01702 LPC_MCI->CLEAR = SDC_STATUS_FIFO; 01703 01704 return 1; 01705 } 01706 01707 void MCIFileSystem::mci_ReadFIFO(uint32_t *pDst, bool bFirstHalf) const 01708 { 01709 uint8_t start = 0, end = 7; 01710 01711 if (!bFirstHalf) { 01712 start += 8; 01713 end += 8; 01714 } 01715 for (; start <= end; start++) { 01716 *pDst = LPC_MCI->FIFO[start]; 01717 pDst++; 01718 } 01719 } 01720 01721 void MCIFileSystem::mci_WriteFIFO(uint32_t *pSrc, bool bFirstHalf) const 01722 { 01723 uint8_t start = 0, end = 7; 01724 if (!bFirstHalf) { 01725 start += 8; 01726 end += 8; 01727 } 01728 for (; start <= end; start++) { 01729 LPC_MCI->FIFO[start] = *pSrc; 01730 pSrc++; 01731 } 01732 } 01733 01734 void MCIFileSystem::mci_SetupEventWakeup(uint8_t dmaChannel) 01735 { 01736 /* Wait for IRQ - for an RTOS, you would pend on an event here with a IRQ based wakeup. */ 01737 NVIC_ClearPendingIRQ(DMA_IRQn); 01738 01739 _eventDmaChannel = dmaChannel; 01740 _eventReceived = false; 01741 _eventSuccess = false; 01742 01743 NVIC_EnableIRQ(DMA_IRQn); 01744 } 01745 01746 uint32_t MCIFileSystem::mci_WaitForEvent() const 01747 { 01748 /* Wait for the event (DMA or MCI interrupt) for a maximum of 2 seconds */ 01749 uint32_t end = us_ticker_read() + 2*1000*1000; 01750 while ((us_ticker_read() < end) && (!_eventReceived)) 01751 { 01752 // If the driver is having problems reading the card, adding a delay here 01753 // might help. 01754 //wait(0.01); 01755 } 01756 01757 if (_eventReceived && _eventSuccess) { 01758 return 0; 01759 } 01760 01761 return 1; 01762 } 01763 01764 MCIFileSystem::ReturnCode MCIFileSystem::_readBlocks(uint32_t card_type, uint32_t startBlock, uint32_t blockNum) const 01765 { 01766 ReturnCode Ret = SDC_RET_FAILED; 01767 response_t Response; 01768 uint32_t Command, Argument; 01769 uint8_t RetryCnt = 0x20; 01770 01771 if (blockNum == 1) { 01772 Command = SD_CMD17_READ_SINGLE_BLOCK; 01773 } 01774 else { 01775 Command = SD_CMD18_READ_MULTIPLE_BLOCK; 01776 } 01777 01778 /* Select single or multiple read based on number of blocks */ 01779 /* if high capacity card use block indexing */ 01780 if (card_type & CARD_TYPE_HC) { 01781 Argument = startBlock; 01782 } 01783 else { /*fix at 512 bytes*/ 01784 Argument = startBlock << 9; 01785 } 01786 01787 while (RetryCnt > 0) { 01788 Ret = mci_ExecuteCmd(Command, Argument, &Response); 01789 if (Ret == SDC_RET_OK) { 01790 if (mci_CheckR1Response(Response.Data[0], &Ret)) { 01791 return Ret; 01792 } 01793 } 01794 RetryCnt--; 01795 } 01796 return Ret; 01797 } 01798 01799 MCIFileSystem::ReturnCode MCIFileSystem::_writeBlocks(uint32_t card_type, uint32_t startBlock, uint32_t blockNum) const 01800 { 01801 ReturnCode Ret = SDC_RET_FAILED; 01802 response_t Response; 01803 uint32_t Command, Argument; 01804 uint8_t RetryCnt = 0x20; 01805 01806 if (blockNum == 1) { 01807 Command = SD_CMD24_WRITE_BLOCK; 01808 } 01809 else { 01810 Command = SD_CMD25_WRITE_MULTIPLE_BLOCK; 01811 } 01812 01813 /* if high capacity card use block indexing */ 01814 if (card_type & CARD_TYPE_HC) { 01815 Argument = startBlock; 01816 } 01817 else { /*fix at 512 bytes*/ 01818 Argument = startBlock << 9; 01819 01820 } 01821 01822 while (RetryCnt > 0) { 01823 Ret = mci_ExecuteCmd(Command, Argument, &Response); 01824 if (Ret == SDC_RET_OK) { 01825 if (mci_CheckR1Response(Response.Data[0], &Ret)) { 01826 return Ret; 01827 } 01828 } 01829 RetryCnt--; 01830 } 01831 return Ret; 01832 } 01833
Generated on Wed Jul 13 2022 02:29:31 by 1.7.2