Update version of EALib.

Dependencies:   FATFileSystem

Fork of EALib by IONX

Committer:
Brendan McDonnell
Date:
Tue Dec 05 12:16:26 2017 -0500
Branch:
mbed-os
Revision:
27:b623423ad6e2
Parent:
23:7d9ca4ac0d1e
created branch mbed-os

Who changed what in which revision?

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