A board support package for the LPC4088 Display Module.

Dependencies:   DM_HttpServer DM_USBHost

Dependents:   lpc4088_displaymodule_emwin lpc4088_displaymodule_demo_sphere sampleGUI sampleEmptyGUI ... more

Fork of DMSupport by EmbeddedArtists AB

Committer:
embeddedartists
Date:
Mon Nov 04 14:32:50 2019 +0000
Revision:
42:bbfe299d4a0c
Parent:
41:e06e764ff4fd
More updates related to mbed OS 5

Who changed what in which revision?

UserRevisionLine numberNew contents of line
embeddedartists 0:6b68dac0d986 1 /*
embeddedartists 9:a33326afd686 2 * Copyright 2014 Embedded Artists AB
embeddedartists 0:6b68dac0d986 3 *
embeddedartists 0:6b68dac0d986 4 * Licensed under the Apache License, Version 2.0 (the "License");
embeddedartists 0:6b68dac0d986 5 * you may not use this file except in compliance with the License.
embeddedartists 0:6b68dac0d986 6 * You may obtain a copy of the License at
embeddedartists 0:6b68dac0d986 7 *
embeddedartists 0:6b68dac0d986 8 * http://www.apache.org/licenses/LICENSE-2.0
embeddedartists 0:6b68dac0d986 9 *
embeddedartists 0:6b68dac0d986 10 * Unless required by applicable law or agreed to in writing, software
embeddedartists 0:6b68dac0d986 11 * distributed under the License is distributed on an "AS IS" BASIS,
embeddedartists 0:6b68dac0d986 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
embeddedartists 0:6b68dac0d986 13 * See the License for the specific language governing permissions and
embeddedartists 0:6b68dac0d986 14 * limitations under the License.
embeddedartists 0:6b68dac0d986 15 */
embeddedartists 0:6b68dac0d986 16
embeddedartists 0:6b68dac0d986 17 /******************************************************************************
embeddedartists 0:6b68dac0d986 18 * Includes
embeddedartists 0:6b68dac0d986 19 *****************************************************************************/
embeddedartists 0:6b68dac0d986 20
embeddedartists 0:6b68dac0d986 21 #include "MCIFileSystem.h"
embeddedartists 0:6b68dac0d986 22 #include "mbed_debug.h"
embeddedartists 31:d47cffcb0a3e 23 #include "rtos.h"
alindvall 40:6df4f63aa406 24 #include "us_ticker_api.h"
embeddedartists 0:6b68dac0d986 25
embeddedartists 0:6b68dac0d986 26 #include "diskio.h" //STA_* defines
embeddedartists 0:6b68dac0d986 27
embeddedartists 0:6b68dac0d986 28 /******************************************************************************
embeddedartists 0:6b68dac0d986 29 * Defines and typedefs
embeddedartists 0:6b68dac0d986 30 *****************************************************************************/
embeddedartists 0:6b68dac0d986 31
embeddedartists 0:6b68dac0d986 32 #define MCI_DBG 0
embeddedartists 0:6b68dac0d986 33
embeddedartists 0:6b68dac0d986 34 #define CMD_TIMEOUT (0x10000)
embeddedartists 0:6b68dac0d986 35
embeddedartists 0:6b68dac0d986 36 #define DATA_TIMER_VALUE_R (SDC_TRAN_CLOCK_RATE / 4) // 250ms
embeddedartists 0:6b68dac0d986 37 #define DATA_TIMER_VALUE_W (SDC_TRAN_CLOCK_RATE) // 1000ms
embeddedartists 31:d47cffcb0a3e 38 #define ACQUIRE_DELAY (100) /*!< inter-command acquire oper condition delay in milliseconds */
embeddedartists 0:6b68dac0d986 39
embeddedartists 0:6b68dac0d986 40 #define SYSCTL_CLOCK_SDC (1<<28)
embeddedartists 0:6b68dac0d986 41
embeddedartists 0:6b68dac0d986 42 /**
embeddedartists 0:6b68dac0d986 43 * @brief SDC Clear Register bit definitions
embeddedartists 0:6b68dac0d986 44 */
embeddedartists 0:6b68dac0d986 45 /** Clear all status flag*/
embeddedartists 0:6b68dac0d986 46 #define SDC_CLEAR_ALL ((uint32_t) 0x7FF)
embeddedartists 0:6b68dac0d986 47
embeddedartists 0:6b68dac0d986 48 /*
embeddedartists 0:6b68dac0d986 49 * SDMMC Card bus clock rate definitions
embeddedartists 0:6b68dac0d986 50 */
embeddedartists 0:6b68dac0d986 51 /** Card bus clock in Card Identification Mode */
embeddedartists 0:6b68dac0d986 52 #define SDC_IDENT_CLOCK_RATE (400000) /* 400KHz */
embeddedartists 0:6b68dac0d986 53 /** Card bus clock in Data Transfer Mode */
embeddedartists 0:6b68dac0d986 54 #define SDC_TRAN_CLOCK_RATE (20000000) /* 20MHz */
embeddedartists 0:6b68dac0d986 55
embeddedartists 0:6b68dac0d986 56 /**
embeddedartists 0:6b68dac0d986 57 * @brief SDC Power Control Register bit definitions
embeddedartists 0:6b68dac0d986 58 */
embeddedartists 0:6b68dac0d986 59 /** SD_CMD Output Control */
embeddedartists 0:6b68dac0d986 60 #define SDC_PWR_OPENDRAIN (((uint32_t) 1) << 6)
embeddedartists 0:6b68dac0d986 61
embeddedartists 0:6b68dac0d986 62 /**
embeddedartists 0:6b68dac0d986 63 * @brief SDC Command Register bit definitions
embeddedartists 0:6b68dac0d986 64 */
embeddedartists 0:6b68dac0d986 65 /** SDC Command Register Bitmask */
embeddedartists 0:6b68dac0d986 66 #define SDC_COMMAND_BITMASK ((uint32_t) 0x7FF)
embeddedartists 0:6b68dac0d986 67 /** SDC Command Index Bitmask */
embeddedartists 0:6b68dac0d986 68 #define SDC_COMMAND_INDEX_BITMASK ((uint32_t) 0x3F)
embeddedartists 0:6b68dac0d986 69 /** Set SDC Command Index */
embeddedartists 0:6b68dac0d986 70 #define SDC_COMMAND_INDEX(n) ((uint32_t) n & 0x3F)
embeddedartists 0:6b68dac0d986 71 /** No response is expected */
embeddedartists 0:6b68dac0d986 72 #define SDC_COMMAND_NO_RSP (((uint32_t) 0 ) << 6)
embeddedartists 0:6b68dac0d986 73 /** Short response is expected */
embeddedartists 0:6b68dac0d986 74 #define SDC_COMMAND_SHORT_RSP (((uint32_t) 1 ) << 6)
embeddedartists 0:6b68dac0d986 75 /** Long response is expected */
embeddedartists 0:6b68dac0d986 76 #define SDC_COMMAND_LONG_RSP (((uint32_t) 3 ) << 6)
embeddedartists 0:6b68dac0d986 77 /** Response bit mask */
embeddedartists 0:6b68dac0d986 78 #define SDC_COMMAND_RSP_BITMASK (((uint32_t) 3 ) << 6)
embeddedartists 0:6b68dac0d986 79 /** Mark that command timer is disabled and CPSM waits for interrupt request */
embeddedartists 0:6b68dac0d986 80 #define SDC_COMMAND_INTERRUPT (((uint32_t) 1 ) << 8)
embeddedartists 0:6b68dac0d986 81 /** Mark that CPSM waits for CmdPend before starting sending a command*/
embeddedartists 0:6b68dac0d986 82 #define SDC_COMMAND_PENDING (((uint32_t) 1 ) << 9)
embeddedartists 0:6b68dac0d986 83 /** Enable CPSM */
embeddedartists 0:6b68dac0d986 84 #define SDC_COMMAND_ENABLE (((uint32_t) 1 ) << 10)
embeddedartists 0:6b68dac0d986 85
embeddedartists 0:6b68dac0d986 86 /**
embeddedartists 0:6b68dac0d986 87 * @brief SDC Command Response Register bit definitions
embeddedartists 0:6b68dac0d986 88 */
embeddedartists 0:6b68dac0d986 89 /** SDC Command Response value */
embeddedartists 0:6b68dac0d986 90 #define SDC_RESPCOMMAND_VAL(n) ((uint32_t) n & 0x3F)
embeddedartists 0:6b68dac0d986 91
embeddedartists 0:6b68dac0d986 92 /*
embeddedartists 0:6b68dac0d986 93 * SD/MMC Response type definitions
embeddedartists 0:6b68dac0d986 94 */
embeddedartists 0:6b68dac0d986 95 #define CMDRESP_NONE_TYPE (SDC_COMMAND_NO_RSP)
embeddedartists 0:6b68dac0d986 96 #define CMDRESP_R1_TYPE (SDC_COMMAND_SHORT_RSP)
embeddedartists 0:6b68dac0d986 97 #define CMDRESP_R1b_TYPE (SDC_COMMAND_SHORT_RSP)
embeddedartists 0:6b68dac0d986 98 #define CMDRESP_R2_TYPE (SDC_COMMAND_LONG_RSP)
embeddedartists 0:6b68dac0d986 99 #define CMDRESP_R3_TYPE (SDC_COMMAND_SHORT_RSP)
embeddedartists 0:6b68dac0d986 100 #define CMDRESP_R6_TYPE (SDC_COMMAND_SHORT_RSP)
embeddedartists 0:6b68dac0d986 101 #define CMDRESP_R7_TYPE (SDC_COMMAND_SHORT_RSP)
embeddedartists 0:6b68dac0d986 102
embeddedartists 0:6b68dac0d986 103 /*
embeddedartists 0:6b68dac0d986 104 * SD command values (Command Index, Response)
embeddedartists 0:6b68dac0d986 105 */
embeddedartists 0:6b68dac0d986 106 #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) */
embeddedartists 0:6b68dac0d986 107 #define SD_CMD1_SEND_OP_COND (SDC_COMMAND_INDEX(MMC_SEND_OP_COND) | CMDRESP_R3_TYPE | 0) /*!< SEND_OP_COND(MMC) or ACMD41(SD) */
embeddedartists 0:6b68dac0d986 108 #define SD_CMD2_ALL_SEND_CID (SDC_COMMAND_INDEX(MMC_ALL_SEND_CID) | CMDRESP_R2_TYPE | 0) /*!< ALL_SEND_CID */
embeddedartists 0:6b68dac0d986 109 #define SD_CMD3_SET_RELATIVE_ADDR (SDC_COMMAND_INDEX(MMC_SET_RELATIVE_ADDR) | CMDRESP_R1_TYPE | 0) /*!< SET_RELATE_ADDR */
embeddedartists 0:6b68dac0d986 110 #define SD_CMD3_SEND_RELATIVE_ADDR (SDC_COMMAND_INDEX(SD_SEND_RELATIVE_ADDR) | CMDRESP_R6_TYPE | 0) /*!< SEND_RELATE_ADDR */
embeddedartists 0:6b68dac0d986 111 #define SD_CMD7_SELECT_CARD (SDC_COMMAND_INDEX(MMC_SELECT_CARD) | CMDRESP_R1b_TYPE | 0) /*!< SELECT/DESELECT_CARD */
embeddedartists 0:6b68dac0d986 112 #define SD_CMD8_SEND_IF_COND (SDC_COMMAND_INDEX(SD_CMD8) | CMDRESP_R7_TYPE | 0) /*!< SEND_IF_COND */
embeddedartists 0:6b68dac0d986 113 #define SD_CMD9_SEND_CSD (SDC_COMMAND_INDEX(MMC_SEND_CSD) | CMDRESP_R2_TYPE | 0) /*!< SEND_CSD */
embeddedartists 0:6b68dac0d986 114 #define SD_CMD12_STOP_TRANSMISSION (SDC_COMMAND_INDEX(MMC_STOP_TRANSMISSION) | CMDRESP_R1_TYPE | 0) /*!< STOP_TRANSMISSION */
embeddedartists 0:6b68dac0d986 115 #define SD_CMD13_SEND_STATUS (SDC_COMMAND_INDEX(MMC_SEND_STATUS) | CMDRESP_R1_TYPE | 0) /*!< SEND_STATUS */
embeddedartists 0:6b68dac0d986 116
embeddedartists 0:6b68dac0d986 117 /* Block-Oriented Read Commands (class 2) */
embeddedartists 0:6b68dac0d986 118 #define SD_CMD16_SET_BLOCKLEN (SDC_COMMAND_INDEX(MMC_SET_BLOCKLEN) | CMDRESP_R1_TYPE | 0) /*!< SET_BLOCK_LEN */
embeddedartists 0:6b68dac0d986 119 #define SD_CMD17_READ_SINGLE_BLOCK (SDC_COMMAND_INDEX(MMC_READ_SINGLE_BLOCK) | CMDRESP_R1_TYPE | 0) /*!< READ_SINGLE_BLOCK */
embeddedartists 0:6b68dac0d986 120 #define SD_CMD18_READ_MULTIPLE_BLOCK (SDC_COMMAND_INDEX(MMC_READ_MULTIPLE_BLOCK) | CMDRESP_R1_TYPE | 0) /*!< READ_MULTIPLE_BLOCK */
embeddedartists 0:6b68dac0d986 121
embeddedartists 0:6b68dac0d986 122 /* Block-Oriented Write Commands (class 4) */
embeddedartists 0:6b68dac0d986 123 #define SD_CMD24_WRITE_BLOCK (SDC_COMMAND_INDEX(MMC_WRITE_BLOCK) | CMDRESP_R1_TYPE | 0) /*!< WRITE_BLOCK */
embeddedartists 0:6b68dac0d986 124 #define SD_CMD25_WRITE_MULTIPLE_BLOCK (SDC_COMMAND_INDEX(MMC_WRITE_MULTIPLE_BLOCK) | CMDRESP_R1_TYPE | 0) /*!< WRITE_MULTIPLE_BLOCK */
embeddedartists 0:6b68dac0d986 125
embeddedartists 0:6b68dac0d986 126 /* Erase Commands (class 5) */
embeddedartists 0:6b68dac0d986 127 #define SD_CMD32_ERASE_WR_BLK_START (SDC_COMMAND_INDEX(SD_ERASE_WR_BLK_START) | CMDRESP_R1_TYPE | 0) /*!< ERASE_WR_BLK_START */
embeddedartists 0:6b68dac0d986 128 #define SD_CMD33_ERASE_WR_BLK_END (SDC_COMMAND_INDEX(SD_ERASE_WR_BLK_END) | CMDRESP_R1_TYPE | 0) /*!< ERASE_WR_BLK_END */
embeddedartists 0:6b68dac0d986 129 #define SD_CMD38_ERASE (SDC_COMMAND_INDEX(SD_ERASE) | CMDRESP_R1b_TYPE | 0) /*!< ERASE */
embeddedartists 0:6b68dac0d986 130
embeddedartists 0:6b68dac0d986 131 /* Application-Specific Commands (class 8) */
embeddedartists 0:6b68dac0d986 132 #define SD_CMD55_APP_CMD (SDC_COMMAND_INDEX(MMC_APP_CMD) | CMDRESP_R1_TYPE | 0) /*!< APP_CMD */
embeddedartists 0:6b68dac0d986 133 #define SD_ACMD6_SET_BUS_WIDTH (SDC_COMMAND_INDEX(SD_APP_SET_BUS_WIDTH) | CMDRESP_R1_TYPE | 0) /*!< SET_BUS_WIDTH */
embeddedartists 0:6b68dac0d986 134 #define SD_ACMD13_SEND_SD_STATUS (SDC_COMMAND_INDEX(MMC_SEND_STATUS) | CMDRESP_R1_TYPE | 0) /*!< SEND_SD_STATUS */
embeddedartists 0:6b68dac0d986 135 #define SD_ACMD41_SD_SEND_OP_COND (SDC_COMMAND_INDEX(SD_APP_OP_COND) | CMDRESP_R3_TYPE | 0) /*!< SD_SEND_OP_COND */
embeddedartists 0:6b68dac0d986 136
embeddedartists 0:6b68dac0d986 137 /**
embeddedartists 0:6b68dac0d986 138 * @brief SDC Interrupt Mask Register bit definitions
embeddedartists 0:6b68dac0d986 139 */
embeddedartists 0:6b68dac0d986 140 /** Mask CmdCrcFail flag.*/
embeddedartists 0:6b68dac0d986 141 #define SDC_MASK0_CMDCRCFAIL (((uint32_t) 1 ) << 0)
embeddedartists 0:6b68dac0d986 142 /** Mask DataCrcFail flag. */
embeddedartists 0:6b68dac0d986 143 #define SDC_MASK0_DATACRCFAIL (((uint32_t) 1 ) << 1)
embeddedartists 0:6b68dac0d986 144 /** Mask CmdTimeOut flag. */
embeddedartists 0:6b68dac0d986 145 #define SDC_MASK0_CMDTIMEOUT (((uint32_t) 1 ) << 2)
embeddedartists 0:6b68dac0d986 146 /** Mask DataTimeOut flag. */
embeddedartists 0:6b68dac0d986 147 #define SDC_MASK0_DATATIMEOUT (((uint32_t) 1 ) << 3)
embeddedartists 0:6b68dac0d986 148 /** Mask TxUnderrun flag. */
embeddedartists 0:6b68dac0d986 149 #define SDC_MASK0_TXUNDERRUN (((uint32_t) 1 ) << 4)
embeddedartists 0:6b68dac0d986 150 /** Mask RxOverrun flag. */
embeddedartists 0:6b68dac0d986 151 #define SDC_MASK0_RXOVERRUN (((uint32_t) 1 ) << 5)
embeddedartists 0:6b68dac0d986 152 /** Mask CmdRespEnd flag. */
embeddedartists 0:6b68dac0d986 153 #define SDC_MASK0_CMDRESPEND (((uint32_t) 1 ) << 6)
embeddedartists 0:6b68dac0d986 154 /** Mask CmdSent flag.*/
embeddedartists 0:6b68dac0d986 155 #define SDC_MASK0_CMDSENT (((uint32_t) 1 ) << 7)
embeddedartists 0:6b68dac0d986 156 /** Mask DataEnd flag.*/
embeddedartists 0:6b68dac0d986 157 #define SDC_MASK0_DATAEND (((uint32_t) 1 ) << 8)
embeddedartists 0:6b68dac0d986 158 /** Mask StartBitErr flag.*/
embeddedartists 0:6b68dac0d986 159 #define SDC_MASK0_STARTBITERR (((uint32_t) 1 ) << 9)
embeddedartists 0:6b68dac0d986 160 /** Mask DataBlockEnd flag.*/
embeddedartists 0:6b68dac0d986 161 #define SDC_MASK0_DATABLOCKEND (((uint32_t) 1 ) << 10)
embeddedartists 0:6b68dac0d986 162 /** Mask CmdActive flag.*/
embeddedartists 0:6b68dac0d986 163 #define SDC_MASK0_CMDACTIVE (((uint32_t) 1 ) << 11)
embeddedartists 0:6b68dac0d986 164 /** Mask TxActive flag.*/
embeddedartists 0:6b68dac0d986 165 #define SDC_MASK0_TXACTIVE (((uint32_t) 1 ) << 12)
embeddedartists 0:6b68dac0d986 166 /** Mask RxActive flag.*/
embeddedartists 0:6b68dac0d986 167 #define SDC_MASK0_RXACTIVE (((uint32_t) 1 ) << 13)
embeddedartists 0:6b68dac0d986 168 /** Mask TxFifoHalfEmpty flag.*/
embeddedartists 0:6b68dac0d986 169 #define SDC_MASK0_TXFIFOHALFEMPTY (((uint32_t) 1 ) << 14)
embeddedartists 0:6b68dac0d986 170 /** Mask RxFifoHalfFull flag.*/
embeddedartists 0:6b68dac0d986 171 #define SDC_MASK0_RXFIFOHALFFULL (((uint32_t) 1 ) << 15)
embeddedartists 0:6b68dac0d986 172 /** Mask TxFifoFull flag.*/
embeddedartists 0:6b68dac0d986 173 #define SDC_MASK0_TXFIFOFULL (((uint32_t) 1 ) << 16)
embeddedartists 0:6b68dac0d986 174 /** Mask RxFifoFull flag.*/
embeddedartists 0:6b68dac0d986 175 #define SDC_MASK0_RXFIFOFULL (((uint32_t) 1 ) << 17)
embeddedartists 0:6b68dac0d986 176 /** Mask TxFifoEmpty flag.*/
embeddedartists 0:6b68dac0d986 177 #define SDC_MASK0_TXFIFOEMPTY (((uint32_t) 1 ) << 18)
embeddedartists 0:6b68dac0d986 178 /** Mask RxFifoEmpty flag.*/
embeddedartists 0:6b68dac0d986 179 #define SDC_MASK0_RXFIFOEMPTY (((uint32_t) 1 ) << 19)
embeddedartists 0:6b68dac0d986 180 /** Mask TxDataAvlbl flag.*/
embeddedartists 0:6b68dac0d986 181 #define SDC_MASK0_TXDATAAVLBL (((uint32_t) 1 ) << 20)
embeddedartists 0:6b68dac0d986 182 /** Mask RxDataAvlbl flag.*/
embeddedartists 0:6b68dac0d986 183 #define SDC_MASK0_RXDATAAVLBL (((uint32_t) 1 ) << 21)
embeddedartists 0:6b68dac0d986 184 /** CMD error interrupt mask */
embeddedartists 0:6b68dac0d986 185 #define SDC_MASK0_CMDERR (SDC_MASK0_CMDCRCFAIL | SDC_MASK0_CMDTIMEOUT | SDC_MASK0_STARTBITERR)
embeddedartists 0:6b68dac0d986 186 /** Data Transmit Error interrupt mask */
embeddedartists 0:6b68dac0d986 187 #define SDC_MASK0_TXDATAERR (SDC_MASK0_DATACRCFAIL | SDC_MASK0_DATATIMEOUT | SDC_MASK0_TXUNDERRUN | SDC_MASK0_STARTBITERR)
embeddedartists 0:6b68dac0d986 188 /** Data Receive Error interrupt mask */
embeddedartists 0:6b68dac0d986 189 #define SDC_MASK0_RXDATAERR (SDC_MASK0_DATACRCFAIL | SDC_MASK0_DATATIMEOUT | SDC_MASK0_RXOVERRUN | SDC_MASK0_STARTBITERR)
embeddedartists 0:6b68dac0d986 190 /** Data Transfer interrupt mask*/
embeddedartists 0:6b68dac0d986 191 #define SDC_MASK0_DATA (SDC_MASK0_DATAEND | SDC_MASK0_DATABLOCKEND )
embeddedartists 0:6b68dac0d986 192
embeddedartists 0:6b68dac0d986 193 /**
embeddedartists 0:6b68dac0d986 194 * @brief SDC Clock Control Register bit definitions
embeddedartists 0:6b68dac0d986 195 */
embeddedartists 0:6b68dac0d986 196 /** SDC Clock Control Register Bitmask */
embeddedartists 0:6b68dac0d986 197 #define SDC_CLOCK_BITMASK ((uint32_t) 0xFFF)
embeddedartists 0:6b68dac0d986 198 /** SDC Clock Divider Bitmask */
embeddedartists 0:6b68dac0d986 199 #define SDC_CLOCK_CLKDIV_BITMASK (((uint32_t) 0xFF ) << 0)
embeddedartists 0:6b68dac0d986 200 /** Set SDC Clock Divide value */
embeddedartists 0:6b68dac0d986 201 #define SDC_CLOCK_CLKDIV(n) (((uint32_t) (n & 0x0FF)) << 0)
embeddedartists 0:6b68dac0d986 202
embeddedartists 0:6b68dac0d986 203 /**
embeddedartists 0:6b68dac0d986 204 * @brief SDC Status Register bit definitions
embeddedartists 0:6b68dac0d986 205 */
embeddedartists 0:6b68dac0d986 206 /** Command Response received (CRC check failed) */
embeddedartists 0:6b68dac0d986 207 #define SDC_STATUS_CMDCRCFAIL (((uint32_t) 1 ) << 0)
embeddedartists 0:6b68dac0d986 208 /** Data block sent/received (CRC check failed). */
embeddedartists 0:6b68dac0d986 209 #define SDC_STATUS_DATACRCFAIL (((uint32_t) 1 ) << 1)
embeddedartists 0:6b68dac0d986 210 /** Command response timeout.. */
embeddedartists 0:6b68dac0d986 211 #define SDC_STATUS_CMDTIMEOUT (((uint32_t) 1 ) << 2)
embeddedartists 0:6b68dac0d986 212 /** Data timeout. */
embeddedartists 0:6b68dac0d986 213 #define SDC_STATUS_DATATIMEOUT (((uint32_t) 1 ) << 3)
embeddedartists 0:6b68dac0d986 214 /** Transmit FIFO underrun error. */
embeddedartists 0:6b68dac0d986 215 #define SDC_STATUS_TXUNDERRUN (((uint32_t) 1 ) << 4)
embeddedartists 0:6b68dac0d986 216 /** Receive FIFO overrun error. */
embeddedartists 0:6b68dac0d986 217 #define SDC_STATUS_RXOVERRUN (((uint32_t) 1 ) << 5)
embeddedartists 0:6b68dac0d986 218 /** Command response received (CRC check passed). */
embeddedartists 0:6b68dac0d986 219 #define SDC_STATUS_CMDRESPEND (((uint32_t) 1 ) << 6)
embeddedartists 0:6b68dac0d986 220 /** Command sent (no response required).*/
embeddedartists 0:6b68dac0d986 221 #define SDC_STATUS_CMDSENT (((uint32_t) 1 ) << 7)
embeddedartists 0:6b68dac0d986 222 /** Data end (data counter is zero).*/
embeddedartists 0:6b68dac0d986 223 #define SDC_STATUS_DATAEND (((uint32_t) 1 ) << 8)
embeddedartists 0:6b68dac0d986 224 /** Start bit not detected on all data signals in wide bus mode..*/
embeddedartists 0:6b68dac0d986 225 #define SDC_STATUS_STARTBITERR (((uint32_t) 1 ) << 9)
embeddedartists 0:6b68dac0d986 226 /** Data block sent/received (CRC check passed).*/
embeddedartists 0:6b68dac0d986 227 #define SDC_STATUS_DATABLOCKEND (((uint32_t) 1 ) << 10)
embeddedartists 0:6b68dac0d986 228 /** Command transfer in progress.*/
embeddedartists 0:6b68dac0d986 229 #define SDC_STATUS_CMDACTIVE (((uint32_t) 1 ) << 11)
embeddedartists 0:6b68dac0d986 230 /** Data transmit in progress.*/
embeddedartists 0:6b68dac0d986 231 #define SDC_STATUS_TXACTIVE (((uint32_t) 1 ) << 12)
embeddedartists 0:6b68dac0d986 232 /** Data receive in progress.*/
embeddedartists 0:6b68dac0d986 233 #define SDC_STATUS_RXACTIVE (((uint32_t) 1 ) << 13)
embeddedartists 0:6b68dac0d986 234 /** Transmit FIFO half empty.*/
embeddedartists 0:6b68dac0d986 235 #define SDC_STATUS_TXFIFOHALFEMPTY (((uint32_t) 1 ) << 14)
embeddedartists 0:6b68dac0d986 236 /** Receive FIFO half full.*/
embeddedartists 0:6b68dac0d986 237 #define SDC_STATUS_RXFIFOHALFFULL (((uint32_t) 1 ) << 15)
embeddedartists 0:6b68dac0d986 238 /** Transmit FIFO full.*/
embeddedartists 0:6b68dac0d986 239 #define SDC_STATUS_TXFIFOFULL (((uint32_t) 1 ) << 16)
embeddedartists 0:6b68dac0d986 240 /** Receive FIFO full.*/
embeddedartists 0:6b68dac0d986 241 #define SDC_STATUS_RXFIFOFULL (((uint32_t) 1 ) << 17)
embeddedartists 0:6b68dac0d986 242 /** Transmit FIFO empty.*/
embeddedartists 0:6b68dac0d986 243 #define SDC_STATUS_TXFIFOEMPTY (((uint32_t) 1 ) << 18)
embeddedartists 0:6b68dac0d986 244 /** Receive FIFO empty.*/
embeddedartists 0:6b68dac0d986 245 #define SDC_STATUS_RXFIFOEMPTY (((uint32_t) 1 ) << 19)
embeddedartists 0:6b68dac0d986 246 /** Data available in transmit FIFO.*/
embeddedartists 0:6b68dac0d986 247 #define SDC_STATUS_TXDATAAVLBL (((uint32_t) 1 ) << 20)
embeddedartists 0:6b68dac0d986 248 /** Data available in receive FIFO.*/
embeddedartists 0:6b68dac0d986 249 #define SDC_STATUS_RXDATAAVLBL (((uint32_t) 1 ) << 21)
embeddedartists 0:6b68dac0d986 250 /** Command Error Status */
embeddedartists 0:6b68dac0d986 251 #define SDC_STATUS_CMDERR (SDC_STATUS_CMDCRCFAIL | SDC_STATUS_CMDTIMEOUT | SDC_STATUS_STARTBITERR)
embeddedartists 0:6b68dac0d986 252 /** Data Error Status */
embeddedartists 0:6b68dac0d986 253 #define SDC_STATUS_DATAERR (SDC_STATUS_DATACRCFAIL | SDC_STATUS_DATATIMEOUT | SDC_STATUS_TXUNDERRUN \
embeddedartists 0:6b68dac0d986 254 | SDC_STATUS_RXOVERRUN | SDC_STATUS_STARTBITERR)
embeddedartists 0:6b68dac0d986 255 /** FIFO Status*/
embeddedartists 0:6b68dac0d986 256 #define SDC_STATUS_FIFO (SDC_STATUS_TXFIFOHALFEMPTY | SDC_STATUS_RXFIFOHALFFULL \
embeddedartists 0:6b68dac0d986 257 | SDC_STATUS_TXFIFOFULL | SDC_STATUS_RXFIFOFULL \
embeddedartists 0:6b68dac0d986 258 | SDC_STATUS_TXFIFOEMPTY | SDC_STATUS_RXFIFOEMPTY \
embeddedartists 0:6b68dac0d986 259 | SDC_STATUS_DATABLOCKEND)
embeddedartists 0:6b68dac0d986 260
embeddedartists 0:6b68dac0d986 261 /** Data Transfer Status*/
embeddedartists 0:6b68dac0d986 262 #define SDC_STATUS_DATA (SDC_STATUS_DATAEND )
embeddedartists 0:6b68dac0d986 263
embeddedartists 0:6b68dac0d986 264 /**
embeddedartists 0:6b68dac0d986 265 * @brief SDC Data Control Register bit definitions
embeddedartists 0:6b68dac0d986 266 */
embeddedartists 0:6b68dac0d986 267 /** SDC Data Control Register Bitmask */
embeddedartists 0:6b68dac0d986 268 #define SDC_DATACTRL_BITMASK ((uint32_t) 0xFF)
embeddedartists 0:6b68dac0d986 269 /** Enable Data Transfer */
embeddedartists 0:6b68dac0d986 270 #define SDC_DATACTRL_ENABLE (((uint32_t) 1 ) << 0)
embeddedartists 0:6b68dac0d986 271 /** Mark that Data is transfer from card to controller */
embeddedartists 0:6b68dac0d986 272 #define SDC_DATACTRL_DIR_FROMCARD (((uint32_t) 1 ) << 1)
embeddedartists 0:6b68dac0d986 273 /** Mark that Data is transfer from controller to card */
embeddedartists 0:6b68dac0d986 274 #define SDC_DATACTRL_DIR_TOCARD ((uint32_t) 0)
embeddedartists 0:6b68dac0d986 275 /** Mark that the transfer mode is Stream Data Transfer */
embeddedartists 0:6b68dac0d986 276 #define SDC_DATACTRL_XFER_MODE_STREAM (((uint32_t) 1 ) << 2)
embeddedartists 0:6b68dac0d986 277 /** Mark that the transfer mode is Block Data Transfer */
embeddedartists 0:6b68dac0d986 278 #define SDC_DATACTRL_XFER_MODE_BLOCK ((uint32_t) 0)
embeddedartists 0:6b68dac0d986 279 /** Enable DMA */
embeddedartists 0:6b68dac0d986 280 #define SDC_DATACTRL_DMA_ENABLE (((uint32_t) 1 ) << 3)
embeddedartists 0:6b68dac0d986 281 /** Set Data Block size */
embeddedartists 0:6b68dac0d986 282 #define SDC_DATACTRL_BLOCKSIZE(n) (((uint32_t) (n & 0x0F) ) << 4)
embeddedartists 0:6b68dac0d986 283 /** Get Data Block size value */
embeddedartists 0:6b68dac0d986 284 #define SDC_DATACTRL_BLOCKSIZE_VAL(n) (((uint32_t) 1) << n)
embeddedartists 0:6b68dac0d986 285
embeddedartists 0:6b68dac0d986 286 /**
embeddedartists 0:6b68dac0d986 287 * @brief OCR Register definitions
embeddedartists 0:6b68dac0d986 288 */
embeddedartists 0:6b68dac0d986 289 /** Support voltage range 2.7-3.6 */
embeddedartists 0:6b68dac0d986 290 #define SDC_OCR_27_36 ((uint32_t) 0x00FF8000)
embeddedartists 0:6b68dac0d986 291 /** Card power up status bit */
embeddedartists 0:6b68dac0d986 292 #define SDC_OCR_IDLE (((uint32_t) 1) << 31)
embeddedartists 0:6b68dac0d986 293 #define SDC_OCR_BUSY (((uint32_t) 0) << 31)
embeddedartists 0:6b68dac0d986 294
embeddedartists 0:6b68dac0d986 295
embeddedartists 0:6b68dac0d986 296 /* SD/MMC commands - this matrix shows the command, response types, and
embeddedartists 0:6b68dac0d986 297 supported card type for that command.
embeddedartists 0:6b68dac0d986 298 Command Number Resp SD MMC
embeddedartists 0:6b68dac0d986 299 ----------------------- ------ ----- --- ---
embeddedartists 0:6b68dac0d986 300 Reset (go idle) CMD0 NA x x
embeddedartists 0:6b68dac0d986 301 Send op condition CMD1 R3 x
embeddedartists 0:6b68dac0d986 302 All send CID CMD2 R2 x x
embeddedartists 0:6b68dac0d986 303 Send relative address CMD3 R1 x
embeddedartists 0:6b68dac0d986 304 Send relative address CMD3 R6 x
embeddedartists 0:6b68dac0d986 305 Program DSR CMD4 NA x
embeddedartists 0:6b68dac0d986 306 Select/deselect card CMD7 R1b x
embeddedartists 0:6b68dac0d986 307 Select/deselect card CMD7 R1 x
embeddedartists 0:6b68dac0d986 308 Send CSD CMD9 R2 x x
embeddedartists 0:6b68dac0d986 309 Send CID CMD10 R2 x x
embeddedartists 0:6b68dac0d986 310 Read data until stop CMD11 R1 x x
embeddedartists 0:6b68dac0d986 311 Stop transmission CMD12 R1/b x x
embeddedartists 0:6b68dac0d986 312 Send status CMD13 R1 x x
embeddedartists 0:6b68dac0d986 313 Go inactive state CMD15 NA x x
embeddedartists 0:6b68dac0d986 314 Set block length CMD16 R1 x x
embeddedartists 0:6b68dac0d986 315 Read single block CMD17 R1 x x
embeddedartists 0:6b68dac0d986 316 Read multiple blocks CMD18 R1 x x
embeddedartists 0:6b68dac0d986 317 Write data until stop CMD20 R1 x
embeddedartists 0:6b68dac0d986 318 Setblock count CMD23 R1 x
embeddedartists 0:6b68dac0d986 319 Write single block CMD24 R1 x x
embeddedartists 0:6b68dac0d986 320 Write multiple blocks CMD25 R1 x x
embeddedartists 0:6b68dac0d986 321 Program CID CMD26 R1 x
embeddedartists 0:6b68dac0d986 322 Program CSD CMD27 R1 x x
embeddedartists 0:6b68dac0d986 323 Set write protection CMD28 R1b x x
embeddedartists 0:6b68dac0d986 324 Clear write protection CMD29 R1b x x
embeddedartists 0:6b68dac0d986 325 Send write protection CMD30 R1 x x
embeddedartists 0:6b68dac0d986 326 Erase block start CMD32 R1 x
embeddedartists 0:6b68dac0d986 327 Erase block end CMD33 R1 x
embeddedartists 0:6b68dac0d986 328 Erase block start CMD35 R1 x
embeddedartists 0:6b68dac0d986 329 Erase block end CMD36 R1 x
embeddedartists 0:6b68dac0d986 330 Erase blocks CMD38 R1b x
embeddedartists 0:6b68dac0d986 331 Fast IO CMD39 R4 x
embeddedartists 0:6b68dac0d986 332 Go IRQ state CMD40 R5 x
embeddedartists 0:6b68dac0d986 333 Lock/unlock CMD42 R1b x
embeddedartists 0:6b68dac0d986 334 Application command CMD55 R1 x
embeddedartists 0:6b68dac0d986 335 General command CMD56 R1b x
embeddedartists 0:6b68dac0d986 336
embeddedartists 0:6b68dac0d986 337 *** SD card application commands - these must be preceded with ***
embeddedartists 0:6b68dac0d986 338 *** MMC CMD55 application specific command first ***
embeddedartists 0:6b68dac0d986 339 Set bus width ACMD6 R1 x
embeddedartists 0:6b68dac0d986 340 Send SD status ACMD13 R1 x
embeddedartists 0:6b68dac0d986 341 Send number WR blocks ACMD22 R1 x
embeddedartists 0:6b68dac0d986 342 Set WR block erase cnt ACMD23 R1 x
embeddedartists 0:6b68dac0d986 343 Send op condition ACMD41 R3 x
embeddedartists 0:6b68dac0d986 344 Set clear card detect ACMD42 R1 x
embeddedartists 0:6b68dac0d986 345 Send CSR ACMD51 R1 x */
embeddedartists 0:6b68dac0d986 346
embeddedartists 0:6b68dac0d986 347 /**
embeddedartists 0:6b68dac0d986 348 * @brief SD/MMC commands, arguments and responses
embeddedartists 0:6b68dac0d986 349 * Standard SD/MMC commands (3.1) type argument response
embeddedartists 0:6b68dac0d986 350 */
embeddedartists 0:6b68dac0d986 351 /* class 1 */
embeddedartists 0:6b68dac0d986 352 #define MMC_GO_IDLE_STATE 0 /* bc */
embeddedartists 0:6b68dac0d986 353 #define MMC_SEND_OP_COND 1 /* bcr [31:0] OCR R3 */
embeddedartists 0:6b68dac0d986 354 #define MMC_ALL_SEND_CID 2 /* bcr R2 */
embeddedartists 0:6b68dac0d986 355 #define MMC_SET_RELATIVE_ADDR 3 /* ac [31:16] RCA R1 */
embeddedartists 0:6b68dac0d986 356 #define MMC_SET_DSR 4 /* bc [31:16] RCA */
embeddedartists 0:6b68dac0d986 357 #define MMC_SELECT_CARD 7 /* ac [31:16] RCA R1 */
embeddedartists 0:6b68dac0d986 358 #define MMC_SEND_EXT_CSD 8 /* bc R1 */
embeddedartists 0:6b68dac0d986 359 #define MMC_SEND_CSD 9 /* ac [31:16] RCA R2 */
embeddedartists 0:6b68dac0d986 360 #define MMC_SEND_CID 10 /* ac [31:16] RCA R2 */
embeddedartists 0:6b68dac0d986 361 #define MMC_STOP_TRANSMISSION 12 /* ac R1b */
embeddedartists 0:6b68dac0d986 362 #define MMC_SEND_STATUS 13 /* ac [31:16] RCA R1 */
embeddedartists 0:6b68dac0d986 363 #define MMC_GO_INACTIVE_STATE 15 /* ac [31:16] RCA */
embeddedartists 0:6b68dac0d986 364
embeddedartists 0:6b68dac0d986 365 /* class 2 */
embeddedartists 0:6b68dac0d986 366 #define MMC_SET_BLOCKLEN 16 /* ac [31:0] block len R1 */
embeddedartists 0:6b68dac0d986 367 #define MMC_READ_SINGLE_BLOCK 17 /* adtc [31:0] data addr R1 */
embeddedartists 0:6b68dac0d986 368 #define MMC_READ_MULTIPLE_BLOCK 18 /* adtc [31:0] data addr R1 */
embeddedartists 0:6b68dac0d986 369
embeddedartists 0:6b68dac0d986 370 /* class 3 */
embeddedartists 0:6b68dac0d986 371 #define MMC_WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 */
embeddedartists 0:6b68dac0d986 372
embeddedartists 0:6b68dac0d986 373 /* class 4 */
embeddedartists 0:6b68dac0d986 374 #define MMC_SET_BLOCK_COUNT 23 /* adtc [31:0] data addr R1 */
embeddedartists 0:6b68dac0d986 375 #define MMC_WRITE_BLOCK 24 /* adtc [31:0] data addr R1 */
embeddedartists 0:6b68dac0d986 376 #define MMC_WRITE_MULTIPLE_BLOCK 25 /* adtc R1 */
embeddedartists 0:6b68dac0d986 377 #define MMC_PROGRAM_CID 26 /* adtc R1 */
embeddedartists 0:6b68dac0d986 378 #define MMC_PROGRAM_CSD 27 /* adtc R1 */
embeddedartists 0:6b68dac0d986 379
embeddedartists 0:6b68dac0d986 380 /* class 6 */
embeddedartists 0:6b68dac0d986 381 #define MMC_SET_WRITE_PROT 28 /* ac [31:0] data addr R1b */
embeddedartists 0:6b68dac0d986 382 #define MMC_CLR_WRITE_PROT 29 /* ac [31:0] data addr R1b */
embeddedartists 0:6b68dac0d986 383 #define MMC_SEND_WRITE_PROT 30 /* adtc [31:0] wpdata addr R1 */
embeddedartists 0:6b68dac0d986 384
embeddedartists 0:6b68dac0d986 385 /* class 5 */
embeddedartists 0:6b68dac0d986 386 #define MMC_ERASE_GROUP_START 35 /* ac [31:0] data addr R1 */
embeddedartists 0:6b68dac0d986 387 #define MMC_ERASE_GROUP_END 36 /* ac [31:0] data addr R1 */
embeddedartists 0:6b68dac0d986 388 #define MMC_ERASE 37 /* ac R1b */
embeddedartists 0:6b68dac0d986 389 #define SD_ERASE_WR_BLK_START 32 /* ac [31:0] data addr R1 */
embeddedartists 0:6b68dac0d986 390 #define SD_ERASE_WR_BLK_END 33 /* ac [31:0] data addr R1 */
embeddedartists 0:6b68dac0d986 391 #define SD_ERASE 38 /* ac R1b */
embeddedartists 0:6b68dac0d986 392
embeddedartists 0:6b68dac0d986 393 /* class 9 */
embeddedartists 0:6b68dac0d986 394 #define MMC_FAST_IO 39 /* ac <Complex> R4 */
embeddedartists 0:6b68dac0d986 395 #define MMC_GO_IRQ_STATE 40 /* bcr R5 */
embeddedartists 0:6b68dac0d986 396
embeddedartists 0:6b68dac0d986 397 /* class 7 */
embeddedartists 0:6b68dac0d986 398 #define MMC_LOCK_UNLOCK 42 /* adtc R1b */
embeddedartists 0:6b68dac0d986 399
embeddedartists 0:6b68dac0d986 400 /* class 8 */
embeddedartists 0:6b68dac0d986 401 #define MMC_APP_CMD 55 /* ac [31:16] RCA R1 */
embeddedartists 0:6b68dac0d986 402 #define MMC_GEN_CMD 56 /* adtc [0] RD/WR R1b */
embeddedartists 0:6b68dac0d986 403
embeddedartists 0:6b68dac0d986 404 /* SD commands type argument response */
embeddedartists 0:6b68dac0d986 405 /* class 8 */
embeddedartists 0:6b68dac0d986 406 /* This is basically the same command as for MMC with some quirks. */
embeddedartists 0:6b68dac0d986 407 #define SD_SEND_RELATIVE_ADDR 3 /* ac R6 */
embeddedartists 0:6b68dac0d986 408 #define SD_CMD8 8 /* bcr [31:0] OCR R3 */
embeddedartists 0:6b68dac0d986 409
embeddedartists 0:6b68dac0d986 410 /* Application commands */
embeddedartists 0:6b68dac0d986 411 #define SD_APP_SET_BUS_WIDTH 6 /* ac [1:0] bus width R1 */
embeddedartists 0:6b68dac0d986 412 #define SD_APP_OP_COND 41 /* bcr [31:0] OCR R1 (R4) */
embeddedartists 0:6b68dac0d986 413 #define SD_APP_SEND_SCR 51 /* adtc R1 */
embeddedartists 0:6b68dac0d986 414
embeddedartists 0:6b68dac0d986 415
embeddedartists 0:6b68dac0d986 416 /**
embeddedartists 0:6b68dac0d986 417 * @brief MMC status in R1<br>
embeddedartists 0:6b68dac0d986 418 * Type<br>
embeddedartists 0:6b68dac0d986 419 * e : error bit<br>
embeddedartists 0:6b68dac0d986 420 * s : status bit<br>
embeddedartists 0:6b68dac0d986 421 * r : detected and set for the actual command response<br>
embeddedartists 0:6b68dac0d986 422 * x : detected and set during command execution. the host must poll
embeddedartists 0:6b68dac0d986 423 * the card by sending status command in order to read these bits.
embeddedartists 0:6b68dac0d986 424 * Clear condition<br>
embeddedartists 0:6b68dac0d986 425 * a : according to the card state<br>
embeddedartists 0:6b68dac0d986 426 * b : always related to the previous command. Reception of
embeddedartists 0:6b68dac0d986 427 * a valid command will clear it (with a delay of one command)<br>
embeddedartists 0:6b68dac0d986 428 * c : clear by read<br>
embeddedartists 0:6b68dac0d986 429 */
embeddedartists 0:6b68dac0d986 430
embeddedartists 0:6b68dac0d986 431 #define R1_OUT_OF_RANGE (1UL << 31) /* er, c */
embeddedartists 0:6b68dac0d986 432 #define R1_ADDRESS_ERROR (1 << 30) /* erx, c */
embeddedartists 0:6b68dac0d986 433 #define R1_BLOCK_LEN_ERROR (1 << 29) /* er, c */
embeddedartists 0:6b68dac0d986 434 #define R1_ERASE_SEQ_ERROR (1 << 28) /* er, c */
embeddedartists 0:6b68dac0d986 435 #define R1_ERASE_PARAM (1 << 27) /* ex, c */
embeddedartists 0:6b68dac0d986 436 #define R1_WP_VIOLATION (1 << 26) /* erx, c */
embeddedartists 0:6b68dac0d986 437 #define R1_CARD_IS_LOCKED (1 << 25) /* sx, a */
embeddedartists 0:6b68dac0d986 438 #define R1_LOCK_UNLOCK_FAILED (1 << 24) /* erx, c */
embeddedartists 0:6b68dac0d986 439 #define R1_COM_CRC_ERROR (1 << 23) /* er, b */
embeddedartists 0:6b68dac0d986 440 #define R1_ILLEGAL_COMMAND (1 << 22) /* er, b */
embeddedartists 0:6b68dac0d986 441 #define R1_CARD_ECC_FAILED (1 << 21) /* ex, c */
embeddedartists 0:6b68dac0d986 442 #define R1_CC_ERROR (1 << 20) /* erx, c */
embeddedartists 0:6b68dac0d986 443 #define R1_ERROR (1 << 19) /* erx, c */
embeddedartists 0:6b68dac0d986 444 #define R1_UNDERRUN (1 << 18) /* ex, c */
embeddedartists 0:6b68dac0d986 445 #define R1_OVERRUN (1 << 17) /* ex, c */
embeddedartists 0:6b68dac0d986 446 #define R1_CID_CSD_OVERWRITE (1 << 16) /* erx, c, CID/CSD overwrite */
embeddedartists 0:6b68dac0d986 447 #define R1_WP_ERASE_SKIP (1 << 15) /* sx, c */
embeddedartists 0:6b68dac0d986 448 #define R1_CARD_ECC_DISABLED (1 << 14) /* sx, a */
embeddedartists 0:6b68dac0d986 449 #define R1_ERASE_RESET (1 << 13) /* sr, c */
embeddedartists 0:6b68dac0d986 450 #define R1_STATUS(x) (x & 0xFFFFE000)
embeddedartists 0:6b68dac0d986 451 #define R1_CURRENT_STATE(x) ((x & 0x00001E00) >> 9) /* sx, b (4 bits) */
embeddedartists 0:6b68dac0d986 452 #define R1_READY_FOR_DATA (1 << 8) /* sx, a */
embeddedartists 0:6b68dac0d986 453 #define R1_APP_CMD (1 << 5) /* sr, c */
embeddedartists 0:6b68dac0d986 454
embeddedartists 0:6b68dac0d986 455
embeddedartists 0:6b68dac0d986 456 /**
embeddedartists 0:6b68dac0d986 457 * @brief SD/MMC card OCR register bits
embeddedartists 0:6b68dac0d986 458 */
embeddedartists 0:6b68dac0d986 459 #define OCR_ALL_READY (1UL << 31) /* Card Power up status bit */
embeddedartists 0:6b68dac0d986 460 #define OCR_HC_CCS (1 << 30) /* High capacity card */
embeddedartists 0:6b68dac0d986 461 #define OCR_VOLTAGE_RANGE_MSK (0x00FF8000)
embeddedartists 0:6b68dac0d986 462
embeddedartists 0:6b68dac0d986 463 #define SD_SEND_IF_ARG 0x000001AA
embeddedartists 0:6b68dac0d986 464 #define SD_SEND_IF_ECHO_MSK 0x000000FF
embeddedartists 0:6b68dac0d986 465 #define SD_SEND_IF_RESP 0x000000AA
embeddedartists 0:6b68dac0d986 466
embeddedartists 0:6b68dac0d986 467 /**
embeddedartists 0:6b68dac0d986 468 * @brief R3 response definitions
embeddedartists 0:6b68dac0d986 469 */
embeddedartists 0:6b68dac0d986 470 #define CMDRESP_R3_OCR_VAL(n) (((uint32_t) n) & 0xFFFFFF)
embeddedartists 0:6b68dac0d986 471 #define CMDRESP_R3_S18A (((uint32_t) 1 ) << 24)
embeddedartists 0:6b68dac0d986 472 #define CMDRESP_R3_HC_CCS (((uint32_t) 1 ) << 30)
embeddedartists 0:6b68dac0d986 473 #define CMDRESP_R3_INIT_COMPLETE (((uint32_t) 1 ) << 31)
embeddedartists 0:6b68dac0d986 474
embeddedartists 0:6b68dac0d986 475 /**
embeddedartists 0:6b68dac0d986 476 * @brief R6 response definitions
embeddedartists 0:6b68dac0d986 477 */
embeddedartists 0:6b68dac0d986 478 #define CMDRESP_R6_RCA_VAL(n) (((uint32_t) (n >> 16)) & 0xFFFF)
embeddedartists 0:6b68dac0d986 479 #define CMDRESP_R6_CARD_STATUS(n) (((uint32_t) (n & 0x1FFF)) | \
embeddedartists 0:6b68dac0d986 480 ((n & (1 << 13)) ? (1 << 19) : 0) | \
embeddedartists 0:6b68dac0d986 481 ((n & (1 << 14)) ? (1 << 22) : 0) | \
embeddedartists 0:6b68dac0d986 482 ((n & (1 << 15)) ? (1 << 23) : 0))
embeddedartists 0:6b68dac0d986 483
embeddedartists 0:6b68dac0d986 484 /**
embeddedartists 0:6b68dac0d986 485 * @brief R7 response definitions
embeddedartists 0:6b68dac0d986 486 */
embeddedartists 0:6b68dac0d986 487 /** Echo-back of check-pattern */
embeddedartists 0:6b68dac0d986 488 #define CMDRESP_R7_CHECK_PATTERN(n) (((uint32_t) n ) & 0xFF)
embeddedartists 0:6b68dac0d986 489 /** Voltage accepted */
embeddedartists 0:6b68dac0d986 490 #define CMDRESP_R7_VOLTAGE_ACCEPTED (((uint32_t) 1 ) << 8)
embeddedartists 0:6b68dac0d986 491
embeddedartists 0:6b68dac0d986 492 /**
embeddedartists 0:6b68dac0d986 493 * @brief CMD3 command definitions
embeddedartists 0:6b68dac0d986 494 */
embeddedartists 0:6b68dac0d986 495 /** Card Address */
embeddedartists 0:6b68dac0d986 496 #define CMD3_RCA(n) (((uint32_t) (n & 0xFFFF) ) << 16)
embeddedartists 0:6b68dac0d986 497
embeddedartists 0:6b68dac0d986 498 /**
embeddedartists 0:6b68dac0d986 499 * @brief CMD7 command definitions
embeddedartists 0:6b68dac0d986 500 */
embeddedartists 0:6b68dac0d986 501 /** Card Address */
embeddedartists 0:6b68dac0d986 502 #define CMD7_RCA(n) (((uint32_t) (n & 0xFFFF) ) << 16)
embeddedartists 0:6b68dac0d986 503
embeddedartists 0:6b68dac0d986 504 /**
embeddedartists 0:6b68dac0d986 505 * @brief CMD8 command definitions
embeddedartists 0:6b68dac0d986 506 */
embeddedartists 0:6b68dac0d986 507 /** Check pattern */
embeddedartists 0:6b68dac0d986 508 #define CMD8_CHECKPATTERN(n) (((uint32_t) (n & 0xFF) ) << 0)
embeddedartists 0:6b68dac0d986 509 /** Recommended pattern */
embeddedartists 0:6b68dac0d986 510 #define CMD8_DEF_PATTERN (0xAA)
embeddedartists 0:6b68dac0d986 511 /** Voltage supplied.*/
embeddedartists 0:6b68dac0d986 512 #define CMD8_VOLTAGESUPPLIED_27_36 (((uint32_t) 1 ) << 8)
embeddedartists 0:6b68dac0d986 513
embeddedartists 0:6b68dac0d986 514 /**
embeddedartists 0:6b68dac0d986 515 * @brief CMD9 command definitions
embeddedartists 0:6b68dac0d986 516 */
embeddedartists 0:6b68dac0d986 517 #define CMD9_RCA(n) (((uint32_t) (n & 0xFFFF) ) << 16)
embeddedartists 0:6b68dac0d986 518
embeddedartists 0:6b68dac0d986 519 /**
embeddedartists 0:6b68dac0d986 520 * @brief CMD13 command definitions
embeddedartists 0:6b68dac0d986 521 */
embeddedartists 0:6b68dac0d986 522 #define CMD13_RCA(n) (((uint32_t) (n & 0xFFFF) ) << 16)
embeddedartists 0:6b68dac0d986 523
embeddedartists 0:6b68dac0d986 524 /**
embeddedartists 0:6b68dac0d986 525 * @brief APP_CMD command definitions
embeddedartists 0:6b68dac0d986 526 */
embeddedartists 0:6b68dac0d986 527 #define CMD55_RCA(n) (((uint32_t) (n & 0xFFFF) ) << 16)
embeddedartists 0:6b68dac0d986 528
embeddedartists 0:6b68dac0d986 529 /**
embeddedartists 0:6b68dac0d986 530 * @brief ACMD41 command definitions
embeddedartists 0:6b68dac0d986 531 */
embeddedartists 0:6b68dac0d986 532 #define ACMD41_OCR(n) (((uint32_t) n) & 0xFFFFFF)
embeddedartists 0:6b68dac0d986 533 #define ACMD41_S18R (((uint32_t) 1 ) << 24)
embeddedartists 0:6b68dac0d986 534 #define ACMD41_XPC (((uint32_t) 1 ) << 28)
embeddedartists 0:6b68dac0d986 535 #define ACMD41_HCS (((uint32_t) 1 ) << 30)
embeddedartists 0:6b68dac0d986 536
embeddedartists 0:6b68dac0d986 537 /**
embeddedartists 0:6b68dac0d986 538 * @brief ACMD6 command definitions
embeddedartists 0:6b68dac0d986 539 */
embeddedartists 0:6b68dac0d986 540 #define ACMD6_BUS_WIDTH(n) ((uint32_t) n & 0x03)
embeddedartists 0:6b68dac0d986 541 #define ACMD6_BUS_WIDTH_1 (0)
embeddedartists 0:6b68dac0d986 542 #define ACMD6_BUS_WIDTH_4 (2)
embeddedartists 0:6b68dac0d986 543
embeddedartists 0:6b68dac0d986 544 /** @brief Card type defines
embeddedartists 0:6b68dac0d986 545 */
embeddedartists 0:6b68dac0d986 546 #define CARD_TYPE_SD (1 << 0)
embeddedartists 0:6b68dac0d986 547 #define CARD_TYPE_4BIT (1 << 1)
embeddedartists 0:6b68dac0d986 548 #define CARD_TYPE_8BIT (1 << 2)
embeddedartists 0:6b68dac0d986 549 #define CARD_TYPE_HC (OCR_HC_CCS)/*!< high capacity card > 2GB */
embeddedartists 0:6b68dac0d986 550
embeddedartists 0:6b68dac0d986 551 /**
embeddedartists 0:6b68dac0d986 552 * @brief SD/MMC sector size in bytes
embeddedartists 0:6b68dac0d986 553 */
embeddedartists 0:6b68dac0d986 554 #define MMC_SECTOR_SIZE 512
embeddedartists 0:6b68dac0d986 555
embeddedartists 0:6b68dac0d986 556 /******************************************************************************
embeddedartists 0:6b68dac0d986 557 * External global variables
embeddedartists 0:6b68dac0d986 558 *****************************************************************************/
embeddedartists 0:6b68dac0d986 559
embeddedartists 0:6b68dac0d986 560 /******************************************************************************
embeddedartists 0:6b68dac0d986 561 * Local variables
embeddedartists 0:6b68dac0d986 562 *****************************************************************************/
embeddedartists 0:6b68dac0d986 563
embeddedartists 0:6b68dac0d986 564 static MCIFileSystem* pUglyForIRQ = NULL;
embeddedartists 0:6b68dac0d986 565
embeddedartists 0:6b68dac0d986 566 /******************************************************************************
embeddedartists 0:6b68dac0d986 567 * Local Functions
embeddedartists 0:6b68dac0d986 568 *****************************************************************************/
embeddedartists 0:6b68dac0d986 569
embeddedartists 0:6b68dac0d986 570 static void mymciirq()
embeddedartists 0:6b68dac0d986 571 {
embeddedartists 0:6b68dac0d986 572 pUglyForIRQ->mci_MCIIRQHandler();
embeddedartists 0:6b68dac0d986 573 }
embeddedartists 0:6b68dac0d986 574
embeddedartists 0:6b68dac0d986 575 static void mydmairq()
embeddedartists 0:6b68dac0d986 576 {
embeddedartists 0:6b68dac0d986 577 pUglyForIRQ->mci_DMAIRQHandler();
embeddedartists 0:6b68dac0d986 578 }
embeddedartists 0:6b68dac0d986 579
embeddedartists 0:6b68dac0d986 580 /******************************************************************************
embeddedartists 0:6b68dac0d986 581 * Public Functions
embeddedartists 0:6b68dac0d986 582 *****************************************************************************/
embeddedartists 0:6b68dac0d986 583
embeddedartists 42:bbfe299d4a0c 584 MCIFileSystem::MCIFileSystem(PinName cd) :
embeddedartists 42:bbfe299d4a0c 585 _init_ref_count(0), _is_initialized(false)
embeddedartists 0:6b68dac0d986 586 {
embeddedartists 0:6b68dac0d986 587 pUglyForIRQ = this;
embeddedartists 0:6b68dac0d986 588
embeddedartists 0:6b68dac0d986 589 memset(&_sdCardInfo, 0, sizeof(SDMMC_CARD_T));
embeddedartists 0:6b68dac0d986 590 _eventReceived = false;
embeddedartists 0:6b68dac0d986 591 _eventSuccess = false;
embeddedartists 0:6b68dac0d986 592
embeddedartists 0:6b68dac0d986 593 initMCI();
embeddedartists 0:6b68dac0d986 594
embeddedartists 0:6b68dac0d986 595 if (cd == NC)
embeddedartists 0:6b68dac0d986 596 {
embeddedartists 0:6b68dac0d986 597 _cardDetect = NULL;
embeddedartists 0:6b68dac0d986 598 }
embeddedartists 0:6b68dac0d986 599 else
embeddedartists 0:6b68dac0d986 600 {
embeddedartists 0:6b68dac0d986 601 _cardDetect = new DigitalIn(cd);
embeddedartists 0:6b68dac0d986 602 _cardDetect->mode(PullUp);
embeddedartists 0:6b68dac0d986 603 }
embeddedartists 0:6b68dac0d986 604 }
embeddedartists 0:6b68dac0d986 605
embeddedartists 0:6b68dac0d986 606 MCIFileSystem::~MCIFileSystem()
embeddedartists 0:6b68dac0d986 607 {
embeddedartists 0:6b68dac0d986 608 if (_cardDetect != NULL)
embeddedartists 0:6b68dac0d986 609 {
embeddedartists 0:6b68dac0d986 610 delete _cardDetect;
embeddedartists 0:6b68dac0d986 611 }
embeddedartists 0:6b68dac0d986 612 }
embeddedartists 0:6b68dac0d986 613 void MCIFileSystem::initMCI()
embeddedartists 0:6b68dac0d986 614 {
embeddedartists 0:6b68dac0d986 615 // Pinsel for MCI
embeddedartists 0:6b68dac0d986 616 LPC_IOCON->P1_2 = 2; /* SD_CLK @ P1.2 */
embeddedartists 0:6b68dac0d986 617 LPC_IOCON->P1_3 = 2; /* SD_CMD @ P1.3 */
embeddedartists 0:6b68dac0d986 618 LPC_IOCON->P1_5 = 2 | (1<<7); /* SD_PWR @ P1.5 - digital mode */
embeddedartists 0:6b68dac0d986 619 LPC_IOCON->P1_6 = 2 | (1<<7); /* SD_DAT[0] @ P1.6 - digital mode */
embeddedartists 0:6b68dac0d986 620 LPC_IOCON->P1_7 = 2 | (1<<7); /* SD_DAT[1] @ P1.7 - digital mode */
embeddedartists 0:6b68dac0d986 621 LPC_IOCON->P1_11 = 2; /* SD_DAT[2] @ P1.11 */
embeddedartists 0:6b68dac0d986 622 LPC_IOCON->P1_12 = 2; /* SD_DAT[3] @ P1.12 */
embeddedartists 0:6b68dac0d986 623
embeddedartists 0:6b68dac0d986 624 LPC_SC->PCONP |= SYSCTL_CLOCK_SDC;
embeddedartists 0:6b68dac0d986 625 LPC_SC->RSTCON0 = (1<<28);
embeddedartists 0:6b68dac0d986 626 LPC_SC->RSTCON0 &= ~(1<<28);
embeddedartists 0:6b68dac0d986 627
embeddedartists 0:6b68dac0d986 628 /* Initialize SDC peripheral */
embeddedartists 0:6b68dac0d986 629 LPC_SC->PCONP |= SYSCTL_CLOCK_SDC;
embeddedartists 0:6b68dac0d986 630
embeddedartists 0:6b68dac0d986 631 /* Disable SD_CLK */
embeddedartists 0:6b68dac0d986 632 mci_ClockControl(SDC_CLOCK_ENABLE, false);
embeddedartists 0:6b68dac0d986 633
embeddedartists 0:6b68dac0d986 634 /* Power-off */
embeddedartists 0:6b68dac0d986 635 mci_PowerControl(PowerOff, 0);
embeddedartists 0:6b68dac0d986 636 mci_WriteDelay();
embeddedartists 0:6b68dac0d986 637
embeddedartists 0:6b68dac0d986 638 /* Disable all interrupts */
embeddedartists 0:6b68dac0d986 639 LPC_MCI->MASK0 = 0;
embeddedartists 0:6b68dac0d986 640
embeddedartists 0:6b68dac0d986 641 /*Setting for timeout problem */
embeddedartists 0:6b68dac0d986 642 LPC_MCI->DATATMR = 0x1FFFFFFF;
embeddedartists 0:6b68dac0d986 643
embeddedartists 0:6b68dac0d986 644 LPC_MCI->COMMAND = 0;
embeddedartists 0:6b68dac0d986 645 mci_WriteDelay();
embeddedartists 0:6b68dac0d986 646
embeddedartists 0:6b68dac0d986 647 LPC_MCI->DATACTRL = 0;
embeddedartists 0:6b68dac0d986 648 mci_WriteDelay();
embeddedartists 0:6b68dac0d986 649
embeddedartists 0:6b68dac0d986 650 /* clear all pending interrupts */
embeddedartists 0:6b68dac0d986 651 LPC_MCI->CLEAR = SDC_CLEAR_ALL;
embeddedartists 0:6b68dac0d986 652
embeddedartists 0:6b68dac0d986 653 /* Power-up SDC Peripheral */
embeddedartists 0:6b68dac0d986 654 mci_PowerControl(PowerUp, 0);
embeddedartists 0:6b68dac0d986 655
embeddedartists 0:6b68dac0d986 656 /* delays for the supply output is stable*/
embeddedartists 0:6b68dac0d986 657 for (uint32_t i = 0; i < 0x80000; i++ ) {}
embeddedartists 0:6b68dac0d986 658
embeddedartists 0:6b68dac0d986 659 mci_SetClock(SDC_IDENT_CLOCK_RATE);
embeddedartists 0:6b68dac0d986 660 mci_ClockControl(SDC_CLOCK_ENABLE, true);
embeddedartists 0:6b68dac0d986 661
embeddedartists 0:6b68dac0d986 662 /* Power-on SDC Interface */
embeddedartists 0:6b68dac0d986 663 mci_PowerControl(PowerOn, 0);
embeddedartists 0:6b68dac0d986 664
embeddedartists 0:6b68dac0d986 665 NVIC_SetVector(MCI_IRQn, (uint32_t) mymciirq);
embeddedartists 0:6b68dac0d986 666 NVIC_EnableIRQ(MCI_IRQn);
embeddedartists 0:6b68dac0d986 667
embeddedartists 38:420cdc281467 668 /* Initialize GPDMA controller */
embeddedartists 38:420cdc281467 669 _eventDmaChannel = GPDMA::instance().acquireChannel(mydmairq);
embeddedartists 0:6b68dac0d986 670 }
embeddedartists 0:6b68dac0d986 671
embeddedartists 42:bbfe299d4a0c 672 int MCIFileSystem::init() {
embeddedartists 42:bbfe299d4a0c 673 uint32_t val = core_util_atomic_incr_u32(&_init_ref_count, 1);
embeddedartists 42:bbfe299d4a0c 674
embeddedartists 42:bbfe299d4a0c 675 if (val != 1) {
embeddedartists 42:bbfe299d4a0c 676 return BD_ERROR_OK;
embeddedartists 42:bbfe299d4a0c 677 }
embeddedartists 0:6b68dac0d986 678
embeddedartists 42:bbfe299d4a0c 679 debug_if(MCI_DBG, "mcifs:disk_initialize()\n");
embeddedartists 0:6b68dac0d986 680
embeddedartists 0:6b68dac0d986 681 if (!cardInserted()) {
embeddedartists 42:bbfe299d4a0c 682 debug("No card detected\r\n");
embeddedartists 42:bbfe299d4a0c 683 return BD_ERROR_DEVICE_ERROR;
embeddedartists 0:6b68dac0d986 684 }
embeddedartists 0:6b68dac0d986 685
embeddedartists 0:6b68dac0d986 686 /* Initialize the Card Data Strucutre */
embeddedartists 0:6b68dac0d986 687 memset(&_sdCardInfo, 0, sizeof(SDMMC_CARD_T));
embeddedartists 0:6b68dac0d986 688
embeddedartists 0:6b68dac0d986 689 /* Enumerate the card once detected. Note this function may block for a little while. */
embeddedartists 0:6b68dac0d986 690 int ret = mci_Acquire();
embeddedartists 0:6b68dac0d986 691 if (ret != 1) {
embeddedartists 0:6b68dac0d986 692 debug("Card Acquire failed... got %d, but expected 1\r\n", ret);
embeddedartists 42:bbfe299d4a0c 693 return BD_ERROR_DEVICE_ERROR;
embeddedartists 0:6b68dac0d986 694 }
embeddedartists 0:6b68dac0d986 695
embeddedartists 42:bbfe299d4a0c 696 _is_initialized = true;
embeddedartists 42:bbfe299d4a0c 697 return BD_ERROR_OK;
embeddedartists 0:6b68dac0d986 698 }
embeddedartists 0:6b68dac0d986 699
embeddedartists 42:bbfe299d4a0c 700 int MCIFileSystem::deinit() {
embeddedartists 42:bbfe299d4a0c 701
embeddedartists 42:bbfe299d4a0c 702 if (!_is_initialized) {
embeddedartists 42:bbfe299d4a0c 703 return BD_ERROR_OK;
embeddedartists 42:bbfe299d4a0c 704 }
embeddedartists 42:bbfe299d4a0c 705
embeddedartists 42:bbfe299d4a0c 706 uint32_t val = core_util_atomic_decr_u32(&_init_ref_count, 1);
embeddedartists 42:bbfe299d4a0c 707
embeddedartists 42:bbfe299d4a0c 708 if (val) {
embeddedartists 42:bbfe299d4a0c 709 return BD_ERROR_OK;
embeddedartists 0:6b68dac0d986 710 }
embeddedartists 0:6b68dac0d986 711
embeddedartists 42:bbfe299d4a0c 712 _is_initialized = false;
embeddedartists 42:bbfe299d4a0c 713 return BD_ERROR_OK;
embeddedartists 0:6b68dac0d986 714 }
embeddedartists 0:6b68dac0d986 715
embeddedartists 42:bbfe299d4a0c 716 int MCIFileSystem::program(const void *buffer, bd_addr_t addr, bd_size_t size) {
embeddedartists 42:bbfe299d4a0c 717 ReturnCode status;
embeddedartists 42:bbfe299d4a0c 718
embeddedartists 42:bbfe299d4a0c 719 debug_if(MCI_DBG, "mcifs:disk_write(%#x, %llu, %llu)\n", (uint32_t)buffer, addr, size);
embeddedartists 42:bbfe299d4a0c 720
embeddedartists 42:bbfe299d4a0c 721 if (!_is_initialized) {
embeddedartists 42:bbfe299d4a0c 722 return BD_ERROR_DEVICE_ERROR;
embeddedartists 0:6b68dac0d986 723 }
embeddedartists 42:bbfe299d4a0c 724
embeddedartists 42:bbfe299d4a0c 725 /* need to convert from number of bytes to blocks */
embeddedartists 42:bbfe299d4a0c 726 addr = addr / MMC_SECTOR_SIZE;
embeddedartists 42:bbfe299d4a0c 727 size = size / MMC_SECTOR_SIZE;
embeddedartists 42:bbfe299d4a0c 728
embeddedartists 42:bbfe299d4a0c 729 status = mci_WriteBlocks((void*)buffer, addr, size);
embeddedartists 42:bbfe299d4a0c 730 if (status != SDC_RET_OK) {
embeddedartists 42:bbfe299d4a0c 731 return status;
embeddedartists 0:6b68dac0d986 732 }
embeddedartists 0:6b68dac0d986 733
embeddedartists 42:bbfe299d4a0c 734 return BD_ERROR_OK;
embeddedartists 0:6b68dac0d986 735 }
embeddedartists 0:6b68dac0d986 736
embeddedartists 42:bbfe299d4a0c 737 int MCIFileSystem::read(void *buffer, bd_addr_t addr, bd_size_t size) {
embeddedartists 42:bbfe299d4a0c 738 ReturnCode status;
embeddedartists 42:bbfe299d4a0c 739 debug_if(MCI_DBG, "mcifs:disk_read(%#x, %llu, %llu)\n", (uint32_t)buffer, addr, size);
embeddedartists 42:bbfe299d4a0c 740
embeddedartists 42:bbfe299d4a0c 741 if (!_is_initialized) {
embeddedartists 42:bbfe299d4a0c 742 return BD_ERROR_DEVICE_ERROR;
embeddedartists 42:bbfe299d4a0c 743 }
embeddedartists 42:bbfe299d4a0c 744
embeddedartists 42:bbfe299d4a0c 745 /* need to convert from number of bytes to blocks */
embeddedartists 42:bbfe299d4a0c 746 addr = addr / MMC_SECTOR_SIZE;
embeddedartists 42:bbfe299d4a0c 747 size = size / MMC_SECTOR_SIZE;
embeddedartists 42:bbfe299d4a0c 748
embeddedartists 42:bbfe299d4a0c 749 status = mci_ReadBlocks(buffer, addr, size);
embeddedartists 42:bbfe299d4a0c 750 if (status != SDC_RET_OK) {
embeddedartists 42:bbfe299d4a0c 751 return status;
embeddedartists 42:bbfe299d4a0c 752 }
embeddedartists 42:bbfe299d4a0c 753
embeddedartists 42:bbfe299d4a0c 754 return BD_ERROR_OK;
embeddedartists 0:6b68dac0d986 755 }
embeddedartists 0:6b68dac0d986 756
embeddedartists 42:bbfe299d4a0c 757 int MCIFileSystem::sync()
embeddedartists 0:6b68dac0d986 758 {
embeddedartists 42:bbfe299d4a0c 759 debug_if(MCI_DBG, "mcifs:disk_sync()\n");
embeddedartists 42:bbfe299d4a0c 760
embeddedartists 42:bbfe299d4a0c 761 if (!_is_initialized) {
embeddedartists 42:bbfe299d4a0c 762 return BD_ERROR_OK;
embeddedartists 42:bbfe299d4a0c 763 }
embeddedartists 42:bbfe299d4a0c 764
embeddedartists 42:bbfe299d4a0c 765 uint32_t end = us_ticker_read() + 50*1000; // 50ms
embeddedartists 42:bbfe299d4a0c 766 while (us_ticker_read() < end)
embeddedartists 0:6b68dac0d986 767 {
embeddedartists 42:bbfe299d4a0c 768 if (mci_GetCardStatus() & R1_READY_FOR_DATA)
embeddedartists 42:bbfe299d4a0c 769 {
embeddedartists 42:bbfe299d4a0c 770 // card is ready
embeddedartists 42:bbfe299d4a0c 771 return BD_ERROR_OK;
embeddedartists 42:bbfe299d4a0c 772 }
embeddedartists 0:6b68dac0d986 773 }
embeddedartists 42:bbfe299d4a0c 774
embeddedartists 42:bbfe299d4a0c 775 // timeout while waiting for card to get ready
embeddedartists 42:bbfe299d4a0c 776 return SDC_RET_TIMEOUT;
embeddedartists 0:6b68dac0d986 777 }
embeddedartists 0:6b68dac0d986 778
embeddedartists 42:bbfe299d4a0c 779 bd_size_t MCIFileSystem::get_read_size() const
embeddedartists 42:bbfe299d4a0c 780 {
embeddedartists 42:bbfe299d4a0c 781 return MMC_SECTOR_SIZE;
embeddedartists 42:bbfe299d4a0c 782 }
embeddedartists 42:bbfe299d4a0c 783
embeddedartists 42:bbfe299d4a0c 784 bd_size_t MCIFileSystem::get_program_size() const
embeddedartists 0:6b68dac0d986 785 {
embeddedartists 42:bbfe299d4a0c 786 return MMC_SECTOR_SIZE;
embeddedartists 42:bbfe299d4a0c 787 }
embeddedartists 42:bbfe299d4a0c 788
embeddedartists 42:bbfe299d4a0c 789 bd_size_t MCIFileSystem::size() const
embeddedartists 42:bbfe299d4a0c 790 {
embeddedartists 42:bbfe299d4a0c 791 return _sdCardInfo.block_len * MMC_SECTOR_SIZE;
embeddedartists 42:bbfe299d4a0c 792 }
embeddedartists 42:bbfe299d4a0c 793
embeddedartists 42:bbfe299d4a0c 794 const char *MCIFileSystem::get_type() const
embeddedartists 42:bbfe299d4a0c 795 {
embeddedartists 42:bbfe299d4a0c 796 return "MCI";
embeddedartists 0:6b68dac0d986 797 }
embeddedartists 0:6b68dac0d986 798
embeddedartists 0:6b68dac0d986 799 void MCIFileSystem::mci_MCIIRQHandler()
embeddedartists 0:6b68dac0d986 800 {
embeddedartists 0:6b68dac0d986 801 int32_t Ret;
embeddedartists 0:6b68dac0d986 802
embeddedartists 0:6b68dac0d986 803 Ret = mci_IRQHandler(NULL, 0, NULL, 0);
embeddedartists 0:6b68dac0d986 804 if(Ret < 0) {
embeddedartists 0:6b68dac0d986 805 _eventSuccess = false;
embeddedartists 0:6b68dac0d986 806 _eventReceived = true;
embeddedartists 0:6b68dac0d986 807 }
embeddedartists 0:6b68dac0d986 808 }
embeddedartists 0:6b68dac0d986 809
embeddedartists 0:6b68dac0d986 810 void MCIFileSystem::mci_DMAIRQHandler()
embeddedartists 0:6b68dac0d986 811 {
embeddedartists 38:420cdc281467 812 _eventSuccess = LPC_GPDMA->IntTCStat & (1<<_eventDmaChannel);
embeddedartists 0:6b68dac0d986 813 _eventReceived = true;
embeddedartists 38:420cdc281467 814 LPC_GPDMA->IntTCClear = (1<<_eventDmaChannel);
embeddedartists 38:420cdc281467 815 LPC_GPDMA->IntErrClr = (1<<_eventDmaChannel);
embeddedartists 0:6b68dac0d986 816 }
embeddedartists 0:6b68dac0d986 817
embeddedartists 0:6b68dac0d986 818 /******************************************************************************
embeddedartists 0:6b68dac0d986 819 * Private Functions
embeddedartists 0:6b68dac0d986 820 *****************************************************************************/
embeddedartists 0:6b68dac0d986 821
embeddedartists 38:420cdc281467 822 static bool gpdma_transfer_to_mci(GPDMA::DMAChannels ChannelNum,
embeddedartists 38:420cdc281467 823 uint32_t src,
embeddedartists 38:420cdc281467 824 uint32_t Size)
embeddedartists 38:420cdc281467 825 {
embeddedartists 38:420cdc281467 826 GPDMA::GPDMA_Channel_CFG_T cfg;
embeddedartists 38:420cdc281467 827 cfg.ChannelNum = ChannelNum;
embeddedartists 38:420cdc281467 828 cfg.TransferType = GPDMA::FlowControl_M2P_Ctrl_Periph;
embeddedartists 38:420cdc281467 829 cfg.TransferSize = Size;
embeddedartists 38:420cdc281467 830 cfg.TransferWidth = 0;
embeddedartists 38:420cdc281467 831 cfg.SrcAddr = src;
embeddedartists 38:420cdc281467 832 cfg.DstAddr = (uint32_t) (&LPC_MCI->FIFO);
embeddedartists 38:420cdc281467 833
embeddedartists 38:420cdc281467 834 uint32_t ctrl_word =
embeddedartists 38:420cdc281467 835 GPDMA_DMACCxControl_TransferSize((uint32_t) cfg.TransferSize)
embeddedartists 38:420cdc281467 836 | GPDMA_DMACCxControl_SBSize(GPDMA_BSIZE_8)
embeddedartists 38:420cdc281467 837 | GPDMA_DMACCxControl_DBSize(GPDMA_BSIZE_8)
embeddedartists 38:420cdc281467 838 | GPDMA_DMACCxControl_SWidth(GPDMA_WIDTH_WORD)
embeddedartists 38:420cdc281467 839 | GPDMA_DMACCxControl_DWidth(GPDMA_WIDTH_WORD)
embeddedartists 38:420cdc281467 840 | GPDMA_DMACCxControl_DestTransUseAHBMaster1
embeddedartists 38:420cdc281467 841 | GPDMA_DMACCxControl_SI
embeddedartists 38:420cdc281467 842 | GPDMA_DMACCxControl_I;
embeddedartists 38:420cdc281467 843
embeddedartists 38:420cdc281467 844 /* Select SD card interface in the DMA MUX*/
embeddedartists 38:420cdc281467 845 LPC_SC->DMAREQSEL &= ~(1 << 1);
embeddedartists 38:420cdc281467 846
embeddedartists 38:420cdc281467 847 return GPDMA::instance().transfer(&cfg, ctrl_word, 0, GPDMA_CONN_MEMORY, GPDMA_CONN_SDC);
embeddedartists 38:420cdc281467 848 }
embeddedartists 38:420cdc281467 849
embeddedartists 38:420cdc281467 850 static bool gpdma_transfer_from_mci(GPDMA::DMAChannels ChannelNum,
embeddedartists 38:420cdc281467 851 uint32_t dst,
embeddedartists 38:420cdc281467 852 uint32_t Size)
embeddedartists 38:420cdc281467 853 {
embeddedartists 38:420cdc281467 854 GPDMA::GPDMA_Channel_CFG_T cfg;
embeddedartists 38:420cdc281467 855 cfg.ChannelNum = ChannelNum;
embeddedartists 38:420cdc281467 856 cfg.TransferType = GPDMA::FlowControl_P2M_Ctrl_Periph;
embeddedartists 38:420cdc281467 857 cfg.TransferSize = Size;
embeddedartists 38:420cdc281467 858 cfg.TransferWidth = 0;
embeddedartists 38:420cdc281467 859 cfg.SrcAddr = (uint32_t) (&LPC_MCI->FIFO);
embeddedartists 38:420cdc281467 860 cfg.DstAddr = dst;
embeddedartists 38:420cdc281467 861
embeddedartists 38:420cdc281467 862 uint32_t ctrl_word =
embeddedartists 38:420cdc281467 863 GPDMA_DMACCxControl_TransferSize((uint32_t) cfg.TransferSize)
embeddedartists 38:420cdc281467 864 | GPDMA_DMACCxControl_SBSize(GPDMA_BSIZE_8)
embeddedartists 38:420cdc281467 865 | GPDMA_DMACCxControl_DBSize(GPDMA_BSIZE_8)
embeddedartists 38:420cdc281467 866 | GPDMA_DMACCxControl_SWidth(GPDMA_WIDTH_WORD)
embeddedartists 38:420cdc281467 867 | GPDMA_DMACCxControl_DWidth(GPDMA_WIDTH_WORD)
embeddedartists 38:420cdc281467 868 | GPDMA_DMACCxControl_SrcTransUseAHBMaster1
embeddedartists 38:420cdc281467 869 | GPDMA_DMACCxControl_DI
embeddedartists 38:420cdc281467 870 | GPDMA_DMACCxControl_I;
embeddedartists 38:420cdc281467 871
embeddedartists 38:420cdc281467 872 /* Select SD card interface in the DMA MUX*/
embeddedartists 38:420cdc281467 873 LPC_SC->DMAREQSEL &= ~(1 << 1);
embeddedartists 38:420cdc281467 874
embeddedartists 38:420cdc281467 875 return GPDMA::instance().transfer(&cfg, ctrl_word, 0, GPDMA_CONN_SDC, GPDMA_CONN_MEMORY);
embeddedartists 38:420cdc281467 876 }
embeddedartists 38:420cdc281467 877
embeddedartists 0:6b68dac0d986 878 bool MCIFileSystem::cardInserted() const
embeddedartists 0:6b68dac0d986 879 {
embeddedartists 0:6b68dac0d986 880 // If no card detect pin is given, then assume that a card is inserted.
embeddedartists 0:6b68dac0d986 881 // If a pin is specified then use that to determing the presence of a card.
embeddedartists 0:6b68dac0d986 882 return ((_cardDetect == NULL) || (_cardDetect->read() == 0));
embeddedartists 0:6b68dac0d986 883 }
embeddedartists 0:6b68dac0d986 884
embeddedartists 0:6b68dac0d986 885
embeddedartists 0:6b68dac0d986 886
embeddedartists 0:6b68dac0d986 887 int32_t MCIFileSystem::mci_Acquire()
embeddedartists 0:6b68dac0d986 888 {
embeddedartists 0:6b68dac0d986 889 int32_t Ret;
embeddedartists 0:6b68dac0d986 890
embeddedartists 0:6b68dac0d986 891 /* Initialize card info */
embeddedartists 0:6b68dac0d986 892 _sdCardInfo.speed = SDC_TRAN_CLOCK_RATE;
embeddedartists 0:6b68dac0d986 893 _sdCardInfo.card_type = 0;
embeddedartists 0:6b68dac0d986 894
embeddedartists 0:6b68dac0d986 895 /* During identification phase, the clock should be less than
embeddedartists 0:6b68dac0d986 896 400Khz. Once we pass this phase, the normal clock can be set up
embeddedartists 0:6b68dac0d986 897 to 25Mhz on SD card and 20Mhz on MMC card. */
embeddedartists 0:6b68dac0d986 898 mci_SetClock(SDC_IDENT_CLOCK_RATE);
embeddedartists 0:6b68dac0d986 899
embeddedartists 0:6b68dac0d986 900 /* Clear Open Drain output control for SD */
embeddedartists 0:6b68dac0d986 901 mci_PowerControl(PowerOn, 0);
embeddedartists 0:6b68dac0d986 902
embeddedartists 0:6b68dac0d986 903 /* Card Reset */
embeddedartists 0:6b68dac0d986 904 Ret = mci_ExecuteCmd(SD_GO_IDLE_STATE, 0, NULL);
embeddedartists 0:6b68dac0d986 905 if (Ret != 0) {
embeddedartists 0:6b68dac0d986 906 return Ret;
embeddedartists 0:6b68dac0d986 907 }
embeddedartists 0:6b68dac0d986 908
embeddedartists 41:e06e764ff4fd 909 ThisThread::sleep_for(ACQUIRE_DELAY);
embeddedartists 0:6b68dac0d986 910
embeddedartists 0:6b68dac0d986 911 /* Send interface operation condiftion */
embeddedartists 0:6b68dac0d986 912 Ret = mci_SendIfCond();
embeddedartists 0:6b68dac0d986 913 if (Ret == SDC_RET_BAD_PARAMETERS) {
embeddedartists 0:6b68dac0d986 914 return Ret; /* Non-compatible voltage range or check pattern is not correct */
embeddedartists 0:6b68dac0d986 915
embeddedartists 0:6b68dac0d986 916 }
embeddedartists 0:6b68dac0d986 917 /* Get Card Type */
embeddedartists 0:6b68dac0d986 918 if (Ret == SDC_RET_OK) {/* Ver2.00 or later SD Memory Card*/
embeddedartists 0:6b68dac0d986 919 bool CCS;
embeddedartists 0:6b68dac0d986 920 uint32_t OCR = SDC_OCR_27_36;
embeddedartists 0:6b68dac0d986 921 _sdCardInfo.card_type |= CARD_TYPE_SD;
embeddedartists 0:6b68dac0d986 922 Ret = mci_SendAppOpCond(0, true, &OCR, &CCS);
embeddedartists 0:6b68dac0d986 923 if (CCS) { /* High Capacity or Extended Capacity SD Memory Card */
embeddedartists 0:6b68dac0d986 924 _sdCardInfo.card_type |= CARD_TYPE_HC;
embeddedartists 0:6b68dac0d986 925 }
embeddedartists 0:6b68dac0d986 926 }
embeddedartists 0:6b68dac0d986 927 else { /*Ver2.00 or later SD Memory Card(voltage mismatch) or Ver1.X SD Memory Card
embeddedartists 0:6b68dac0d986 928 or not SD Memory Card*/
embeddedartists 0:6b68dac0d986 929 bool CCS;
embeddedartists 0:6b68dac0d986 930 uint32_t OCR = SDC_OCR_27_36;
embeddedartists 0:6b68dac0d986 931 Ret = mci_SendAppOpCond(0, false, &OCR, &CCS);
embeddedartists 0:6b68dac0d986 932 if (Ret == SDC_RET_OK) {
embeddedartists 0:6b68dac0d986 933 _sdCardInfo.card_type |= CARD_TYPE_SD;
embeddedartists 0:6b68dac0d986 934 }
embeddedartists 0:6b68dac0d986 935 else if (Ret == SDC_RET_BAD_PARAMETERS) {
embeddedartists 0:6b68dac0d986 936 return Ret;
embeddedartists 0:6b68dac0d986 937 }
embeddedartists 0:6b68dac0d986 938 else { /* MMC Card setup */
embeddedartists 0:6b68dac0d986 939 uint32_t OCR;
embeddedartists 0:6b68dac0d986 940 /* Enter to Open Drain mode */
embeddedartists 0:6b68dac0d986 941 mci_PowerControl(PowerOn, SDC_PWR_OPENDRAIN);
embeddedartists 41:e06e764ff4fd 942 ThisThread::sleep_for(ACQUIRE_DELAY);
embeddedartists 0:6b68dac0d986 943 Ret = mci_SendOpCond(&OCR);
embeddedartists 0:6b68dac0d986 944 if (Ret != SDC_RET_OK) {
embeddedartists 0:6b68dac0d986 945 return Ret;
embeddedartists 0:6b68dac0d986 946 }
embeddedartists 0:6b68dac0d986 947
embeddedartists 0:6b68dac0d986 948 }
embeddedartists 0:6b68dac0d986 949 }
embeddedartists 0:6b68dac0d986 950
embeddedartists 0:6b68dac0d986 951 /* Read CID */
embeddedartists 0:6b68dac0d986 952 mci_GetCID(_sdCardInfo.cid);
embeddedartists 0:6b68dac0d986 953
embeddedartists 0:6b68dac0d986 954 /* RCA send, for SD get RCA */
embeddedartists 0:6b68dac0d986 955 if (_sdCardInfo.card_type & CARD_TYPE_SD) {
embeddedartists 0:6b68dac0d986 956 mci_GetAddr(&_sdCardInfo.rca);
embeddedartists 0:6b68dac0d986 957 }
embeddedartists 0:6b68dac0d986 958 else {
embeddedartists 0:6b68dac0d986 959 _sdCardInfo.rca = 1;
embeddedartists 0:6b68dac0d986 960 mci_SetAddr(_sdCardInfo.rca);
embeddedartists 0:6b68dac0d986 961 mci_PowerControl(PowerOn, 0); /* enter to push-pull mode */
embeddedartists 0:6b68dac0d986 962 }
embeddedartists 0:6b68dac0d986 963
embeddedartists 0:6b68dac0d986 964 /* Get CSD */
embeddedartists 0:6b68dac0d986 965 mci_GetCSD(_sdCardInfo.rca, _sdCardInfo.csd);
embeddedartists 0:6b68dac0d986 966
embeddedartists 0:6b68dac0d986 967 /* Compute card size, block size and no. of blocks based on CSD response recived. */
embeddedartists 0:6b68dac0d986 968 if (_sdCardInfo.cid[0]) {
embeddedartists 0:6b68dac0d986 969 mci_ProcessCSD();
embeddedartists 0:6b68dac0d986 970
embeddedartists 0:6b68dac0d986 971 if (mci_SetTranState(_sdCardInfo.rca) != SDC_RET_OK) {
embeddedartists 0:6b68dac0d986 972 return 0;
embeddedartists 0:6b68dac0d986 973 }
embeddedartists 0:6b68dac0d986 974
embeddedartists 0:6b68dac0d986 975 if (mci_GetCardState() != SDMMC_TRAN_ST) {
embeddedartists 0:6b68dac0d986 976 return 0;
embeddedartists 0:6b68dac0d986 977 }
embeddedartists 0:6b68dac0d986 978
embeddedartists 0:6b68dac0d986 979 if (mci_SetCardParams() != 0) {
embeddedartists 0:6b68dac0d986 980 return 0;
embeddedartists 0:6b68dac0d986 981 }
embeddedartists 0:6b68dac0d986 982 }
embeddedartists 0:6b68dac0d986 983
embeddedartists 0:6b68dac0d986 984 return (_sdCardInfo.cid[0]) ? 1 : 0;
embeddedartists 0:6b68dac0d986 985 }
embeddedartists 0:6b68dac0d986 986
embeddedartists 0:6b68dac0d986 987 uint32_t MCIFileSystem::mci_GetCardStatus() const
embeddedartists 0:6b68dac0d986 988 {
embeddedartists 0:6b68dac0d986 989 uint32_t Status;
embeddedartists 0:6b68dac0d986 990 mci_GetStatus(_sdCardInfo.rca, &Status);
embeddedartists 0:6b68dac0d986 991 return Status;
embeddedartists 0:6b68dac0d986 992 }
embeddedartists 0:6b68dac0d986 993
embeddedartists 0:6b68dac0d986 994 MCIFileSystem::CardState MCIFileSystem::mci_GetCardState() const
embeddedartists 0:6b68dac0d986 995 {
embeddedartists 0:6b68dac0d986 996 uint32_t Status;
embeddedartists 0:6b68dac0d986 997 volatile int32_t Ret;
embeddedartists 0:6b68dac0d986 998
embeddedartists 0:6b68dac0d986 999 /* get current state of the card */
embeddedartists 0:6b68dac0d986 1000 Ret = mci_GetStatus(_sdCardInfo.rca, &Status);
embeddedartists 0:6b68dac0d986 1001
embeddedartists 0:6b68dac0d986 1002 /* check card state in response */
embeddedartists 0:6b68dac0d986 1003 return (CardState) R1_CURRENT_STATE(Status);
embeddedartists 0:6b68dac0d986 1004 }
embeddedartists 0:6b68dac0d986 1005
embeddedartists 0:6b68dac0d986 1006 MCIFileSystem::ReturnCode MCIFileSystem::mci_StopTransmission(uint32_t rca) const
embeddedartists 0:6b68dac0d986 1007 {
embeddedartists 0:6b68dac0d986 1008 uint32_t Status;
embeddedartists 0:6b68dac0d986 1009 ReturnCode Ret = SDC_RET_FAILED;
embeddedartists 0:6b68dac0d986 1010 response_t Response;
embeddedartists 0:6b68dac0d986 1011 uint32_t RetryCnt = 20;
embeddedartists 0:6b68dac0d986 1012
embeddedartists 0:6b68dac0d986 1013 Ret = mci_GetStatus(rca, &Status);
embeddedartists 0:6b68dac0d986 1014 if (Ret != SDC_RET_OK) {
embeddedartists 0:6b68dac0d986 1015 return SDC_RET_ERR_STATE;
embeddedartists 0:6b68dac0d986 1016 }
embeddedartists 0:6b68dac0d986 1017
embeddedartists 0:6b68dac0d986 1018 if (R1_CURRENT_STATE(Status) == SDMMC_TRAN_ST) {
embeddedartists 0:6b68dac0d986 1019 return SDC_RET_OK;
embeddedartists 0:6b68dac0d986 1020 }
embeddedartists 0:6b68dac0d986 1021
embeddedartists 0:6b68dac0d986 1022 if ((R1_CURRENT_STATE(Status) != SDMMC_DATA_ST) &&
embeddedartists 0:6b68dac0d986 1023 (R1_CURRENT_STATE(Status) != SDMMC_RCV_ST)) {
embeddedartists 0:6b68dac0d986 1024 return SDC_RET_ERR_STATE;
embeddedartists 0:6b68dac0d986 1025 }
embeddedartists 0:6b68dac0d986 1026
embeddedartists 0:6b68dac0d986 1027 while (RetryCnt > 0) {
embeddedartists 0:6b68dac0d986 1028 Ret = mci_ExecuteCmd(SD_CMD12_STOP_TRANSMISSION, 0, &Response);
embeddedartists 0:6b68dac0d986 1029 if (Ret == SDC_RET_OK) {
embeddedartists 0:6b68dac0d986 1030 if (mci_CheckR1Response(Response.Data[0], &Ret)) {
embeddedartists 0:6b68dac0d986 1031 if (Ret != SDC_RET_OK) {
embeddedartists 0:6b68dac0d986 1032 return Ret;
embeddedartists 0:6b68dac0d986 1033 }
embeddedartists 0:6b68dac0d986 1034 Ret = mci_GetStatus(rca, &Status);
embeddedartists 0:6b68dac0d986 1035 if ((R1_CURRENT_STATE(Status) == SDMMC_TRAN_ST) || (R1_CURRENT_STATE(Status) == SDMMC_PRG_ST)) {
embeddedartists 0:6b68dac0d986 1036 return SDC_RET_OK;
embeddedartists 0:6b68dac0d986 1037 }
embeddedartists 0:6b68dac0d986 1038 return SDC_RET_ERR_STATE;
embeddedartists 0:6b68dac0d986 1039 }
embeddedartists 0:6b68dac0d986 1040 }
embeddedartists 0:6b68dac0d986 1041 RetryCnt--;
embeddedartists 0:6b68dac0d986 1042 }
embeddedartists 0:6b68dac0d986 1043 return Ret;
embeddedartists 0:6b68dac0d986 1044 }
embeddedartists 0:6b68dac0d986 1045
embeddedartists 0:6b68dac0d986 1046 MCIFileSystem::ReturnCode MCIFileSystem::mci_ReadBlocks(void *buffer, int32_t startBlock, int32_t blockNum)
embeddedartists 0:6b68dac0d986 1047 {
embeddedartists 0:6b68dac0d986 1048 ReturnCode Ret = SDC_RET_FAILED;
embeddedartists 0:6b68dac0d986 1049 int32_t ByteNum = blockNum * MMC_SECTOR_SIZE;
embeddedartists 0:6b68dac0d986 1050
embeddedartists 0:6b68dac0d986 1051 do
embeddedartists 0:6b68dac0d986 1052 {
embeddedartists 0:6b68dac0d986 1053 /* if card is not acquired return immediately */
embeddedartists 0:6b68dac0d986 1054 if (( startBlock < 0) || ( (startBlock + blockNum) > _sdCardInfo.blocknr) ) {
embeddedartists 0:6b68dac0d986 1055 Ret = SDC_RET_NOT_READY;
embeddedartists 0:6b68dac0d986 1056 break;
embeddedartists 0:6b68dac0d986 1057 }
embeddedartists 0:6b68dac0d986 1058
embeddedartists 0:6b68dac0d986 1059 /* Put to tran state */
embeddedartists 0:6b68dac0d986 1060 Ret = mci_SetTranState(_sdCardInfo.rca);
embeddedartists 0:6b68dac0d986 1061 if (Ret != SDC_RET_OK) {
embeddedartists 0:6b68dac0d986 1062 break;
embeddedartists 0:6b68dac0d986 1063 }
embeddedartists 0:6b68dac0d986 1064
embeddedartists 0:6b68dac0d986 1065 LPC_MCI->MASK0 = SDC_MASK0_DATA | SDC_MASK0_RXDATAERR;
embeddedartists 0:6b68dac0d986 1066
embeddedartists 0:6b68dac0d986 1067 /* DMA Setup */
embeddedartists 38:420cdc281467 1068 mci_SetupEventWakeup();
embeddedartists 38:420cdc281467 1069 gpdma_transfer_from_mci(_eventDmaChannel, (uint32_t)buffer, ByteNum);
embeddedartists 0:6b68dac0d986 1070
embeddedartists 0:6b68dac0d986 1071 /* set transfer information */
embeddedartists 0:6b68dac0d986 1072 mci_SetDataTransfer(blockNum, true, DATA_TIMER_VALUE_R);
embeddedartists 0:6b68dac0d986 1073
embeddedartists 0:6b68dac0d986 1074 Ret = _readBlocks(_sdCardInfo.card_type, startBlock, blockNum);
embeddedartists 0:6b68dac0d986 1075 if (Ret == SDC_RET_OK) {
embeddedartists 0:6b68dac0d986 1076 /* Wait for transfer Finish */
embeddedartists 0:6b68dac0d986 1077 if (mci_WaitForEvent() != 0) {
embeddedartists 0:6b68dac0d986 1078 Ret = SDC_RET_FAILED;
embeddedartists 0:6b68dac0d986 1079 }
embeddedartists 0:6b68dac0d986 1080 } else {
embeddedartists 0:6b68dac0d986 1081 Ret = SDC_RET_FAILED;
embeddedartists 0:6b68dac0d986 1082 }
embeddedartists 0:6b68dac0d986 1083
embeddedartists 38:420cdc281467 1084 GPDMA::instance().stopTransfer(_eventDmaChannel);
embeddedartists 0:6b68dac0d986 1085
embeddedartists 0:6b68dac0d986 1086 if ((blockNum > 1) || (mci_GetCardState() == SDMMC_DATA_ST)) {
embeddedartists 0:6b68dac0d986 1087 /* Send Stop transmission command */
embeddedartists 0:6b68dac0d986 1088 mci_StopTransmission(_sdCardInfo.rca);
embeddedartists 0:6b68dac0d986 1089 }
embeddedartists 0:6b68dac0d986 1090
embeddedartists 0:6b68dac0d986 1091 /* Wait for card to enter tran state */
embeddedartists 0:6b68dac0d986 1092 while (mci_GetCardState() != SDMMC_TRAN_ST) {}
embeddedartists 0:6b68dac0d986 1093
embeddedartists 0:6b68dac0d986 1094 } while(false);
embeddedartists 0:6b68dac0d986 1095
embeddedartists 0:6b68dac0d986 1096 return Ret;
embeddedartists 0:6b68dac0d986 1097 }
embeddedartists 0:6b68dac0d986 1098
embeddedartists 0:6b68dac0d986 1099 MCIFileSystem::ReturnCode MCIFileSystem::mci_WriteBlocks(void *buffer, int32_t startBlock, int32_t blockNum)
embeddedartists 0:6b68dac0d986 1100 {
embeddedartists 0:6b68dac0d986 1101 ReturnCode Ret = SDC_RET_FAILED;
embeddedartists 0:6b68dac0d986 1102
embeddedartists 0:6b68dac0d986 1103 do
embeddedartists 0:6b68dac0d986 1104 {
embeddedartists 0:6b68dac0d986 1105 /* if card is not acquired return immediately */
embeddedartists 0:6b68dac0d986 1106 if (( startBlock < 0) || ( (startBlock + blockNum) > _sdCardInfo.blocknr) ) {
embeddedartists 0:6b68dac0d986 1107 Ret = SDC_RET_NOT_READY;
embeddedartists 0:6b68dac0d986 1108 break;
embeddedartists 0:6b68dac0d986 1109 }
embeddedartists 0:6b68dac0d986 1110
embeddedartists 0:6b68dac0d986 1111 /* Put to tran state */
embeddedartists 0:6b68dac0d986 1112 Ret = mci_SetTranState(_sdCardInfo.rca);
embeddedartists 0:6b68dac0d986 1113 if (Ret != SDC_RET_OK) {
embeddedartists 0:6b68dac0d986 1114 break;
embeddedartists 0:6b68dac0d986 1115 }
embeddedartists 0:6b68dac0d986 1116
embeddedartists 0:6b68dac0d986 1117 Ret = _writeBlocks(_sdCardInfo.card_type, startBlock, blockNum);
embeddedartists 0:6b68dac0d986 1118 if (Ret != SDC_RET_OK) {
embeddedartists 0:6b68dac0d986 1119 break;
embeddedartists 0:6b68dac0d986 1120 }
embeddedartists 0:6b68dac0d986 1121
embeddedartists 0:6b68dac0d986 1122 /*Wait for card enter to rcv state*/
embeddedartists 0:6b68dac0d986 1123 while (mci_GetCardState() != SDMMC_RCV_ST) {}
embeddedartists 0:6b68dac0d986 1124
embeddedartists 0:6b68dac0d986 1125 LPC_MCI->MASK0 = SDC_MASK0_DATA | SDC_MASK0_TXDATAERR;
embeddedartists 0:6b68dac0d986 1126
embeddedartists 0:6b68dac0d986 1127 /* DMA Setup */
embeddedartists 38:420cdc281467 1128 mci_SetupEventWakeup();
embeddedartists 38:420cdc281467 1129 gpdma_transfer_to_mci(_eventDmaChannel, (uint32_t)buffer, blockNum*MMC_SECTOR_SIZE);
embeddedartists 0:6b68dac0d986 1130
embeddedartists 0:6b68dac0d986 1131 /* set transfer information */
embeddedartists 0:6b68dac0d986 1132 mci_SetDataTransfer(blockNum, false, DATA_TIMER_VALUE_W);
embeddedartists 0:6b68dac0d986 1133
embeddedartists 0:6b68dac0d986 1134 /* Wait for transfer done */
embeddedartists 0:6b68dac0d986 1135 if (mci_WaitForEvent() != 0) {
embeddedartists 0:6b68dac0d986 1136 Ret = SDC_RET_FAILED;
embeddedartists 0:6b68dac0d986 1137 }
embeddedartists 0:6b68dac0d986 1138
embeddedartists 0:6b68dac0d986 1139 if ((blockNum > 1) || (mci_GetCardState() == SDMMC_RCV_ST)) {
embeddedartists 0:6b68dac0d986 1140 /* Send Stop transmission command */
embeddedartists 0:6b68dac0d986 1141 mci_StopTransmission(_sdCardInfo.rca);
embeddedartists 0:6b68dac0d986 1142 }
embeddedartists 0:6b68dac0d986 1143
embeddedartists 0:6b68dac0d986 1144 /* Wait for card to enter tran state */
embeddedartists 0:6b68dac0d986 1145 while (mci_GetCardState() != SDMMC_TRAN_ST) {}
embeddedartists 0:6b68dac0d986 1146
embeddedartists 0:6b68dac0d986 1147 } while (false);
embeddedartists 0:6b68dac0d986 1148
embeddedartists 0:6b68dac0d986 1149 return Ret;
embeddedartists 0:6b68dac0d986 1150 }
embeddedartists 0:6b68dac0d986 1151
embeddedartists 0:6b68dac0d986 1152 void MCIFileSystem::mci_SetClock(uint32_t freq) const
embeddedartists 0:6b68dac0d986 1153 {
embeddedartists 0:6b68dac0d986 1154 uint32_t PClk;
embeddedartists 0:6b68dac0d986 1155 uint32_t ClkValue = 0;
embeddedartists 0:6b68dac0d986 1156
embeddedartists 0:6b68dac0d986 1157 PClk = PeripheralClock;
embeddedartists 0:6b68dac0d986 1158
embeddedartists 0:6b68dac0d986 1159 ClkValue = (PClk + 2 * freq - 1) / (2 * freq);
embeddedartists 0:6b68dac0d986 1160 if (ClkValue > 0) {
embeddedartists 0:6b68dac0d986 1161 ClkValue -= 1;
embeddedartists 0:6b68dac0d986 1162 }
embeddedartists 0:6b68dac0d986 1163 uint32_t temp;
embeddedartists 0:6b68dac0d986 1164 temp = (LPC_MCI->CLOCK & (~SDC_CLOCK_CLKDIV_BITMASK));
embeddedartists 0:6b68dac0d986 1165 LPC_MCI->CLOCK = temp | (SDC_CLOCK_CLKDIV(ClkValue));
embeddedartists 0:6b68dac0d986 1166 mci_WriteDelay();
embeddedartists 0:6b68dac0d986 1167 }
embeddedartists 0:6b68dac0d986 1168
embeddedartists 0:6b68dac0d986 1169 void MCIFileSystem::mci_ClockControl(ClockControl ctrlType, bool enable) const
embeddedartists 0:6b68dac0d986 1170 {
embeddedartists 0:6b68dac0d986 1171 if (enable) {
embeddedartists 0:6b68dac0d986 1172 LPC_MCI->CLOCK |= (1 << ctrlType);
embeddedartists 0:6b68dac0d986 1173 }
embeddedartists 0:6b68dac0d986 1174 else {
embeddedartists 0:6b68dac0d986 1175 LPC_MCI->CLOCK &= (~(1 << ctrlType));
embeddedartists 0:6b68dac0d986 1176 }
embeddedartists 0:6b68dac0d986 1177 mci_WriteDelay();
embeddedartists 0:6b68dac0d986 1178 }
embeddedartists 0:6b68dac0d986 1179
embeddedartists 0:6b68dac0d986 1180 void MCIFileSystem::mci_PowerControl(power_ctrl_t powerMode, uint32_t flag) const
embeddedartists 0:6b68dac0d986 1181 {
embeddedartists 0:6b68dac0d986 1182 LPC_MCI->POWER = (powerMode & 0x3) | flag;
embeddedartists 0:6b68dac0d986 1183 mci_WriteDelay();
embeddedartists 0:6b68dac0d986 1184 }
embeddedartists 0:6b68dac0d986 1185
embeddedartists 0:6b68dac0d986 1186 MCIFileSystem::ReturnCode MCIFileSystem::mci_ExecuteCmd(uint32_t Command, uint32_t Arg, response_t* pResp) const
embeddedartists 0:6b68dac0d986 1187 {
embeddedartists 0:6b68dac0d986 1188 ReturnCode Ret = SDC_RET_FAILED;
embeddedartists 0:6b68dac0d986 1189
embeddedartists 0:6b68dac0d986 1190 /* Send Command to card */
embeddedartists 0:6b68dac0d986 1191 Ret = mci_SendCmd(Command, Arg, CMD_TIMEOUT);
embeddedartists 0:6b68dac0d986 1192 if (Ret != SDC_RET_OK) {
embeddedartists 0:6b68dac0d986 1193 return Ret;
embeddedartists 0:6b68dac0d986 1194 }
embeddedartists 0:6b68dac0d986 1195
embeddedartists 0:6b68dac0d986 1196 /* Get response (if any) */
embeddedartists 0:6b68dac0d986 1197 if ((Command & SDC_COMMAND_RSP_BITMASK) != SDC_COMMAND_NO_RSP) {
embeddedartists 0:6b68dac0d986 1198
embeddedartists 0:6b68dac0d986 1199 mci_GetResp(pResp);
embeddedartists 0:6b68dac0d986 1200
embeddedartists 0:6b68dac0d986 1201 /* If the response is not R1, in the response field, the Expected Cmd data
embeddedartists 0:6b68dac0d986 1202 won't be the same as the CMD data in SendCmd(). Below four cmds have
embeddedartists 0:6b68dac0d986 1203 R2 or R3 response. We don't need to check if MCI_RESP_CMD is the same
embeddedartists 0:6b68dac0d986 1204 as the Expected or not. */
embeddedartists 0:6b68dac0d986 1205 if ((SDC_COMMAND_INDEX(Command) != MMC_SEND_OP_COND) &&
embeddedartists 0:6b68dac0d986 1206 (SDC_COMMAND_INDEX(Command) != SD_APP_OP_COND) &&
embeddedartists 0:6b68dac0d986 1207 (SDC_COMMAND_INDEX(Command) != MMC_ALL_SEND_CID) &&
embeddedartists 0:6b68dac0d986 1208 (SDC_COMMAND_INDEX(Command) != MMC_SEND_CSD) &&
embeddedartists 0:6b68dac0d986 1209 (pResp->CmdIndex != SDC_COMMAND_INDEX(Command))) {
embeddedartists 0:6b68dac0d986 1210 return SDC_RET_CMD_FAILED;
embeddedartists 0:6b68dac0d986 1211 }
embeddedartists 0:6b68dac0d986 1212 }
embeddedartists 0:6b68dac0d986 1213
embeddedartists 0:6b68dac0d986 1214 return SDC_RET_OK;
embeddedartists 0:6b68dac0d986 1215 }
embeddedartists 0:6b68dac0d986 1216
embeddedartists 0:6b68dac0d986 1217 MCIFileSystem::ReturnCode MCIFileSystem::mci_SendIfCond() const
embeddedartists 0:6b68dac0d986 1218 {
embeddedartists 0:6b68dac0d986 1219 ReturnCode Ret = SDC_RET_FAILED;
embeddedartists 0:6b68dac0d986 1220 response_t Response;
embeddedartists 0:6b68dac0d986 1221 uint32_t RetryCnt = 20;
embeddedartists 0:6b68dac0d986 1222
embeddedartists 0:6b68dac0d986 1223 while (RetryCnt > 0) {
embeddedartists 0:6b68dac0d986 1224 Ret = mci_ExecuteCmd(SD_CMD8_SEND_IF_COND, (CMD8_VOLTAGESUPPLIED_27_36 | CMD8_CHECKPATTERN(
embeddedartists 0:6b68dac0d986 1225 CMD8_DEF_PATTERN)), &Response);
embeddedartists 0:6b68dac0d986 1226 if (Ret == SDC_RET_OK) {
embeddedartists 0:6b68dac0d986 1227 if ((Response.Data[0] & CMDRESP_R7_VOLTAGE_ACCEPTED) &&
embeddedartists 0:6b68dac0d986 1228 (CMDRESP_R7_CHECK_PATTERN(Response.Data[0]) == CMD8_DEF_PATTERN)) {
embeddedartists 0:6b68dac0d986 1229 return SDC_RET_OK;
embeddedartists 0:6b68dac0d986 1230 }
embeddedartists 0:6b68dac0d986 1231 return SDC_RET_BAD_PARAMETERS;
embeddedartists 0:6b68dac0d986 1232 }
embeddedartists 0:6b68dac0d986 1233 RetryCnt--;
embeddedartists 0:6b68dac0d986 1234 }
embeddedartists 0:6b68dac0d986 1235 return Ret;
embeddedartists 0:6b68dac0d986 1236 }
embeddedartists 0:6b68dac0d986 1237
embeddedartists 0:6b68dac0d986 1238 MCIFileSystem::ReturnCode MCIFileSystem::mci_SendOpCond(uint32_t *pOCR) const
embeddedartists 0:6b68dac0d986 1239 {
embeddedartists 0:6b68dac0d986 1240 ReturnCode Ret = SDC_RET_FAILED;
embeddedartists 0:6b68dac0d986 1241 response_t Response;
embeddedartists 0:6b68dac0d986 1242 uint32_t RetryCnt = 0x200;
embeddedartists 0:6b68dac0d986 1243
embeddedartists 0:6b68dac0d986 1244 while (RetryCnt > 0) {
embeddedartists 0:6b68dac0d986 1245 Ret = mci_ExecuteCmd(SD_CMD1_SEND_OP_COND, SDC_OCR_27_36, &Response);
embeddedartists 0:6b68dac0d986 1246 if (Ret == SDC_RET_OK) {
embeddedartists 0:6b68dac0d986 1247 *pOCR = Response.Data[0];
embeddedartists 0:6b68dac0d986 1248 if (*pOCR & SDC_OCR_IDLE) {
embeddedartists 0:6b68dac0d986 1249 if ((Response.Data[0] & SDC_OCR_27_36) != SDC_OCR_27_36) {
embeddedartists 0:6b68dac0d986 1250 return SDC_RET_BAD_PARAMETERS;
embeddedartists 0:6b68dac0d986 1251 }
embeddedartists 0:6b68dac0d986 1252 return SDC_RET_OK;
embeddedartists 0:6b68dac0d986 1253 }
embeddedartists 0:6b68dac0d986 1254 }
embeddedartists 0:6b68dac0d986 1255 RetryCnt--;
embeddedartists 0:6b68dac0d986 1256 }
embeddedartists 0:6b68dac0d986 1257 return SDC_RET_FAILED;
embeddedartists 0:6b68dac0d986 1258 }
embeddedartists 0:6b68dac0d986 1259
embeddedartists 0:6b68dac0d986 1260 MCIFileSystem::ReturnCode MCIFileSystem::mci_SendAppOpCond(uint16_t rca, bool hcs, uint32_t *pOcr, bool *pCCS) const
embeddedartists 0:6b68dac0d986 1261 {
embeddedartists 0:6b68dac0d986 1262 ReturnCode Ret = SDC_RET_FAILED;
embeddedartists 0:6b68dac0d986 1263 response_t Response;
embeddedartists 0:6b68dac0d986 1264 uint32_t Argument;
embeddedartists 0:6b68dac0d986 1265 uint32_t RetryCnt = 0x2000; /* The host repeatedly issues ACMD41 for at least 1 second or
embeddedartists 0:6b68dac0d986 1266 until the busy bit are set to 1 */
embeddedartists 0:6b68dac0d986 1267
embeddedartists 0:6b68dac0d986 1268 Argument = ACMD41_OCR(*pOcr);
embeddedartists 0:6b68dac0d986 1269 if (hcs) {
embeddedartists 0:6b68dac0d986 1270 Argument |= ACMD41_HCS;
embeddedartists 0:6b68dac0d986 1271 }
embeddedartists 0:6b68dac0d986 1272
embeddedartists 0:6b68dac0d986 1273 while (RetryCnt > 0) {
embeddedartists 0:6b68dac0d986 1274 Ret = mci_SendAppCmd(rca);
embeddedartists 0:6b68dac0d986 1275 if (Ret == SDC_RET_OK) {
embeddedartists 0:6b68dac0d986 1276 Ret = mci_ExecuteCmd(SD_ACMD41_SD_SEND_OP_COND, Argument, &Response);
embeddedartists 0:6b68dac0d986 1277 if (Ret == SDC_RET_OK) {
embeddedartists 0:6b68dac0d986 1278 if (Response.Data[0] & CMDRESP_R3_INIT_COMPLETE) {
embeddedartists 0:6b68dac0d986 1279 if (*pOcr == 0) {
embeddedartists 0:6b68dac0d986 1280 *pOcr = CMDRESP_R3_OCR_VAL(Response.Data[0]);
embeddedartists 0:6b68dac0d986 1281 return SDC_RET_OK;
embeddedartists 0:6b68dac0d986 1282 }
embeddedartists 0:6b68dac0d986 1283 if ((CMDRESP_R3_OCR_VAL(Response.Data[0]) & *pOcr) != *pOcr) {
embeddedartists 0:6b68dac0d986 1284 return SDC_RET_BAD_PARAMETERS;
embeddedartists 0:6b68dac0d986 1285 }
embeddedartists 0:6b68dac0d986 1286 *pCCS = (Response.Data[0] & CMDRESP_R3_HC_CCS) ? true : false;
embeddedartists 0:6b68dac0d986 1287 return SDC_RET_OK;
embeddedartists 0:6b68dac0d986 1288 }
embeddedartists 0:6b68dac0d986 1289 }
embeddedartists 0:6b68dac0d986 1290 }
embeddedartists 0:6b68dac0d986 1291 else {
embeddedartists 0:6b68dac0d986 1292 //If we abort here then some cards will go undetected, better to keep retrying
embeddedartists 0:6b68dac0d986 1293 //return Ret;
embeddedartists 0:6b68dac0d986 1294 }
embeddedartists 0:6b68dac0d986 1295 RetryCnt--;
embeddedartists 0:6b68dac0d986 1296 }
embeddedartists 0:6b68dac0d986 1297 return SDC_RET_FAILED;
embeddedartists 0:6b68dac0d986 1298 }
embeddedartists 0:6b68dac0d986 1299
embeddedartists 0:6b68dac0d986 1300 MCIFileSystem::ReturnCode MCIFileSystem::mci_GetCID(uint32_t *pCID) const
embeddedartists 0:6b68dac0d986 1301 {
embeddedartists 0:6b68dac0d986 1302 ReturnCode Ret = SDC_RET_FAILED;
embeddedartists 0:6b68dac0d986 1303 response_t Response;
embeddedartists 0:6b68dac0d986 1304 uint32_t RetryCnt = 20;
embeddedartists 0:6b68dac0d986 1305
embeddedartists 0:6b68dac0d986 1306 while (RetryCnt > 0) {
embeddedartists 0:6b68dac0d986 1307 Ret = mci_ExecuteCmd(SD_CMD2_ALL_SEND_CID, 0, &Response);
embeddedartists 0:6b68dac0d986 1308 if (Ret == SDC_RET_OK) {
embeddedartists 0:6b68dac0d986 1309 pCID[3] = Response.Data[0];
embeddedartists 0:6b68dac0d986 1310 pCID[2] = Response.Data[1];
embeddedartists 0:6b68dac0d986 1311 pCID[1] = Response.Data[2];
embeddedartists 0:6b68dac0d986 1312 pCID[0] = Response.Data[3];
embeddedartists 0:6b68dac0d986 1313 return SDC_RET_OK;
embeddedartists 0:6b68dac0d986 1314 }
embeddedartists 0:6b68dac0d986 1315 RetryCnt--;
embeddedartists 0:6b68dac0d986 1316 }
embeddedartists 0:6b68dac0d986 1317 return Ret;
embeddedartists 0:6b68dac0d986 1318 }
embeddedartists 0:6b68dac0d986 1319
embeddedartists 0:6b68dac0d986 1320 MCIFileSystem::ReturnCode MCIFileSystem::mci_SetAddr(uint16_t addr) const
embeddedartists 0:6b68dac0d986 1321 {
embeddedartists 0:6b68dac0d986 1322 ReturnCode Ret = SDC_RET_FAILED;
embeddedartists 0:6b68dac0d986 1323 response_t Response;
embeddedartists 0:6b68dac0d986 1324 uint32_t RetryCnt = 20;
embeddedartists 0:6b68dac0d986 1325
embeddedartists 0:6b68dac0d986 1326 while (RetryCnt > 0) {
embeddedartists 0:6b68dac0d986 1327 Ret = mci_ExecuteCmd(SD_CMD3_SET_RELATIVE_ADDR, CMD3_RCA(addr), &Response);
embeddedartists 0:6b68dac0d986 1328 if (Ret == SDC_RET_OK) {
embeddedartists 0:6b68dac0d986 1329 if (mci_CheckR1Response(Response.Data[0], &Ret)) {
embeddedartists 0:6b68dac0d986 1330 return Ret;
embeddedartists 0:6b68dac0d986 1331 }
embeddedartists 0:6b68dac0d986 1332 }
embeddedartists 0:6b68dac0d986 1333 RetryCnt--;
embeddedartists 0:6b68dac0d986 1334 }
embeddedartists 0:6b68dac0d986 1335 return Ret;
embeddedartists 0:6b68dac0d986 1336 }
embeddedartists 0:6b68dac0d986 1337
embeddedartists 0:6b68dac0d986 1338 MCIFileSystem::ReturnCode MCIFileSystem::mci_GetAddr(uint16_t *pRCA) const
embeddedartists 0:6b68dac0d986 1339 {
embeddedartists 0:6b68dac0d986 1340 ReturnCode Ret = SDC_RET_FAILED;
embeddedartists 0:6b68dac0d986 1341 response_t Response;
embeddedartists 0:6b68dac0d986 1342 uint32_t RetryCnt = 20;
embeddedartists 0:6b68dac0d986 1343
embeddedartists 0:6b68dac0d986 1344 *pRCA = 0;
embeddedartists 0:6b68dac0d986 1345 while (RetryCnt > 0) {
embeddedartists 0:6b68dac0d986 1346 Ret = mci_ExecuteCmd(SD_CMD3_SEND_RELATIVE_ADDR, 0, &Response);
embeddedartists 0:6b68dac0d986 1347 if (Ret == SDC_RET_OK) {
embeddedartists 0:6b68dac0d986 1348 if (!(CMDRESP_R6_CARD_STATUS(Response.Data[0]) & R1_READY_FOR_DATA)) {
embeddedartists 0:6b68dac0d986 1349 Ret = SDC_RET_NOT_READY;
embeddedartists 0:6b68dac0d986 1350 }
embeddedartists 0:6b68dac0d986 1351 else if (R1_CURRENT_STATE(CMDRESP_R6_CARD_STATUS(Response.Data[0])) != SDMMC_STBY_ST) {
embeddedartists 0:6b68dac0d986 1352 Ret = SDC_RET_ERR_STATE;
embeddedartists 0:6b68dac0d986 1353 }
embeddedartists 0:6b68dac0d986 1354 else {
embeddedartists 0:6b68dac0d986 1355 *pRCA = CMDRESP_R6_RCA_VAL(Response.Data[0]);
embeddedartists 0:6b68dac0d986 1356 return SDC_RET_OK;
embeddedartists 0:6b68dac0d986 1357 }
embeddedartists 0:6b68dac0d986 1358 }
embeddedartists 0:6b68dac0d986 1359 RetryCnt--;
embeddedartists 0:6b68dac0d986 1360 }
embeddedartists 0:6b68dac0d986 1361 return Ret;
embeddedartists 0:6b68dac0d986 1362 }
embeddedartists 0:6b68dac0d986 1363
embeddedartists 0:6b68dac0d986 1364 MCIFileSystem::ReturnCode MCIFileSystem::mci_GetCSD(uint16_t rca, uint32_t *pCSD) const
embeddedartists 0:6b68dac0d986 1365 {
embeddedartists 0:6b68dac0d986 1366 ReturnCode Ret = SDC_RET_FAILED;
embeddedartists 0:6b68dac0d986 1367 response_t Response;
embeddedartists 0:6b68dac0d986 1368 uint32_t RetryCnt = 20;
embeddedartists 0:6b68dac0d986 1369
embeddedartists 0:6b68dac0d986 1370 while (RetryCnt > 0) {
embeddedartists 0:6b68dac0d986 1371 Ret = mci_ExecuteCmd(SD_CMD9_SEND_CSD, CMD9_RCA(rca), &Response);
embeddedartists 0:6b68dac0d986 1372 if (Ret == SDC_RET_OK) {
embeddedartists 0:6b68dac0d986 1373 pCSD[3] = Response.Data[0];
embeddedartists 0:6b68dac0d986 1374 pCSD[2] = Response.Data[1];
embeddedartists 0:6b68dac0d986 1375 pCSD[1] = Response.Data[2];
embeddedartists 0:6b68dac0d986 1376 pCSD[0] = Response.Data[3];
embeddedartists 0:6b68dac0d986 1377 return Ret;
embeddedartists 0:6b68dac0d986 1378 }
embeddedartists 0:6b68dac0d986 1379 RetryCnt--;
embeddedartists 0:6b68dac0d986 1380 }
embeddedartists 0:6b68dac0d986 1381 return Ret;
embeddedartists 0:6b68dac0d986 1382 }
embeddedartists 0:6b68dac0d986 1383
embeddedartists 0:6b68dac0d986 1384 MCIFileSystem::ReturnCode MCIFileSystem::mci_SelectCard(uint16_t addr) const
embeddedartists 0:6b68dac0d986 1385 {
embeddedartists 0:6b68dac0d986 1386 ReturnCode Ret = SDC_RET_FAILED;
embeddedartists 0:6b68dac0d986 1387 response_t Response;
embeddedartists 0:6b68dac0d986 1388 uint32_t RetryCnt = 20;
embeddedartists 0:6b68dac0d986 1389
embeddedartists 0:6b68dac0d986 1390 while (RetryCnt > 0) {
embeddedartists 0:6b68dac0d986 1391 Ret = mci_ExecuteCmd(SD_CMD7_SELECT_CARD, CMD7_RCA(addr), &Response);
embeddedartists 0:6b68dac0d986 1392 if (Ret == SDC_RET_OK) {
embeddedartists 0:6b68dac0d986 1393 if (mci_CheckR1Response(Response.Data[0], &Ret)) {
embeddedartists 0:6b68dac0d986 1394 return Ret;
embeddedartists 0:6b68dac0d986 1395 }
embeddedartists 0:6b68dac0d986 1396 }
embeddedartists 0:6b68dac0d986 1397 RetryCnt--;
embeddedartists 0:6b68dac0d986 1398 }
embeddedartists 0:6b68dac0d986 1399 return Ret;
embeddedartists 0:6b68dac0d986 1400 }
embeddedartists 0:6b68dac0d986 1401
embeddedartists 0:6b68dac0d986 1402 MCIFileSystem::ReturnCode MCIFileSystem::mci_GetStatus(uint16_t rca, uint32_t *pStatus) const
embeddedartists 0:6b68dac0d986 1403 {
embeddedartists 0:6b68dac0d986 1404 ReturnCode Ret = SDC_RET_FAILED;
embeddedartists 0:6b68dac0d986 1405 response_t Response;
embeddedartists 0:6b68dac0d986 1406 uint32_t RetryCnt = 20;
embeddedartists 0:6b68dac0d986 1407
embeddedartists 0:6b68dac0d986 1408 *pStatus = (uint32_t) -1;
embeddedartists 0:6b68dac0d986 1409 while (RetryCnt > 0) {
embeddedartists 0:6b68dac0d986 1410 Ret = mci_ExecuteCmd(SD_CMD13_SEND_STATUS, CMD13_RCA(rca), &Response);
embeddedartists 0:6b68dac0d986 1411 if (Ret == SDC_RET_OK) {
embeddedartists 0:6b68dac0d986 1412 mci_CheckR1Response(Response.Data[0], &Ret);
embeddedartists 0:6b68dac0d986 1413 *pStatus = Response.Data[0];
embeddedartists 0:6b68dac0d986 1414 return Ret;
embeddedartists 0:6b68dac0d986 1415 }
embeddedartists 0:6b68dac0d986 1416 RetryCnt--;
embeddedartists 0:6b68dac0d986 1417 }
embeddedartists 0:6b68dac0d986 1418 return Ret;
embeddedartists 0:6b68dac0d986 1419 }
embeddedartists 0:6b68dac0d986 1420
embeddedartists 0:6b68dac0d986 1421 void MCIFileSystem::mci_ProcessCSD()
embeddedartists 0:6b68dac0d986 1422 {
embeddedartists 0:6b68dac0d986 1423 int32_t CSize = 0;
embeddedartists 0:6b68dac0d986 1424 int32_t CSizeMult = 0;
embeddedartists 0:6b68dac0d986 1425 int32_t Mult = 0;
embeddedartists 0:6b68dac0d986 1426
embeddedartists 0:6b68dac0d986 1427 /* compute block length based on CSD response */
embeddedartists 0:6b68dac0d986 1428 _sdCardInfo.block_len = 1 << mci_GetBits(80, 83, _sdCardInfo.csd);
embeddedartists 0:6b68dac0d986 1429 if ((_sdCardInfo.card_type & CARD_TYPE_HC) && (_sdCardInfo.card_type & CARD_TYPE_SD)) {
embeddedartists 0:6b68dac0d986 1430 /* See section 5.3.3 CSD Register (CSD Version 2.0) of SD2.0 spec an explanation for the calculation of these values */
embeddedartists 0:6b68dac0d986 1431 CSize = mci_GetBits(48, 63, (uint32_t *) _sdCardInfo.csd) + 1;
embeddedartists 0:6b68dac0d986 1432 _sdCardInfo.blocknr = CSize << 10; /* 512 byte blocks */
embeddedartists 0:6b68dac0d986 1433 }
embeddedartists 0:6b68dac0d986 1434 else {
embeddedartists 0:6b68dac0d986 1435 /* See section 5.3 of the 4.1 revision of the MMC specs for an explanation for the calculation of these values */
embeddedartists 0:6b68dac0d986 1436 CSize = mci_GetBits(62, 73, (uint32_t *) _sdCardInfo.csd);
embeddedartists 0:6b68dac0d986 1437 CSizeMult = mci_GetBits(47, 49, (uint32_t *) _sdCardInfo.csd);
embeddedartists 0:6b68dac0d986 1438 Mult = 1 << (CSizeMult + 2);
embeddedartists 0:6b68dac0d986 1439 _sdCardInfo.blocknr = (CSize + 1) * Mult;
embeddedartists 0:6b68dac0d986 1440
embeddedartists 0:6b68dac0d986 1441 /* adjust blocknr to 512/block */
embeddedartists 0:6b68dac0d986 1442 if (_sdCardInfo.block_len > MMC_SECTOR_SIZE) {
embeddedartists 0:6b68dac0d986 1443 _sdCardInfo.blocknr = _sdCardInfo.blocknr * (_sdCardInfo.block_len >> 9);
embeddedartists 0:6b68dac0d986 1444 }
embeddedartists 0:6b68dac0d986 1445 }
embeddedartists 0:6b68dac0d986 1446
embeddedartists 0:6b68dac0d986 1447 _sdCardInfo.device_size = _sdCardInfo.blocknr << 9; /* blocknr * 512 */
embeddedartists 0:6b68dac0d986 1448 }
embeddedartists 0:6b68dac0d986 1449
embeddedartists 0:6b68dac0d986 1450 MCIFileSystem::ReturnCode MCIFileSystem::mci_SetBusWidth(uint16_t rca, uint8_t width) const
embeddedartists 0:6b68dac0d986 1451 {
embeddedartists 0:6b68dac0d986 1452 ReturnCode Ret = SDC_RET_FAILED;
embeddedartists 0:6b68dac0d986 1453 response_t Response;
embeddedartists 0:6b68dac0d986 1454 uint8_t RetryCnt = 0x20;
embeddedartists 0:6b68dac0d986 1455
embeddedartists 0:6b68dac0d986 1456 while (RetryCnt > 0) {
embeddedartists 0:6b68dac0d986 1457 Ret = mci_SendAppCmd(rca);
embeddedartists 0:6b68dac0d986 1458 if (Ret == SDC_RET_OK) {
embeddedartists 0:6b68dac0d986 1459 Ret = mci_ExecuteCmd(SD_ACMD6_SET_BUS_WIDTH, ACMD6_BUS_WIDTH(width), &Response);
embeddedartists 0:6b68dac0d986 1460 if (Ret == SDC_RET_OK) {
embeddedartists 0:6b68dac0d986 1461 if (mci_CheckR1Response(Response.Data[0], &Ret)) {
embeddedartists 0:6b68dac0d986 1462 return Ret;
embeddedartists 0:6b68dac0d986 1463 }
embeddedartists 0:6b68dac0d986 1464 }
embeddedartists 0:6b68dac0d986 1465 }
embeddedartists 0:6b68dac0d986 1466 RetryCnt--;
embeddedartists 0:6b68dac0d986 1467 }
embeddedartists 0:6b68dac0d986 1468 return SDC_RET_FAILED;
embeddedartists 0:6b68dac0d986 1469 }
embeddedartists 0:6b68dac0d986 1470
embeddedartists 0:6b68dac0d986 1471 MCIFileSystem::ReturnCode MCIFileSystem::mci_SetTranState(uint16_t rca) const
embeddedartists 0:6b68dac0d986 1472 {
embeddedartists 0:6b68dac0d986 1473 ReturnCode Ret = SDC_RET_OK;
embeddedartists 0:6b68dac0d986 1474 uint32_t status = 0;
embeddedartists 41:e06e764ff4fd 1475 CardState state;
embeddedartists 0:6b68dac0d986 1476
embeddedartists 0:6b68dac0d986 1477 /* get current state of the card */
embeddedartists 0:6b68dac0d986 1478 Ret = mci_GetStatus(rca, &status);
embeddedartists 0:6b68dac0d986 1479 if (Ret != SDC_RET_OK) {
embeddedartists 0:6b68dac0d986 1480 /* unable to get the card state. So return immediatly. */
embeddedartists 0:6b68dac0d986 1481 return Ret;
embeddedartists 0:6b68dac0d986 1482 }
embeddedartists 0:6b68dac0d986 1483
embeddedartists 0:6b68dac0d986 1484 /* check card state in response */
embeddedartists 41:e06e764ff4fd 1485 state = (CardState) R1_CURRENT_STATE(status);
embeddedartists 0:6b68dac0d986 1486 switch (state) {
embeddedartists 0:6b68dac0d986 1487 case SDMMC_STBY_ST:
embeddedartists 0:6b68dac0d986 1488 /* put card in 'Trans' state */
embeddedartists 0:6b68dac0d986 1489 Ret = mci_SelectCard(rca);
embeddedartists 0:6b68dac0d986 1490 if (Ret != SDC_RET_OK) {
embeddedartists 0:6b68dac0d986 1491 /* unable to put the card in Trans state. So return immediatly. */
embeddedartists 0:6b68dac0d986 1492 return Ret;
embeddedartists 0:6b68dac0d986 1493 }
embeddedartists 0:6b68dac0d986 1494 mci_GetStatus(rca, &status);
embeddedartists 41:e06e764ff4fd 1495 if (((CardState) R1_CURRENT_STATE(status)) != SDMMC_TRAN_ST) {
embeddedartists 0:6b68dac0d986 1496 return SDC_RET_ERR_STATE;
embeddedartists 0:6b68dac0d986 1497 }
embeddedartists 0:6b68dac0d986 1498 break;
embeddedartists 0:6b68dac0d986 1499
embeddedartists 0:6b68dac0d986 1500 case SDMMC_TRAN_ST:
embeddedartists 0:6b68dac0d986 1501 /*do nothing */
embeddedartists 0:6b68dac0d986 1502 break;
embeddedartists 0:6b68dac0d986 1503
embeddedartists 0:6b68dac0d986 1504 default:
embeddedartists 0:6b68dac0d986 1505 /* card shouldn't be in other states so return */
embeddedartists 0:6b68dac0d986 1506 return SDC_RET_ERR_STATE;
embeddedartists 0:6b68dac0d986 1507 }
embeddedartists 0:6b68dac0d986 1508
embeddedartists 0:6b68dac0d986 1509 return SDC_RET_OK;
embeddedartists 0:6b68dac0d986 1510 }
embeddedartists 0:6b68dac0d986 1511
embeddedartists 0:6b68dac0d986 1512 MCIFileSystem::ReturnCode MCIFileSystem::mci_SetBlockLength(uint32_t rca, uint32_t block_len) const
embeddedartists 0:6b68dac0d986 1513 {
embeddedartists 0:6b68dac0d986 1514 ReturnCode Ret = SDC_RET_FAILED;
embeddedartists 0:6b68dac0d986 1515 response_t Response;
embeddedartists 0:6b68dac0d986 1516 uint8_t RetryCnt = 0x20;
embeddedartists 0:6b68dac0d986 1517
embeddedartists 0:6b68dac0d986 1518 while (RetryCnt > 0) {
embeddedartists 0:6b68dac0d986 1519 Ret = mci_ExecuteCmd(SD_CMD16_SET_BLOCKLEN, block_len, &Response);
embeddedartists 0:6b68dac0d986 1520 if (Ret == SDC_RET_OK) {
embeddedartists 0:6b68dac0d986 1521 if (mci_CheckR1Response(Response.Data[0], &Ret)) {
embeddedartists 0:6b68dac0d986 1522 return Ret;
embeddedartists 0:6b68dac0d986 1523 }
embeddedartists 0:6b68dac0d986 1524 }
embeddedartists 0:6b68dac0d986 1525 RetryCnt--;
embeddedartists 0:6b68dac0d986 1526 }
embeddedartists 0:6b68dac0d986 1527 return SDC_RET_FAILED;
embeddedartists 0:6b68dac0d986 1528 }
embeddedartists 0:6b68dac0d986 1529
embeddedartists 0:6b68dac0d986 1530 MCIFileSystem::ReturnCode MCIFileSystem::mci_SetCardParams() const
embeddedartists 0:6b68dac0d986 1531 {
embeddedartists 0:6b68dac0d986 1532 ReturnCode Ret;
embeddedartists 0:6b68dac0d986 1533
embeddedartists 0:6b68dac0d986 1534 mci_SetClock(SDC_TRAN_CLOCK_RATE);
embeddedartists 0:6b68dac0d986 1535 if (_sdCardInfo.card_type & CARD_TYPE_SD) {
embeddedartists 0:6b68dac0d986 1536 mci_ClockControl(SDC_CLOCK_WIDEBUS_MODE, true);
embeddedartists 0:6b68dac0d986 1537 Ret = mci_SetBusWidth(_sdCardInfo.rca, ACMD6_BUS_WIDTH_4);
embeddedartists 0:6b68dac0d986 1538 if (Ret != SDC_RET_OK) {
embeddedartists 0:6b68dac0d986 1539 return Ret;
embeddedartists 0:6b68dac0d986 1540 }
embeddedartists 0:6b68dac0d986 1541 }
embeddedartists 0:6b68dac0d986 1542 else {
embeddedartists 0:6b68dac0d986 1543 mci_ClockControl(SDC_CLOCK_WIDEBUS_MODE, false);
embeddedartists 0:6b68dac0d986 1544 }
embeddedartists 0:6b68dac0d986 1545
embeddedartists 0:6b68dac0d986 1546 /* set block length */
embeddedartists 0:6b68dac0d986 1547 Ret = mci_SetBlockLength(_sdCardInfo.rca, MMC_SECTOR_SIZE);
embeddedartists 0:6b68dac0d986 1548 return Ret;
embeddedartists 0:6b68dac0d986 1549 }
embeddedartists 0:6b68dac0d986 1550
embeddedartists 0:6b68dac0d986 1551 bool MCIFileSystem::mci_CheckR1Response(uint32_t resp, ReturnCode* pCheckResult) const
embeddedartists 0:6b68dac0d986 1552 {
embeddedartists 0:6b68dac0d986 1553 bool Ret = true;
embeddedartists 0:6b68dac0d986 1554
embeddedartists 0:6b68dac0d986 1555 if (!(resp & R1_READY_FOR_DATA)) {
embeddedartists 0:6b68dac0d986 1556 *pCheckResult = SDC_RET_NOT_READY;
embeddedartists 0:6b68dac0d986 1557 Ret = false;
embeddedartists 0:6b68dac0d986 1558 }
embeddedartists 0:6b68dac0d986 1559 else if (R1_STATUS(resp)) {
embeddedartists 0:6b68dac0d986 1560 *pCheckResult = SDC_RET_FAILED;
embeddedartists 0:6b68dac0d986 1561 }
embeddedartists 0:6b68dac0d986 1562 else {
embeddedartists 0:6b68dac0d986 1563 *pCheckResult = SDC_RET_OK;
embeddedartists 0:6b68dac0d986 1564 }
embeddedartists 0:6b68dac0d986 1565 return Ret;
embeddedartists 0:6b68dac0d986 1566 }
embeddedartists 0:6b68dac0d986 1567
embeddedartists 0:6b68dac0d986 1568 void MCIFileSystem::mci_WriteDelay() const
embeddedartists 0:6b68dac0d986 1569 {
embeddedartists 31:d47cffcb0a3e 1570 wait_us(10);
embeddedartists 0:6b68dac0d986 1571 }
embeddedartists 0:6b68dac0d986 1572
embeddedartists 0:6b68dac0d986 1573 MCIFileSystem::ReturnCode MCIFileSystem::mci_SendCmd(uint32_t Command, uint32_t Arg, uint32_t timeout) const
embeddedartists 0:6b68dac0d986 1574 {
embeddedartists 0:6b68dac0d986 1575 ReturnCode ret = SDC_RET_TIMEOUT;
embeddedartists 0:6b68dac0d986 1576 uint32_t Status;
embeddedartists 0:6b68dac0d986 1577
embeddedartists 0:6b68dac0d986 1578 /* Set Command Info */
embeddedartists 0:6b68dac0d986 1579 mci_SetCommand(Command, Arg);
embeddedartists 0:6b68dac0d986 1580
embeddedartists 0:6b68dac0d986 1581 while (timeout) {
embeddedartists 0:6b68dac0d986 1582
embeddedartists 0:6b68dac0d986 1583 Status = LPC_MCI->STATUS;
embeddedartists 0:6b68dac0d986 1584
embeddedartists 0:6b68dac0d986 1585 /* check if command was sent */
embeddedartists 0:6b68dac0d986 1586 if (((Command & SDC_COMMAND_RSP_BITMASK) == SDC_COMMAND_NO_RSP) && (Status & SDC_STATUS_CMDSENT)) {
embeddedartists 0:6b68dac0d986 1587 ret = SDC_RET_OK;
embeddedartists 0:6b68dac0d986 1588 break;
embeddedartists 0:6b68dac0d986 1589 }
embeddedartists 0:6b68dac0d986 1590 /* check if response was received */
embeddedartists 0:6b68dac0d986 1591 if (Status & SDC_STATUS_CMDRESPEND) {
embeddedartists 0:6b68dac0d986 1592 ret = SDC_RET_OK;
embeddedartists 0:6b68dac0d986 1593 break;
embeddedartists 0:6b68dac0d986 1594 }
embeddedartists 0:6b68dac0d986 1595
embeddedartists 0:6b68dac0d986 1596 /* check command sending status */
embeddedartists 0:6b68dac0d986 1597 if (Status & SDC_STATUS_CMDERR) {
embeddedartists 0:6b68dac0d986 1598 if (Status & SDC_STATUS_CMDCRCFAIL) {
embeddedartists 0:6b68dac0d986 1599 if ((SDC_COMMAND_INDEX(Command) == MMC_SEND_OP_COND) ||
embeddedartists 0:6b68dac0d986 1600 (SDC_COMMAND_INDEX(Command) == SD_APP_OP_COND) ||
embeddedartists 0:6b68dac0d986 1601 (SDC_COMMAND_INDEX(Command) == MMC_STOP_TRANSMISSION)) {
embeddedartists 0:6b68dac0d986 1602 ret = SDC_RET_OK; /* ignore CRC error if it's a resp for SEND_OP_COND or STOP_TRANSMISSION. */
embeddedartists 0:6b68dac0d986 1603 break;
embeddedartists 0:6b68dac0d986 1604 }
embeddedartists 0:6b68dac0d986 1605 }
embeddedartists 0:6b68dac0d986 1606 ret = SDC_RET_CMD_FAILED;
embeddedartists 0:6b68dac0d986 1607 break;
embeddedartists 0:6b68dac0d986 1608 }
embeddedartists 0:6b68dac0d986 1609
embeddedartists 0:6b68dac0d986 1610 timeout--;
embeddedartists 0:6b68dac0d986 1611 }
embeddedartists 0:6b68dac0d986 1612
embeddedartists 0:6b68dac0d986 1613 mci_ResetCommand();
embeddedartists 0:6b68dac0d986 1614
embeddedartists 0:6b68dac0d986 1615 return ret;
embeddedartists 0:6b68dac0d986 1616 }
embeddedartists 0:6b68dac0d986 1617
embeddedartists 0:6b68dac0d986 1618 MCIFileSystem::ReturnCode MCIFileSystem::mci_SendAppCmd(uint16_t rca) const
embeddedartists 0:6b68dac0d986 1619 {
embeddedartists 0:6b68dac0d986 1620 ReturnCode Ret = SDC_RET_FAILED;
embeddedartists 0:6b68dac0d986 1621 response_t Response;
embeddedartists 0:6b68dac0d986 1622 uint32_t RetryCnt = 20;
embeddedartists 0:6b68dac0d986 1623
embeddedartists 0:6b68dac0d986 1624 while (RetryCnt > 0) {
embeddedartists 0:6b68dac0d986 1625 Ret = mci_ExecuteCmd(SD_CMD55_APP_CMD, CMD55_RCA(rca), &Response);
embeddedartists 0:6b68dac0d986 1626 if (Ret == SDC_RET_OK) {
embeddedartists 0:6b68dac0d986 1627 if (mci_CheckR1Response(Response.Data[0], &Ret)) {
embeddedartists 0:6b68dac0d986 1628 if (Ret != SDC_RET_OK) {
embeddedartists 0:6b68dac0d986 1629 return Ret;
embeddedartists 0:6b68dac0d986 1630 }
embeddedartists 0:6b68dac0d986 1631 if (Response.Data[0] & R1_APP_CMD) {
embeddedartists 0:6b68dac0d986 1632 return SDC_RET_OK;
embeddedartists 0:6b68dac0d986 1633 }
embeddedartists 0:6b68dac0d986 1634 else {
embeddedartists 0:6b68dac0d986 1635 Ret = SDC_RET_FAILED;
embeddedartists 0:6b68dac0d986 1636 }
embeddedartists 0:6b68dac0d986 1637 }
embeddedartists 0:6b68dac0d986 1638 }
embeddedartists 0:6b68dac0d986 1639 RetryCnt--;
embeddedartists 0:6b68dac0d986 1640 }
embeddedartists 0:6b68dac0d986 1641 return SDC_RET_FAILED;
embeddedartists 0:6b68dac0d986 1642 }
embeddedartists 0:6b68dac0d986 1643
embeddedartists 0:6b68dac0d986 1644 void MCIFileSystem::mci_SetDataTransfer(uint16_t BlockNum, bool DirFromCard, uint32_t Timeout) const
embeddedartists 0:6b68dac0d986 1645 {
embeddedartists 0:6b68dac0d986 1646 uint32_t DataCtrl = 0;
embeddedartists 0:6b68dac0d986 1647 LPC_MCI->DATATMR = Timeout;
embeddedartists 0:6b68dac0d986 1648 LPC_MCI->DATALEN = BlockNum * 512;
embeddedartists 0:6b68dac0d986 1649
embeddedartists 0:6b68dac0d986 1650 DataCtrl = SDC_DATACTRL_ENABLE;
embeddedartists 0:6b68dac0d986 1651 // DataCtrl mode=block, block size=512byte
embeddedartists 0:6b68dac0d986 1652 DataCtrl |= (0x9 << 4);
embeddedartists 0:6b68dac0d986 1653 if (DirFromCard) {
embeddedartists 0:6b68dac0d986 1654 DataCtrl |= (0x1 << 1);
embeddedartists 0:6b68dac0d986 1655 }
embeddedartists 0:6b68dac0d986 1656 DataCtrl |= SDC_DATACTRL_DMA_ENABLE;
embeddedartists 0:6b68dac0d986 1657 LPC_MCI->DATACTRL = DataCtrl;
embeddedartists 0:6b68dac0d986 1658 mci_WriteDelay();
embeddedartists 0:6b68dac0d986 1659 }
embeddedartists 0:6b68dac0d986 1660
embeddedartists 0:6b68dac0d986 1661 void MCIFileSystem::mci_GetResp(response_t* pResp) const
embeddedartists 0:6b68dac0d986 1662 {
embeddedartists 0:6b68dac0d986 1663 pResp->CmdIndex = SDC_RESPCOMMAND_VAL(LPC_MCI->RESP_CMD);
embeddedartists 0:6b68dac0d986 1664 pResp->Data[0] = LPC_MCI->RESP0;
embeddedartists 0:6b68dac0d986 1665 if (CardStatusNumBytes == 4) {
embeddedartists 0:6b68dac0d986 1666 pResp->Data[1] = LPC_MCI->RESP1;
embeddedartists 0:6b68dac0d986 1667 pResp->Data[2] = LPC_MCI->RESP2;
embeddedartists 0:6b68dac0d986 1668 pResp->Data[3] = LPC_MCI->RESP3;
embeddedartists 0:6b68dac0d986 1669 }
embeddedartists 0:6b68dac0d986 1670 }
embeddedartists 0:6b68dac0d986 1671
embeddedartists 0:6b68dac0d986 1672 uint32_t MCIFileSystem::mci_GetBits(int32_t start, int32_t end, uint32_t *data) const
embeddedartists 0:6b68dac0d986 1673 {
embeddedartists 0:6b68dac0d986 1674 uint32_t v;
embeddedartists 0:6b68dac0d986 1675 uint32_t i = end >> 5;
embeddedartists 0:6b68dac0d986 1676 uint32_t j = start & 0x1f;
embeddedartists 0:6b68dac0d986 1677
embeddedartists 0:6b68dac0d986 1678 if (i == (start >> 5)) {
embeddedartists 0:6b68dac0d986 1679 v = (data[i] >> j);
embeddedartists 0:6b68dac0d986 1680 }
embeddedartists 0:6b68dac0d986 1681 else {
embeddedartists 0:6b68dac0d986 1682 v = ((data[i] << (32 - j)) | (data[start >> 5] >> j));
embeddedartists 0:6b68dac0d986 1683 }
embeddedartists 0:6b68dac0d986 1684
embeddedartists 0:6b68dac0d986 1685 return v & ((1 << (end - start + 1)) - 1);
embeddedartists 0:6b68dac0d986 1686 }
embeddedartists 0:6b68dac0d986 1687
embeddedartists 0:6b68dac0d986 1688 void MCIFileSystem::mci_SetCommand(uint32_t Cmd, uint32_t Arg) const
embeddedartists 0:6b68dac0d986 1689 {
embeddedartists 0:6b68dac0d986 1690 /* Clear status register */
embeddedartists 0:6b68dac0d986 1691 LPC_MCI->CLEAR = SDC_CLEAR_ALL;
embeddedartists 0:6b68dac0d986 1692
embeddedartists 0:6b68dac0d986 1693 /* Set the argument first, finally command */
embeddedartists 0:6b68dac0d986 1694 LPC_MCI->ARGUMENT = Arg;
embeddedartists 0:6b68dac0d986 1695
embeddedartists 0:6b68dac0d986 1696 /* Write command value, enable the command */
embeddedartists 0:6b68dac0d986 1697 LPC_MCI->COMMAND = Cmd | SDC_COMMAND_ENABLE;
embeddedartists 0:6b68dac0d986 1698
embeddedartists 0:6b68dac0d986 1699 mci_WriteDelay();
embeddedartists 0:6b68dac0d986 1700 }
embeddedartists 0:6b68dac0d986 1701
embeddedartists 0:6b68dac0d986 1702 void MCIFileSystem::mci_ResetCommand() const
embeddedartists 0:6b68dac0d986 1703 {
embeddedartists 0:6b68dac0d986 1704 LPC_MCI->CLEAR = SDC_CLEAR_ALL;
embeddedartists 0:6b68dac0d986 1705
embeddedartists 0:6b68dac0d986 1706 LPC_MCI->ARGUMENT = 0xFFFFFFFF;
embeddedartists 0:6b68dac0d986 1707
embeddedartists 0:6b68dac0d986 1708 LPC_MCI->COMMAND = 0;
embeddedartists 0:6b68dac0d986 1709
embeddedartists 0:6b68dac0d986 1710 mci_WriteDelay();
embeddedartists 0:6b68dac0d986 1711 }
embeddedartists 0:6b68dac0d986 1712
embeddedartists 0:6b68dac0d986 1713 int32_t MCIFileSystem::mci_IRQHandler(uint8_t *txBuf, uint32_t *txCnt, uint8_t *rxBuf, uint32_t *rxCnt)
embeddedartists 0:6b68dac0d986 1714 {
embeddedartists 0:6b68dac0d986 1715 uint32_t Status;
embeddedartists 0:6b68dac0d986 1716
embeddedartists 0:6b68dac0d986 1717 Status = LPC_MCI->STATUS;
embeddedartists 0:6b68dac0d986 1718
embeddedartists 0:6b68dac0d986 1719 if ( Status & SDC_STATUS_DATAERR) {
embeddedartists 0:6b68dac0d986 1720 LPC_MCI->CLEAR = SDC_STATUS_DATAERR;
embeddedartists 0:6b68dac0d986 1721 return -1; /* Data transfer error */
embeddedartists 0:6b68dac0d986 1722 }
embeddedartists 0:6b68dac0d986 1723
embeddedartists 0:6b68dac0d986 1724 if ( Status & SDC_STATUS_DATAEND) {
embeddedartists 0:6b68dac0d986 1725 LPC_MCI->CLEAR = SDC_STATUS_DATAEND;
embeddedartists 0:6b68dac0d986 1726 LPC_MCI->MASK0 = 0;
embeddedartists 0:6b68dac0d986 1727 return 0;
embeddedartists 0:6b68dac0d986 1728 }
embeddedartists 0:6b68dac0d986 1729
embeddedartists 0:6b68dac0d986 1730 if ( Status & SDC_STATUS_DATABLOCKEND) {
embeddedartists 0:6b68dac0d986 1731 LPC_MCI->CLEAR = SDC_STATUS_DATABLOCKEND;
embeddedartists 0:6b68dac0d986 1732 return 1;
embeddedartists 0:6b68dac0d986 1733 }
embeddedartists 0:6b68dac0d986 1734
embeddedartists 0:6b68dac0d986 1735 if (Status & SDC_STATUS_FIFO) {
embeddedartists 0:6b68dac0d986 1736 return mci_FIFOIRQHandler(txBuf, txCnt, rxBuf, rxCnt);
embeddedartists 0:6b68dac0d986 1737 }
embeddedartists 0:6b68dac0d986 1738
embeddedartists 0:6b68dac0d986 1739 return 1;
embeddedartists 0:6b68dac0d986 1740 }
embeddedartists 0:6b68dac0d986 1741
embeddedartists 0:6b68dac0d986 1742 int32_t MCIFileSystem::mci_FIFOIRQHandler(uint8_t *txBuf, uint32_t *txCnt, uint8_t *rxBuf, uint32_t *rxCnt)
embeddedartists 0:6b68dac0d986 1743 {
embeddedartists 0:6b68dac0d986 1744 uint32_t Status;
embeddedartists 0:6b68dac0d986 1745 Status = LPC_MCI->STATUS;
embeddedartists 0:6b68dac0d986 1746
embeddedartists 0:6b68dac0d986 1747 if (txBuf) {
embeddedartists 0:6b68dac0d986 1748 if (Status & SDC_STATUS_TXFIFOHALFEMPTY) {
embeddedartists 0:6b68dac0d986 1749 if (*txCnt % 64) {
embeddedartists 0:6b68dac0d986 1750 mci_WriteFIFO((uint32_t *) &txBuf[*txCnt], false);
embeddedartists 0:6b68dac0d986 1751 }
embeddedartists 0:6b68dac0d986 1752 else {
embeddedartists 0:6b68dac0d986 1753 mci_WriteFIFO((uint32_t *) &txBuf[*txCnt], true);
embeddedartists 0:6b68dac0d986 1754 }
embeddedartists 0:6b68dac0d986 1755 *txCnt += 32;
embeddedartists 0:6b68dac0d986 1756 }
embeddedartists 0:6b68dac0d986 1757 }
embeddedartists 0:6b68dac0d986 1758
embeddedartists 0:6b68dac0d986 1759 if (rxBuf) {
embeddedartists 0:6b68dac0d986 1760 if (Status & SDC_STATUS_RXFIFOHALFFULL) {
embeddedartists 0:6b68dac0d986 1761 if (*rxCnt % 64) {
embeddedartists 0:6b68dac0d986 1762 mci_ReadFIFO((uint32_t *) &rxBuf[*rxCnt], false);
embeddedartists 0:6b68dac0d986 1763 }
embeddedartists 0:6b68dac0d986 1764 else {
embeddedartists 0:6b68dac0d986 1765 mci_ReadFIFO((uint32_t *) &rxBuf[*rxCnt], true);
embeddedartists 0:6b68dac0d986 1766 }
embeddedartists 0:6b68dac0d986 1767 *rxCnt += 32;
embeddedartists 0:6b68dac0d986 1768 }
embeddedartists 0:6b68dac0d986 1769 }
embeddedartists 0:6b68dac0d986 1770
embeddedartists 0:6b68dac0d986 1771 LPC_MCI->CLEAR = SDC_STATUS_FIFO;
embeddedartists 0:6b68dac0d986 1772
embeddedartists 0:6b68dac0d986 1773 return 1;
embeddedartists 0:6b68dac0d986 1774 }
embeddedartists 0:6b68dac0d986 1775
embeddedartists 0:6b68dac0d986 1776 void MCIFileSystem::mci_ReadFIFO(uint32_t *pDst, bool bFirstHalf) const
embeddedartists 0:6b68dac0d986 1777 {
embeddedartists 0:6b68dac0d986 1778 uint8_t start = 0, end = 7;
embeddedartists 0:6b68dac0d986 1779
embeddedartists 0:6b68dac0d986 1780 if (!bFirstHalf) {
embeddedartists 0:6b68dac0d986 1781 start += 8;
embeddedartists 0:6b68dac0d986 1782 end += 8;
embeddedartists 0:6b68dac0d986 1783 }
embeddedartists 0:6b68dac0d986 1784 for (; start <= end; start++) {
embeddedartists 0:6b68dac0d986 1785 *pDst = LPC_MCI->FIFO[start];
embeddedartists 0:6b68dac0d986 1786 pDst++;
embeddedartists 0:6b68dac0d986 1787 }
embeddedartists 0:6b68dac0d986 1788 }
embeddedartists 0:6b68dac0d986 1789
embeddedartists 0:6b68dac0d986 1790 void MCIFileSystem::mci_WriteFIFO(uint32_t *pSrc, bool bFirstHalf) const
embeddedartists 0:6b68dac0d986 1791 {
embeddedartists 0:6b68dac0d986 1792 uint8_t start = 0, end = 7;
embeddedartists 0:6b68dac0d986 1793 if (!bFirstHalf) {
embeddedartists 0:6b68dac0d986 1794 start += 8;
embeddedartists 0:6b68dac0d986 1795 end += 8;
embeddedartists 0:6b68dac0d986 1796 }
embeddedartists 0:6b68dac0d986 1797 for (; start <= end; start++) {
embeddedartists 0:6b68dac0d986 1798 LPC_MCI->FIFO[start] = *pSrc;
embeddedartists 0:6b68dac0d986 1799 pSrc++;
embeddedartists 0:6b68dac0d986 1800 }
embeddedartists 0:6b68dac0d986 1801 }
embeddedartists 0:6b68dac0d986 1802
embeddedartists 38:420cdc281467 1803 void MCIFileSystem::mci_SetupEventWakeup()
embeddedartists 0:6b68dac0d986 1804 {
embeddedartists 0:6b68dac0d986 1805 /* Wait for IRQ - for an RTOS, you would pend on an event here with a IRQ based wakeup. */
embeddedartists 0:6b68dac0d986 1806
embeddedartists 0:6b68dac0d986 1807 _eventReceived = false;
embeddedartists 0:6b68dac0d986 1808 _eventSuccess = false;
embeddedartists 0:6b68dac0d986 1809 }
embeddedartists 0:6b68dac0d986 1810
embeddedartists 0:6b68dac0d986 1811 uint32_t MCIFileSystem::mci_WaitForEvent() const
embeddedartists 0:6b68dac0d986 1812 {
embeddedartists 0:6b68dac0d986 1813 /* Wait for the event (DMA or MCI interrupt) for a maximum of 2 seconds */
embeddedartists 0:6b68dac0d986 1814 uint32_t end = us_ticker_read() + 2*1000*1000;
embeddedartists 0:6b68dac0d986 1815 while ((us_ticker_read() < end) && (!_eventReceived))
embeddedartists 0:6b68dac0d986 1816 {
embeddedartists 0:6b68dac0d986 1817 // If the driver is having problems reading the card, adding a delay here
embeddedartists 0:6b68dac0d986 1818 // might help.
embeddedartists 0:6b68dac0d986 1819 //wait(0.01);
embeddedartists 42:bbfe299d4a0c 1820 ThisThread::sleep_for(10);
embeddedartists 0:6b68dac0d986 1821 }
embeddedartists 0:6b68dac0d986 1822
embeddedartists 0:6b68dac0d986 1823 if (_eventReceived && _eventSuccess) {
embeddedartists 0:6b68dac0d986 1824 return 0;
embeddedartists 0:6b68dac0d986 1825 }
embeddedartists 0:6b68dac0d986 1826
embeddedartists 0:6b68dac0d986 1827 return 1;
embeddedartists 0:6b68dac0d986 1828 }
embeddedartists 0:6b68dac0d986 1829
embeddedartists 0:6b68dac0d986 1830 MCIFileSystem::ReturnCode MCIFileSystem::_readBlocks(uint32_t card_type, uint32_t startBlock, uint32_t blockNum) const
embeddedartists 0:6b68dac0d986 1831 {
embeddedartists 0:6b68dac0d986 1832 ReturnCode Ret = SDC_RET_FAILED;
embeddedartists 0:6b68dac0d986 1833 response_t Response;
embeddedartists 0:6b68dac0d986 1834 uint32_t Command, Argument;
embeddedartists 0:6b68dac0d986 1835 uint8_t RetryCnt = 0x20;
embeddedartists 0:6b68dac0d986 1836
embeddedartists 0:6b68dac0d986 1837 if (blockNum == 1) {
embeddedartists 0:6b68dac0d986 1838 Command = SD_CMD17_READ_SINGLE_BLOCK;
embeddedartists 0:6b68dac0d986 1839 }
embeddedartists 0:6b68dac0d986 1840 else {
embeddedartists 0:6b68dac0d986 1841 Command = SD_CMD18_READ_MULTIPLE_BLOCK;
embeddedartists 0:6b68dac0d986 1842 }
embeddedartists 0:6b68dac0d986 1843
embeddedartists 0:6b68dac0d986 1844 /* Select single or multiple read based on number of blocks */
embeddedartists 0:6b68dac0d986 1845 /* if high capacity card use block indexing */
embeddedartists 0:6b68dac0d986 1846 if (card_type & CARD_TYPE_HC) {
embeddedartists 0:6b68dac0d986 1847 Argument = startBlock;
embeddedartists 0:6b68dac0d986 1848 }
embeddedartists 0:6b68dac0d986 1849 else { /*fix at 512 bytes*/
embeddedartists 0:6b68dac0d986 1850 Argument = startBlock << 9;
embeddedartists 0:6b68dac0d986 1851 }
embeddedartists 0:6b68dac0d986 1852
embeddedartists 0:6b68dac0d986 1853 while (RetryCnt > 0) {
embeddedartists 0:6b68dac0d986 1854 Ret = mci_ExecuteCmd(Command, Argument, &Response);
embeddedartists 0:6b68dac0d986 1855 if (Ret == SDC_RET_OK) {
embeddedartists 0:6b68dac0d986 1856 if (mci_CheckR1Response(Response.Data[0], &Ret)) {
embeddedartists 0:6b68dac0d986 1857 return Ret;
embeddedartists 0:6b68dac0d986 1858 }
embeddedartists 0:6b68dac0d986 1859 }
embeddedartists 0:6b68dac0d986 1860 RetryCnt--;
embeddedartists 0:6b68dac0d986 1861 }
embeddedartists 0:6b68dac0d986 1862 return Ret;
embeddedartists 0:6b68dac0d986 1863 }
embeddedartists 0:6b68dac0d986 1864
embeddedartists 0:6b68dac0d986 1865 MCIFileSystem::ReturnCode MCIFileSystem::_writeBlocks(uint32_t card_type, uint32_t startBlock, uint32_t blockNum) const
embeddedartists 0:6b68dac0d986 1866 {
embeddedartists 0:6b68dac0d986 1867 ReturnCode Ret = SDC_RET_FAILED;
embeddedartists 0:6b68dac0d986 1868 response_t Response;
embeddedartists 0:6b68dac0d986 1869 uint32_t Command, Argument;
embeddedartists 0:6b68dac0d986 1870 uint8_t RetryCnt = 0x20;
embeddedartists 0:6b68dac0d986 1871
embeddedartists 0:6b68dac0d986 1872 if (blockNum == 1) {
embeddedartists 0:6b68dac0d986 1873 Command = SD_CMD24_WRITE_BLOCK;
embeddedartists 0:6b68dac0d986 1874 }
embeddedartists 0:6b68dac0d986 1875 else {
embeddedartists 0:6b68dac0d986 1876 Command = SD_CMD25_WRITE_MULTIPLE_BLOCK;
embeddedartists 0:6b68dac0d986 1877 }
embeddedartists 0:6b68dac0d986 1878
embeddedartists 0:6b68dac0d986 1879 /* if high capacity card use block indexing */
embeddedartists 0:6b68dac0d986 1880 if (card_type & CARD_TYPE_HC) {
embeddedartists 0:6b68dac0d986 1881 Argument = startBlock;
embeddedartists 0:6b68dac0d986 1882 }
embeddedartists 0:6b68dac0d986 1883 else { /*fix at 512 bytes*/
embeddedartists 0:6b68dac0d986 1884 Argument = startBlock << 9;
embeddedartists 0:6b68dac0d986 1885
embeddedartists 0:6b68dac0d986 1886 }
embeddedartists 0:6b68dac0d986 1887
embeddedartists 0:6b68dac0d986 1888 while (RetryCnt > 0) {
embeddedartists 0:6b68dac0d986 1889 Ret = mci_ExecuteCmd(Command, Argument, &Response);
embeddedartists 0:6b68dac0d986 1890 if (Ret == SDC_RET_OK) {
embeddedartists 0:6b68dac0d986 1891 if (mci_CheckR1Response(Response.Data[0], &Ret)) {
embeddedartists 0:6b68dac0d986 1892 return Ret;
embeddedartists 0:6b68dac0d986 1893 }
embeddedartists 0:6b68dac0d986 1894 }
embeddedartists 0:6b68dac0d986 1895 RetryCnt--;
embeddedartists 0:6b68dac0d986 1896 }
embeddedartists 0:6b68dac0d986 1897 return Ret;
embeddedartists 0:6b68dac0d986 1898 }