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