mbed library sources. Supersedes mbed-src.

Fork of mbed-dev by mbed official

Committer:
<>
Date:
Fri Oct 28 11:17:30 2016 +0100
Revision:
149:156823d33999
This updates the lib to the mbed lib v128

NOTE: This release includes a restructuring of the file and directory locations and thus some
include paths in your code may need updating accordingly.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
<> 149:156823d33999 1 /**************************************************************************//**
<> 149:156823d33999 2 * @file SD.c
<> 149:156823d33999 3 * @version V1.00
<> 149:156823d33999 4 * $Revision: 16 $
<> 149:156823d33999 5 * $Date: 15/11/26 10:45a $
<> 149:156823d33999 6 * @brief NUC472/NUC442 SD driver source file
<> 149:156823d33999 7 *
<> 149:156823d33999 8 * @note
<> 149:156823d33999 9 * Copyright (C) 2013 Nuvoton Technology Corp. All rights reserved.
<> 149:156823d33999 10 *****************************************************************************/
<> 149:156823d33999 11 #include <stdio.h>
<> 149:156823d33999 12 #include <stdlib.h>
<> 149:156823d33999 13 #include <string.h>
<> 149:156823d33999 14 #include "NUC472_442.h"
<> 149:156823d33999 15
<> 149:156823d33999 16 /** @addtogroup NUC472_442_Device_Driver NUC472/NUC442 Device Driver
<> 149:156823d33999 17 @{
<> 149:156823d33999 18 */
<> 149:156823d33999 19
<> 149:156823d33999 20 /** @addtogroup NUC472_442_SD_Driver SD Driver
<> 149:156823d33999 21 @{
<> 149:156823d33999 22 */
<> 149:156823d33999 23
<> 149:156823d33999 24
<> 149:156823d33999 25 /** @addtogroup NUC472_442_SD_EXPORTED_FUNCTIONS SD Exported Functions
<> 149:156823d33999 26 @{
<> 149:156823d33999 27 */
<> 149:156823d33999 28 #define SD_BLOCK_SIZE 512
<> 149:156823d33999 29
<> 149:156823d33999 30 /// @cond HIDDEN_SYMBOLS
<> 149:156823d33999 31
<> 149:156823d33999 32 // global variables
<> 149:156823d33999 33 // For response R3 (such as ACMD41, CRC-7 is invalid; but SD controller will still
<> 149:156823d33999 34 // calculate CRC-7 and get an error result, software should ignore this error and clear SDISR [CRC_IF] flag
<> 149:156823d33999 35 // _sd_uR3_CMD is the flag for it. 1 means software should ignore CRC-7 error
<> 149:156823d33999 36 uint32_t _sd_uR3_CMD=0;
<> 149:156823d33999 37 uint32_t _sd_uR7_CMD=0;
<> 149:156823d33999 38 uint8_t volatile _sd_SDDataReady = FALSE;
<> 149:156823d33999 39
<> 149:156823d33999 40 uint8_t *_sd_pSDHCBuffer;
<> 149:156823d33999 41 uint32_t _sd_ReferenceClock;
<> 149:156823d33999 42
<> 149:156823d33999 43 #if defined (__CC_ARM)
<> 149:156823d33999 44 __align(4096) uint8_t _sd_ucSDHCBuffer[512];
<> 149:156823d33999 45 #elif defined ( __ICCARM__ ) /*!< IAR Compiler */
<> 149:156823d33999 46 #pragma data_alignment = 4096
<> 149:156823d33999 47 uint8_t _sd_ucSDHCBuffer[512];
<> 149:156823d33999 48 #elif defined ( __GNUC__ )
<> 149:156823d33999 49 uint8_t _sd_ucSDHCBuffer[512] __attribute__((aligned (4096)));
<> 149:156823d33999 50 #endif
<> 149:156823d33999 51
<> 149:156823d33999 52 int sd0_ok = 0;
<> 149:156823d33999 53 int sd1_ok = 0;
<> 149:156823d33999 54
<> 149:156823d33999 55 uint8_t pSD0_offset = 0;
<> 149:156823d33999 56 uint8_t pSD1_offset = 0;
<> 149:156823d33999 57
<> 149:156823d33999 58 DISK_DATA_T SD_DiskInfo0;
<> 149:156823d33999 59 DISK_DATA_T SD_DiskInfo1;
<> 149:156823d33999 60
<> 149:156823d33999 61 SD_INFO_T SD0;
<> 149:156823d33999 62 SD_INFO_T SD1;
<> 149:156823d33999 63
<> 149:156823d33999 64 void SD_CheckRB()
<> 149:156823d33999 65 {
<> 149:156823d33999 66 while(1) {
<> 149:156823d33999 67 SD->CTL |= SDH_CTL_CLK8OEN_Msk;
<> 149:156823d33999 68 while(SD->CTL & SDH_CTL_CLK8OEN_Msk);
<> 149:156823d33999 69 if (SD->INTSTS & SDH_INTSTS_DAT0STS_Msk)
<> 149:156823d33999 70 break;
<> 149:156823d33999 71 }
<> 149:156823d33999 72 }
<> 149:156823d33999 73
<> 149:156823d33999 74
<> 149:156823d33999 75 int SD_SDCommand(SD_INFO_T *pSD, uint8_t ucCmd, uint32_t uArg)
<> 149:156823d33999 76 {
<> 149:156823d33999 77 volatile int buf;
<> 149:156823d33999 78
<> 149:156823d33999 79 SD->CMDARG = uArg;
<> 149:156823d33999 80 buf = (SD->CTL&(~SDH_CTL_CMDCODE_Msk))|(ucCmd << 8)|(SDH_CTL_COEN_Msk);
<> 149:156823d33999 81 SD->CTL = buf;
<> 149:156823d33999 82
<> 149:156823d33999 83 while(SD->CTL & SDH_CTL_COEN_Msk) {
<> 149:156823d33999 84 if (pSD->IsCardInsert == FALSE)
<> 149:156823d33999 85 return SD_NO_SD_CARD;
<> 149:156823d33999 86 }
<> 149:156823d33999 87 return Successful;
<> 149:156823d33999 88 }
<> 149:156823d33999 89
<> 149:156823d33999 90
<> 149:156823d33999 91 int SD_SDCmdAndRsp(SD_INFO_T *pSD, uint8_t ucCmd, uint32_t uArg, int ntickCount)
<> 149:156823d33999 92 {
<> 149:156823d33999 93 volatile int buf;
<> 149:156823d33999 94
<> 149:156823d33999 95 SD->CMDARG = uArg;
<> 149:156823d33999 96 buf = (SD->CTL&(~SDH_CTL_CMDCODE_Msk))|(ucCmd << 8)|(SDH_CTL_COEN_Msk | SDH_CTL_RIEN_Msk);
<> 149:156823d33999 97 SD->CTL = buf;
<> 149:156823d33999 98
<> 149:156823d33999 99 if (ntickCount > 0) {
<> 149:156823d33999 100 while(SD->CTL & SDH_CTL_RIEN_Msk) {
<> 149:156823d33999 101 if(ntickCount-- == 0) {
<> 149:156823d33999 102 SD->CTL |= SDH_CTL_CTLRST_Msk; // reset SD engine
<> 149:156823d33999 103 return 2;
<> 149:156823d33999 104 }
<> 149:156823d33999 105 if (pSD->IsCardInsert == FALSE)
<> 149:156823d33999 106 return SD_NO_SD_CARD;
<> 149:156823d33999 107 }
<> 149:156823d33999 108 } else {
<> 149:156823d33999 109 while(SD->CTL & SDH_CTL_RIEN_Msk) {
<> 149:156823d33999 110 if (pSD->IsCardInsert == FALSE)
<> 149:156823d33999 111 return SD_NO_SD_CARD;
<> 149:156823d33999 112 }
<> 149:156823d33999 113 }
<> 149:156823d33999 114
<> 149:156823d33999 115 if (_sd_uR7_CMD) {
<> 149:156823d33999 116 if (((SD->RESP1 & 0xff) != 0x55) && ((SD->RESP0 & 0xf) != 0x01)) {
<> 149:156823d33999 117 _sd_uR7_CMD = 0;
<> 149:156823d33999 118 return SD_CMD8_ERROR;
<> 149:156823d33999 119 }
<> 149:156823d33999 120 }
<> 149:156823d33999 121
<> 149:156823d33999 122 if (!_sd_uR3_CMD) {
<> 149:156823d33999 123 if (SD->INTSTS & SDH_INTSTS_CRC7_Msk) // check CRC7
<> 149:156823d33999 124 return Successful;
<> 149:156823d33999 125 else {
<> 149:156823d33999 126 return SD_CRC7_ERROR;
<> 149:156823d33999 127 }
<> 149:156823d33999 128 } else { // ignore CRC error for R3 case
<> 149:156823d33999 129 _sd_uR3_CMD = 0;
<> 149:156823d33999 130 SD->INTSTS = SDH_INTSTS_CRCIF_Msk;
<> 149:156823d33999 131 return Successful;
<> 149:156823d33999 132 }
<> 149:156823d33999 133 }
<> 149:156823d33999 134
<> 149:156823d33999 135
<> 149:156823d33999 136 int SD_Swap32(int val)
<> 149:156823d33999 137 {
<> 149:156823d33999 138 #if 1
<> 149:156823d33999 139 int buf;
<> 149:156823d33999 140
<> 149:156823d33999 141 buf = val;
<> 149:156823d33999 142 val <<= 24;
<> 149:156823d33999 143 val |= (buf<<8)&0xff0000;
<> 149:156823d33999 144 val |= (buf>>8)&0xff00;
<> 149:156823d33999 145 val |= (buf>>24)&0xff;
<> 149:156823d33999 146 return val;
<> 149:156823d33999 147
<> 149:156823d33999 148 #else
<> 149:156823d33999 149 return ((val<<24) | ((val<<8)&0xff0000) | ((val>>8)&0xff00) | (val>>24));
<> 149:156823d33999 150 #endif
<> 149:156823d33999 151 }
<> 149:156823d33999 152
<> 149:156823d33999 153 // Get 16 bytes CID or CSD
<> 149:156823d33999 154 int SD_SDCmdAndRsp2(SD_INFO_T *pSD, uint8_t ucCmd, uint32_t uArg, uint32_t *puR2ptr)
<> 149:156823d33999 155 {
<> 149:156823d33999 156 unsigned int i, buf;
<> 149:156823d33999 157 unsigned int tmpBuf[5];
<> 149:156823d33999 158
<> 149:156823d33999 159 SD->CMDARG = uArg;
<> 149:156823d33999 160 buf = (SD->CTL&(~SDH_CTL_CMDCODE_Msk))|(ucCmd << 8)|(SDH_CTL_COEN_Msk | SDH_CTL_R2EN_Msk);
<> 149:156823d33999 161 SD->CTL = buf;
<> 149:156823d33999 162
<> 149:156823d33999 163 while(SD->CTL & SDH_CTL_R2EN_Msk) {
<> 149:156823d33999 164 if (pSD->IsCardInsert == FALSE)
<> 149:156823d33999 165 return SD_NO_SD_CARD;
<> 149:156823d33999 166 }
<> 149:156823d33999 167
<> 149:156823d33999 168 if (SD->INTSTS & SDH_INTSTS_CRC7_Msk) {
<> 149:156823d33999 169 for (i=0; i<5; i++) {
<> 149:156823d33999 170 tmpBuf[i] = SD_Swap32(*(int*)(SD_BASE+i*4));
<> 149:156823d33999 171 }
<> 149:156823d33999 172 for (i=0; i<4; i++)
<> 149:156823d33999 173 *puR2ptr++ = ((tmpBuf[i] & 0x00ffffff)<<8) | ((tmpBuf[i+1] & 0xff000000)>>24);
<> 149:156823d33999 174 return Successful;
<> 149:156823d33999 175 } else
<> 149:156823d33999 176 return SD_CRC7_ERROR;
<> 149:156823d33999 177 }
<> 149:156823d33999 178
<> 149:156823d33999 179
<> 149:156823d33999 180 int SD_SDCmdAndRspDataIn(SD_INFO_T *pSD, uint8_t ucCmd, uint32_t uArg)
<> 149:156823d33999 181 {
<> 149:156823d33999 182 volatile int buf;
<> 149:156823d33999 183
<> 149:156823d33999 184 SD->CMDARG = uArg;
<> 149:156823d33999 185 buf = (SD->CTL&(~SDH_CTL_CMDCODE_Msk))|(ucCmd << 8)|
<> 149:156823d33999 186 (SDH_CTL_COEN_Msk | SDH_CTL_RIEN_Msk | SDH_CTL_DIEN_Msk);
<> 149:156823d33999 187
<> 149:156823d33999 188 SD->CTL = buf;
<> 149:156823d33999 189
<> 149:156823d33999 190 while (SD->CTL & SDH_CTL_RIEN_Msk) {
<> 149:156823d33999 191 if (pSD->IsCardInsert == FALSE)
<> 149:156823d33999 192 return SD_NO_SD_CARD;
<> 149:156823d33999 193 }
<> 149:156823d33999 194
<> 149:156823d33999 195 while (SD->CTL & SDH_CTL_DIEN_Msk) {
<> 149:156823d33999 196 if (pSD->IsCardInsert == FALSE)
<> 149:156823d33999 197 return SD_NO_SD_CARD;
<> 149:156823d33999 198 }
<> 149:156823d33999 199
<> 149:156823d33999 200 if (!(SD->INTSTS & SDH_INTSTS_CRC7_Msk)) { // check CRC7
<> 149:156823d33999 201 return SD_CRC7_ERROR;
<> 149:156823d33999 202 }
<> 149:156823d33999 203
<> 149:156823d33999 204 if (!(SD->INTSTS & SDH_INTSTS_CRC16_Msk)) { // check CRC16
<> 149:156823d33999 205 return SD_CRC16_ERROR;
<> 149:156823d33999 206 }
<> 149:156823d33999 207 return Successful;
<> 149:156823d33999 208 }
<> 149:156823d33999 209
<> 149:156823d33999 210 // there are 8 bits for divider0, maximum is 256
<> 149:156823d33999 211 #define SD_CLK_DIV0_MAX 256
<> 149:156823d33999 212
<> 149:156823d33999 213 void SD_Set_clock(uint32_t sd_clock_khz)
<> 149:156823d33999 214 {
<> 149:156823d33999 215 uint32_t rate, div1, i;
<> 149:156823d33999 216 uint32_t u32SD_ClkSrc;
<> 149:156823d33999 217
<> 149:156823d33999 218 if(sd_clock_khz >= 24000) {
<> 149:156823d33999 219 sd_clock_khz = 24000;
<> 149:156823d33999 220 }
<> 149:156823d33999 221
<> 149:156823d33999 222 u32SD_ClkSrc = (CLK->CLKSEL0 & CLK_CLKSEL0_SDHSEL_Msk);
<> 149:156823d33999 223
<> 149:156823d33999 224 if(u32SD_ClkSrc == CLK_CLKSEL0_SDHSEL_HXT)
<> 149:156823d33999 225 _sd_ReferenceClock = (CLK_GetHXTFreq() / 1000);
<> 149:156823d33999 226 else if(u32SD_ClkSrc == CLK_CLKSEL0_SDHSEL_HIRC)
<> 149:156823d33999 227 _sd_ReferenceClock = (__HIRC / 1000);
<> 149:156823d33999 228 else if(u32SD_ClkSrc == CLK_CLKSEL0_SDHSEL_PLL)
<> 149:156823d33999 229 _sd_ReferenceClock = (CLK_GetPLLClockFreq() / 1000);
<> 149:156823d33999 230 else if(u32SD_ClkSrc == CLK_CLKSEL0_SDHSEL_HCLK)
<> 149:156823d33999 231 _sd_ReferenceClock = (CLK_GetHCLKFreq() / 1000);
<> 149:156823d33999 232
<> 149:156823d33999 233 rate = _sd_ReferenceClock / sd_clock_khz;
<> 149:156823d33999 234
<> 149:156823d33999 235 // choose slower clock if system clock cannot divisible by wanted clock
<> 149:156823d33999 236 if (_sd_ReferenceClock % sd_clock_khz != 0)
<> 149:156823d33999 237 rate++;
<> 149:156823d33999 238
<> 149:156823d33999 239 if(rate >= SD_CLK_DIV0_MAX) {
<> 149:156823d33999 240 rate = SD_CLK_DIV0_MAX;
<> 149:156823d33999 241 }
<> 149:156823d33999 242
<> 149:156823d33999 243 //--- calculate the second divider CLKDIV0[SDHOST_N]
<> 149:156823d33999 244 div1 = ((rate -1) & 0xFF);
<> 149:156823d33999 245
<> 149:156823d33999 246 //--- setup register
<> 149:156823d33999 247 CLK->CLKDIV0 &= ~CLK_CLKDIV0_SDHDIV_Msk;
<> 149:156823d33999 248 CLK->CLKDIV0 |= (div1 << CLK_CLKDIV0_SDHDIV_Pos);
<> 149:156823d33999 249
<> 149:156823d33999 250 for(i=0; i<1000; i++); // waiting for clock become stable
<> 149:156823d33999 251 return;
<> 149:156823d33999 252 }
<> 149:156823d33999 253
<> 149:156823d33999 254 void SD_CardSelect(int cardSel)
<> 149:156823d33999 255 {
<> 149:156823d33999 256 if(cardSel == 0) {
<> 149:156823d33999 257 SD->CTL |= (SD->CTL & ~SDH_CTL_SDPORT_Msk);
<> 149:156823d33999 258 } else if(cardSel == 1) {
<> 149:156823d33999 259 SD->CTL |= ((SD->CTL & ~SDH_CTL_SDPORT_Msk) | (1 << SDH_CTL_SDPORT_Pos));
<> 149:156823d33999 260 }
<> 149:156823d33999 261 }
<> 149:156823d33999 262
<> 149:156823d33999 263 uint32_t SD_CardDetection(uint32_t u32CardNum)
<> 149:156823d33999 264 {
<> 149:156823d33999 265 uint32_t i;
<> 149:156823d33999 266
<> 149:156823d33999 267 if (u32CardNum == SD_PORT0) {
<> 149:156823d33999 268 if(SD->INTEN & SDH_INTEN_CDSRC0_Msk) { // Card detect pin from GPIO
<> 149:156823d33999 269 if(SD->INTSTS & SDH_INTSTS_CDSTS0_Msk) { // Card remove
<> 149:156823d33999 270 SD0.IsCardInsert = FALSE;
<> 149:156823d33999 271 return FALSE;
<> 149:156823d33999 272 } else
<> 149:156823d33999 273 SD0.IsCardInsert = TRUE;
<> 149:156823d33999 274 } else if(!(SD->INTEN & SDH_INTEN_CDSRC0_Msk)) {
<> 149:156823d33999 275 SD->CTL |= SDH_CTL_CLKKEEP0_Msk;
<> 149:156823d33999 276 for(i= 0; i < 5000; i++);
<> 149:156823d33999 277
<> 149:156823d33999 278 if(SD->INTSTS & SDH_INTSTS_CDSTS0_Msk) // Card insert
<> 149:156823d33999 279 SD0.IsCardInsert = TRUE;
<> 149:156823d33999 280 else {
<> 149:156823d33999 281 SD0.IsCardInsert = FALSE;
<> 149:156823d33999 282 return FALSE;
<> 149:156823d33999 283 }
<> 149:156823d33999 284
<> 149:156823d33999 285 SD->CTL &= ~SDH_CTL_CLKKEEP0_Msk;
<> 149:156823d33999 286 }
<> 149:156823d33999 287
<> 149:156823d33999 288 } else if (u32CardNum == SD_PORT1) {
<> 149:156823d33999 289 if(SD->INTEN & SDH_INTEN_CDSRC1_Msk) { // Card detect pin from GPIO
<> 149:156823d33999 290 if(SD->INTSTS & SDH_INTSTS_CDSTS1_Msk) { // Card remove
<> 149:156823d33999 291 SD1.IsCardInsert = FALSE;
<> 149:156823d33999 292 return FALSE;
<> 149:156823d33999 293 } else
<> 149:156823d33999 294 SD1.IsCardInsert = TRUE;
<> 149:156823d33999 295 } else if(!(SD->INTEN & SDH_INTEN_CDSRC1_Msk)) {
<> 149:156823d33999 296 SD->CTL |= SDH_CTL_CLKKEEP1_Msk;
<> 149:156823d33999 297 for(i= 0; i < 5000; i++);
<> 149:156823d33999 298
<> 149:156823d33999 299 if(SD->INTSTS & SDH_INTSTS_CDSTS1_Msk) // Card insert
<> 149:156823d33999 300 SD1.IsCardInsert = TRUE;
<> 149:156823d33999 301 else {
<> 149:156823d33999 302 SD1.IsCardInsert = FALSE;
<> 149:156823d33999 303 return FALSE;
<> 149:156823d33999 304 }
<> 149:156823d33999 305
<> 149:156823d33999 306 SD->CTL &= ~SDH_CTL_CLKKEEP1_Msk;
<> 149:156823d33999 307 }
<> 149:156823d33999 308
<> 149:156823d33999 309 }
<> 149:156823d33999 310
<> 149:156823d33999 311 return TRUE;
<> 149:156823d33999 312 }
<> 149:156823d33999 313
<> 149:156823d33999 314
<> 149:156823d33999 315 // Initial
<> 149:156823d33999 316 int SD_Init(SD_INFO_T *pSD)
<> 149:156823d33999 317 {
<> 149:156823d33999 318 int volatile i, status;
<> 149:156823d33999 319 unsigned int resp;
<> 149:156823d33999 320 unsigned int CIDBuffer[4];
<> 149:156823d33999 321 unsigned int volatile u32CmdTimeOut;
<> 149:156823d33999 322
<> 149:156823d33999 323 // set the clock to 200KHz
<> 149:156823d33999 324 //SD_Set_clock(200);
<> 149:156823d33999 325 SD_Set_clock(100);
<> 149:156823d33999 326
<> 149:156823d33999 327 // power ON 74 clock
<> 149:156823d33999 328 SD->CTL |= SDH_CTL_CLK74OEN_Msk;
<> 149:156823d33999 329
<> 149:156823d33999 330 while(SD->CTL & SDH_CTL_CLK74OEN_Msk) {
<> 149:156823d33999 331 if (pSD->IsCardInsert == FALSE)
<> 149:156823d33999 332 return SD_NO_SD_CARD;
<> 149:156823d33999 333 }
<> 149:156823d33999 334
<> 149:156823d33999 335 SD_SDCommand(pSD, 0, 0); // reset all cards
<> 149:156823d33999 336 for (i=0x1000; i>0; i--);
<> 149:156823d33999 337
<> 149:156823d33999 338 // initial SDHC
<> 149:156823d33999 339 _sd_uR7_CMD = 1;
<> 149:156823d33999 340 //u32CmdTimeOut = 5000;
<> 149:156823d33999 341 u32CmdTimeOut = 0xFFFFF;
<> 149:156823d33999 342 //u32CmdTimeOut = 0;
<> 149:156823d33999 343
<> 149:156823d33999 344 i = SD_SDCmdAndRsp(pSD, 8, 0x00000155, u32CmdTimeOut);
<> 149:156823d33999 345 if (i == Successful) {
<> 149:156823d33999 346 // SD 2.0
<> 149:156823d33999 347 SD_SDCmdAndRsp(pSD, 55, 0x00, u32CmdTimeOut);
<> 149:156823d33999 348 _sd_uR3_CMD = 1;
<> 149:156823d33999 349 SD_SDCmdAndRsp(pSD, 41, 0x40ff8000, u32CmdTimeOut); // 2.7v-3.6v
<> 149:156823d33999 350 resp = SD->RESP0;
<> 149:156823d33999 351
<> 149:156823d33999 352 while (!(resp & 0x00800000)) { // check if card is ready
<> 149:156823d33999 353 SD_SDCmdAndRsp(pSD, 55, 0x00, u32CmdTimeOut);
<> 149:156823d33999 354 _sd_uR3_CMD = 1;
<> 149:156823d33999 355 SD_SDCmdAndRsp(pSD, 41, 0x40ff8000, u32CmdTimeOut); // 3.0v-3.4v
<> 149:156823d33999 356 resp = SD->RESP0;
<> 149:156823d33999 357 }
<> 149:156823d33999 358 if (resp & 0x00400000)
<> 149:156823d33999 359 pSD->CardType = SD_TYPE_SD_HIGH;
<> 149:156823d33999 360 else
<> 149:156823d33999 361 pSD->CardType = SD_TYPE_SD_LOW;
<> 149:156823d33999 362 } else {
<> 149:156823d33999 363 // SD 1.1
<> 149:156823d33999 364 SD_SDCommand(pSD, 0, 0); // reset all cards
<> 149:156823d33999 365 for (i=0x100; i>0; i--);
<> 149:156823d33999 366
<> 149:156823d33999 367 i = SD_SDCmdAndRsp(pSD, 55, 0x00, u32CmdTimeOut);
<> 149:156823d33999 368 if (i == 2) { // MMC memory
<> 149:156823d33999 369
<> 149:156823d33999 370 SD_SDCommand(pSD, 0, 0); // reset
<> 149:156823d33999 371 for (i=0x100; i>0; i--);
<> 149:156823d33999 372
<> 149:156823d33999 373 _sd_uR3_CMD = 1;
<> 149:156823d33999 374
<> 149:156823d33999 375 if (SD_SDCmdAndRsp(pSD, 1, 0x40ff8000, u32CmdTimeOut) != 2) { // eMMC memory
<> 149:156823d33999 376 resp = SD->RESP0;
<> 149:156823d33999 377 while (!(resp & 0x00800000)) { // check if card is ready
<> 149:156823d33999 378 _sd_uR3_CMD = 1;
<> 149:156823d33999 379
<> 149:156823d33999 380 SD_SDCmdAndRsp(pSD, 1, 0x40ff8000, u32CmdTimeOut); // high voltage
<> 149:156823d33999 381 resp = SD->RESP0;
<> 149:156823d33999 382 }
<> 149:156823d33999 383
<> 149:156823d33999 384 if(resp & 0x00400000)
<> 149:156823d33999 385 pSD->CardType = SD_TYPE_EMMC;
<> 149:156823d33999 386 else
<> 149:156823d33999 387 pSD->CardType = SD_TYPE_MMC;
<> 149:156823d33999 388 } else {
<> 149:156823d33999 389 pSD->CardType = SD_TYPE_UNKNOWN;
<> 149:156823d33999 390 return SD_ERR_DEVICE;
<> 149:156823d33999 391 }
<> 149:156823d33999 392 } else if (i == 0) { // SD Memory
<> 149:156823d33999 393 _sd_uR3_CMD = 1;
<> 149:156823d33999 394 SD_SDCmdAndRsp(pSD, 41, 0x00ff8000, u32CmdTimeOut); // 3.0v-3.4v
<> 149:156823d33999 395 resp = SD->RESP0;
<> 149:156823d33999 396 while (!(resp & 0x00800000)) { // check if card is ready
<> 149:156823d33999 397 SD_SDCmdAndRsp(pSD, 55, 0x00,u32CmdTimeOut);
<> 149:156823d33999 398 _sd_uR3_CMD = 1;
<> 149:156823d33999 399 SD_SDCmdAndRsp(pSD, 41, 0x00ff8000, u32CmdTimeOut); // 3.0v-3.4v
<> 149:156823d33999 400 resp = SD->RESP0;
<> 149:156823d33999 401 }
<> 149:156823d33999 402 pSD->CardType = SD_TYPE_SD_LOW;
<> 149:156823d33999 403 } else {
<> 149:156823d33999 404 pSD->CardType = SD_TYPE_UNKNOWN;
<> 149:156823d33999 405 return SD_INIT_ERROR;
<> 149:156823d33999 406 }
<> 149:156823d33999 407 }
<> 149:156823d33999 408
<> 149:156823d33999 409 // CMD2, CMD3
<> 149:156823d33999 410 if (pSD->CardType != SD_TYPE_UNKNOWN) {
<> 149:156823d33999 411 SD_SDCmdAndRsp2(pSD, 2, 0x00, CIDBuffer);
<> 149:156823d33999 412 if ((pSD->CardType == SD_TYPE_MMC) || (pSD->CardType == SD_TYPE_EMMC)) {
<> 149:156823d33999 413 if ((status = SD_SDCmdAndRsp(pSD, 3, 0x10000, 0)) != Successful) // set RCA
<> 149:156823d33999 414 return status;
<> 149:156823d33999 415 pSD->RCA = 0x10000;
<> 149:156823d33999 416 } else {
<> 149:156823d33999 417 if ((status = SD_SDCmdAndRsp(pSD, 3, 0x00, 0)) != Successful) // get RCA
<> 149:156823d33999 418 return status;
<> 149:156823d33999 419 else
<> 149:156823d33999 420 pSD->RCA = (SD->RESP0 << 8) & 0xffff0000;
<> 149:156823d33999 421 }
<> 149:156823d33999 422 }
<> 149:156823d33999 423
<> 149:156823d33999 424 return Successful;
<> 149:156823d33999 425 }
<> 149:156823d33999 426
<> 149:156823d33999 427
<> 149:156823d33999 428 int SD_SwitchToHighSpeed(SD_INFO_T *pSD)
<> 149:156823d33999 429 {
<> 149:156823d33999 430 int volatile status=0;
<> 149:156823d33999 431 uint16_t current_comsumption, busy_status0;
<> 149:156823d33999 432
<> 149:156823d33999 433 SD->DMASA = (uint32_t)_sd_pSDHCBuffer; // set DMA transfer starting address
<> 149:156823d33999 434 SD->BLEN = 63; // 512 bit
<> 149:156823d33999 435
<> 149:156823d33999 436 if ((status = SD_SDCmdAndRspDataIn(pSD, 6, 0x00ffff01)) != Successful)
<> 149:156823d33999 437 return Fail;
<> 149:156823d33999 438
<> 149:156823d33999 439 current_comsumption = _sd_pSDHCBuffer[0]<<8 | _sd_pSDHCBuffer[1];
<> 149:156823d33999 440 if (!current_comsumption)
<> 149:156823d33999 441 return Fail;
<> 149:156823d33999 442
<> 149:156823d33999 443 busy_status0 = _sd_pSDHCBuffer[28]<<8 | _sd_pSDHCBuffer[29];
<> 149:156823d33999 444
<> 149:156823d33999 445 if (!busy_status0) { // function ready
<> 149:156823d33999 446 SD->DMASA = (uint32_t)_sd_pSDHCBuffer; // set DMA transfer starting address
<> 149:156823d33999 447 SD->BLEN = 63; // 512 bit
<> 149:156823d33999 448
<> 149:156823d33999 449 if ((status = SD_SDCmdAndRspDataIn(pSD, 6, 0x80ffff01)) != Successful)
<> 149:156823d33999 450 return Fail;
<> 149:156823d33999 451
<> 149:156823d33999 452 // function change timing: 8 clocks
<> 149:156823d33999 453 SD->CTL |= SDH_CTL_CLK8OEN_Msk;
<> 149:156823d33999 454 while(SD->CTL & SDH_CTL_CLK8OEN_Msk);
<> 149:156823d33999 455
<> 149:156823d33999 456 current_comsumption = _sd_pSDHCBuffer[0]<<8 | _sd_pSDHCBuffer[1];
<> 149:156823d33999 457 if (!current_comsumption)
<> 149:156823d33999 458 return Fail;
<> 149:156823d33999 459
<> 149:156823d33999 460 return Successful;
<> 149:156823d33999 461 } else
<> 149:156823d33999 462 return Fail;
<> 149:156823d33999 463 }
<> 149:156823d33999 464
<> 149:156823d33999 465
<> 149:156823d33999 466 int SD_SelectCardType(SD_INFO_T *pSD)
<> 149:156823d33999 467 {
<> 149:156823d33999 468 int volatile status=0;
<> 149:156823d33999 469 unsigned int arg;
<> 149:156823d33999 470
<> 149:156823d33999 471 if ((status = SD_SDCmdAndRsp(pSD, 7, pSD->RCA, 0)) != Successful)
<> 149:156823d33999 472 return status;
<> 149:156823d33999 473
<> 149:156823d33999 474 SD_CheckRB();
<> 149:156823d33999 475
<> 149:156823d33999 476 // if SD card set 4bit
<> 149:156823d33999 477 if (pSD->CardType == SD_TYPE_SD_HIGH) {
<> 149:156823d33999 478 _sd_pSDHCBuffer = (uint8_t *)((uint32_t)_sd_ucSDHCBuffer);
<> 149:156823d33999 479 SD->DMASA = (uint32_t)_sd_pSDHCBuffer; // set DMA transfer starting address
<> 149:156823d33999 480 SD->BLEN = 0x07; // 64 bit
<> 149:156823d33999 481
<> 149:156823d33999 482 if ((status = SD_SDCmdAndRsp(pSD, 55, pSD->RCA, 0)) != Successful)
<> 149:156823d33999 483 return status;
<> 149:156823d33999 484 if ((status = SD_SDCmdAndRspDataIn(pSD, 51, 0x00)) != Successful)
<> 149:156823d33999 485 return status;
<> 149:156823d33999 486
<> 149:156823d33999 487 if ((_sd_ucSDHCBuffer[0] & 0xf) == 0x2) {
<> 149:156823d33999 488 status = SD_SwitchToHighSpeed(pSD);
<> 149:156823d33999 489 if (status == Successful) {
<> 149:156823d33999 490 /* divider */
<> 149:156823d33999 491 SD_Set_clock(SDHC_FREQ);
<> 149:156823d33999 492 }
<> 149:156823d33999 493 }
<> 149:156823d33999 494
<> 149:156823d33999 495 if ((status = SD_SDCmdAndRsp(pSD, 55, pSD->RCA, 0)) != Successful)
<> 149:156823d33999 496 return status;
<> 149:156823d33999 497 if ((status = SD_SDCmdAndRsp(pSD, 6, 0x02, 0)) != Successful) // set bus width
<> 149:156823d33999 498 return status;
<> 149:156823d33999 499
<> 149:156823d33999 500 SD->CTL |= SDH_CTL_DBW_Msk;
<> 149:156823d33999 501 } else if (pSD->CardType == SD_TYPE_SD_LOW) {
<> 149:156823d33999 502 _sd_pSDHCBuffer = (uint8_t *)((uint32_t)_sd_ucSDHCBuffer);
<> 149:156823d33999 503 SD->DMASA = (uint32_t) _sd_pSDHCBuffer; // set DMA transfer starting address
<> 149:156823d33999 504 SD->BLEN = 0x07; // 64 bit
<> 149:156823d33999 505
<> 149:156823d33999 506 if ((status = SD_SDCmdAndRsp(pSD, 55, pSD->RCA, 0)) != Successful)
<> 149:156823d33999 507 return status;
<> 149:156823d33999 508 if ((status = SD_SDCmdAndRspDataIn(pSD, 51, 0x00)) != Successful)
<> 149:156823d33999 509 return status;
<> 149:156823d33999 510
<> 149:156823d33999 511 // set data bus width. ACMD6 for SD card, SDCR_DBW for host.
<> 149:156823d33999 512 if ((status = SD_SDCmdAndRsp(pSD, 55, pSD->RCA, 0)) != Successful)
<> 149:156823d33999 513 return status;
<> 149:156823d33999 514
<> 149:156823d33999 515 if ((status = SD_SDCmdAndRsp(pSD, 6, 0x02, 0)) != Successful) // set bus width
<> 149:156823d33999 516 return status;
<> 149:156823d33999 517
<> 149:156823d33999 518 SD->CTL |= SDH_CTL_DBW_Msk;
<> 149:156823d33999 519 } else if ((pSD->CardType == SD_TYPE_MMC) ||(pSD->CardType == SD_TYPE_EMMC)) {
<> 149:156823d33999 520
<> 149:156823d33999 521 if(pSD->CardType == SD_TYPE_MMC)
<> 149:156823d33999 522 SD->CTL &= ~SDH_CTL_DBW_Msk;
<> 149:156823d33999 523
<> 149:156823d33999 524 //--- sent CMD6 to MMC card to set bus width to 4 bits mode
<> 149:156823d33999 525 // set CMD6 argument Access field to 3, Index to 183, Value to 1 (4-bit mode)
<> 149:156823d33999 526 arg = (3 << 24) | (183 << 16) | (1 << 8);
<> 149:156823d33999 527 if ((status = SD_SDCmdAndRsp(pSD, 6, arg, 0)) != Successful)
<> 149:156823d33999 528 return status;
<> 149:156823d33999 529 SD_CheckRB();
<> 149:156823d33999 530
<> 149:156823d33999 531 SD->CTL |= SDH_CTL_DBW_Msk;; // set bus width to 4-bit mode for SD host controller
<> 149:156823d33999 532
<> 149:156823d33999 533 }
<> 149:156823d33999 534
<> 149:156823d33999 535 if ((status = SD_SDCmdAndRsp(pSD, 16, SD_BLOCK_SIZE, 0)) != Successful) // set block length
<> 149:156823d33999 536 return status;
<> 149:156823d33999 537 SD->BLEN = SD_BLOCK_SIZE - 1; // set the block size
<> 149:156823d33999 538
<> 149:156823d33999 539 SD_SDCommand(pSD, 7, 0);
<> 149:156823d33999 540 SD->CTL |= SDH_CTL_CLK8OEN_Msk;
<> 149:156823d33999 541 while(SD->CTL & SDH_CTL_CLK8OEN_Msk);
<> 149:156823d33999 542
<> 149:156823d33999 543 #ifdef _SD_USE_INT_
<> 149:156823d33999 544 SD->INTEN |= SDH_INTEN_BLKDIEN_Msk;
<> 149:156823d33999 545 #endif //_SD_USE_INT_
<> 149:156823d33999 546
<> 149:156823d33999 547 return Successful;
<> 149:156823d33999 548 }
<> 149:156823d33999 549
<> 149:156823d33999 550 void SD_Get_SD_info(SD_INFO_T *pSD, DISK_DATA_T *_info)
<> 149:156823d33999 551 {
<> 149:156823d33999 552 unsigned int R_LEN, C_Size, MULT, size;
<> 149:156823d33999 553 unsigned int Buffer[4];
<> 149:156823d33999 554 unsigned char *ptr;
<> 149:156823d33999 555
<> 149:156823d33999 556 SD_SDCmdAndRsp2(pSD, 9, pSD->RCA, Buffer);
<> 149:156823d33999 557
<> 149:156823d33999 558 if ((pSD->CardType == SD_TYPE_MMC) || (pSD->CardType == SD_TYPE_EMMC)) {
<> 149:156823d33999 559 // for MMC/eMMC card
<> 149:156823d33999 560 if ((Buffer[0] & 0xc0000000) == 0xc0000000) {
<> 149:156823d33999 561 // CSD_STRUCTURE [127:126] is 3
<> 149:156823d33999 562 // CSD version depend on EXT_CSD register in eMMC v4.4 for card size > 2GB
<> 149:156823d33999 563 SD_SDCmdAndRsp(pSD, 7, pSD->RCA, 0);
<> 149:156823d33999 564
<> 149:156823d33999 565 ptr = (uint8_t *)((uint32_t)_sd_ucSDHCBuffer );
<> 149:156823d33999 566 SD->DMASA = (uint32_t)ptr; // set DMA transfer starting address
<> 149:156823d33999 567 SD->BLEN = 511; // read 512 bytes for EXT_CSD
<> 149:156823d33999 568
<> 149:156823d33999 569 if (SD_SDCmdAndRspDataIn(pSD, 8, 0x00) != Successful)
<> 149:156823d33999 570 return;
<> 149:156823d33999 571
<> 149:156823d33999 572 SD_SDCommand(pSD, 7, 0);
<> 149:156823d33999 573 SD->CTL |= SDH_CTL_CLK8OEN_Msk;
<> 149:156823d33999 574 while(SD->CTL & SDH_CTL_CLK8OEN_Msk);
<> 149:156823d33999 575
<> 149:156823d33999 576 _info->totalSectorN = (*(uint32_t *)(ptr+212));
<> 149:156823d33999 577 _info->diskSize = _info->totalSectorN / 2;
<> 149:156823d33999 578 } else {
<> 149:156823d33999 579 // CSD version v1.0/1.1/1.2 in eMMC v4.4 spec for card size <= 2GB
<> 149:156823d33999 580 R_LEN = (Buffer[1] & 0x000f0000) >> 16;
<> 149:156823d33999 581 C_Size = ((Buffer[1] & 0x000003ff) << 2) | ((Buffer[2] & 0xc0000000) >> 30);
<> 149:156823d33999 582 MULT = (Buffer[2] & 0x00038000) >> 15;
<> 149:156823d33999 583 size = (C_Size+1) * (1<<(MULT+2)) * (1<<R_LEN);
<> 149:156823d33999 584
<> 149:156823d33999 585 _info->diskSize = size / 1024;
<> 149:156823d33999 586 _info->totalSectorN = size / 512;
<> 149:156823d33999 587 }
<> 149:156823d33999 588 } else {
<> 149:156823d33999 589 if (Buffer[0] & 0xc0000000) {
<> 149:156823d33999 590 C_Size = ((Buffer[1] & 0x0000003f) << 16) | ((Buffer[2] & 0xffff0000) >> 16);
<> 149:156823d33999 591 size = (C_Size+1) * 512; // Kbytes
<> 149:156823d33999 592
<> 149:156823d33999 593 _info->diskSize = size;
<> 149:156823d33999 594 _info->totalSectorN = size << 1;
<> 149:156823d33999 595 } else {
<> 149:156823d33999 596 R_LEN = (Buffer[1] & 0x000f0000) >> 16;
<> 149:156823d33999 597 C_Size = ((Buffer[1] & 0x000003ff) << 2) | ((Buffer[2] & 0xc0000000) >> 30);
<> 149:156823d33999 598 MULT = (Buffer[2] & 0x00038000) >> 15;
<> 149:156823d33999 599 size = (C_Size+1) * (1<<(MULT+2)) * (1<<R_LEN);
<> 149:156823d33999 600
<> 149:156823d33999 601 _info->diskSize = size / 1024;
<> 149:156823d33999 602 _info->totalSectorN = size / 512;
<> 149:156823d33999 603 }
<> 149:156823d33999 604 }
<> 149:156823d33999 605
<> 149:156823d33999 606 _info->sectorSize = 512;
<> 149:156823d33999 607 }
<> 149:156823d33999 608
<> 149:156823d33999 609 int SD_ChipErase(SD_INFO_T *pSD, DISK_DATA_T *_info)
<> 149:156823d33999 610 {
<> 149:156823d33999 611 int status=0;
<> 149:156823d33999 612
<> 149:156823d33999 613 status = SD_SDCmdAndRsp(pSD, 32, 512, 6000);
<> 149:156823d33999 614 if (status < 0) {
<> 149:156823d33999 615 return status;
<> 149:156823d33999 616 }
<> 149:156823d33999 617 status = SD_SDCmdAndRsp(pSD, 33, _info->totalSectorN*512, 6000);
<> 149:156823d33999 618 if (status < 0) {
<> 149:156823d33999 619 return status;
<> 149:156823d33999 620 }
<> 149:156823d33999 621 status = SD_SDCmdAndRsp(pSD, 38, 0, 6000);
<> 149:156823d33999 622 if (status < 0) {
<> 149:156823d33999 623 return status;
<> 149:156823d33999 624 }
<> 149:156823d33999 625 SD_CheckRB();
<> 149:156823d33999 626
<> 149:156823d33999 627 return 0;
<> 149:156823d33999 628 }
<> 149:156823d33999 629
<> 149:156823d33999 630 /// @endcond HIDDEN_SYMBOLS
<> 149:156823d33999 631
<> 149:156823d33999 632
<> 149:156823d33999 633 /**
<> 149:156823d33999 634 * @brief This function use to reset SD function and select card detection source and pin.
<> 149:156823d33999 635 *
<> 149:156823d33999 636 * @param[in] u32CardDetSrc Select card detection source from SD0 or SD1. ( \ref SD_PORT0 / \ref SD_PORT1) \n
<> 149:156823d33999 637 * And also select card detection pin from GPIO or DAT3 pin. ( \ref CardDetect_From_GPIO / \ref CardDetect_From_DAT3)
<> 149:156823d33999 638 *
<> 149:156823d33999 639 * @return None
<> 149:156823d33999 640 */
<> 149:156823d33999 641 void SD_Open(uint32_t u32CardDetSrc)
<> 149:156823d33999 642 {
<> 149:156823d33999 643 // Enable SD Card Host Controller operation.
<> 149:156823d33999 644 //CLK->AHBCLK |= CLK_AHBCLK_SDHCKEN_Msk;
<> 149:156823d33999 645
<> 149:156823d33999 646 // enable DMAC
<> 149:156823d33999 647 SD->DMACTL = SDH_DMACTL_DMARST_Msk;
<> 149:156823d33999 648 while(SD->DMACTL & SDH_DMACTL_DMARST_Msk);
<> 149:156823d33999 649
<> 149:156823d33999 650 SD->DMACTL = SDH_DMACTL_DMAEN_Msk;
<> 149:156823d33999 651
<> 149:156823d33999 652 //Reset FMI
<> 149:156823d33999 653 SD->GCTL = SDH_GCTL_GCTLRST_Msk; // Start reset FMI controller.
<> 149:156823d33999 654 while(SD->GCTL & SDH_GCTL_GCTLRST_Msk);
<> 149:156823d33999 655
<> 149:156823d33999 656
<> 149:156823d33999 657 //#ifdef _SD_USE_INT_
<> 149:156823d33999 658 // NVIC_EnableIRQ(SD_IRQn);
<> 149:156823d33999 659 //#endif //_SD_USE_INT_
<> 149:156823d33999 660
<> 149:156823d33999 661 // enable SD
<> 149:156823d33999 662 SD->GCTL = SDH_GCTL_SDEN_Msk;
<> 149:156823d33999 663
<> 149:156823d33999 664 if(u32CardDetSrc & SD_PORT0) {
<> 149:156823d33999 665 SD->CTL |= (SD->CTL & ~SDH_CTL_SDPORT_Msk);
<> 149:156823d33999 666
<> 149:156823d33999 667 if(u32CardDetSrc & CardDetect_From_DAT3) {
<> 149:156823d33999 668 SD->INTEN &= ~SDH_INTEN_CDSRC0_Msk;
<> 149:156823d33999 669 } else {
<> 149:156823d33999 670 SD->INTEN |= SDH_INTEN_CDSRC0_Msk;
<> 149:156823d33999 671 }
<> 149:156823d33999 672 } else if(u32CardDetSrc & SD_PORT1) {
<> 149:156823d33999 673 SD->CTL |= ((SD->CTL & ~SDH_CTL_SDPORT_Msk) | (1 << SDH_CTL_SDPORT_Pos));
<> 149:156823d33999 674
<> 149:156823d33999 675 if(u32CardDetSrc & CardDetect_From_DAT3) {
<> 149:156823d33999 676 SD->INTEN &= ~SDH_INTEN_CDSRC1_Msk;
<> 149:156823d33999 677 } else {
<> 149:156823d33999 678 SD->INTEN |= SDH_INTEN_CDSRC1_Msk;
<> 149:156823d33999 679 }
<> 149:156823d33999 680 }
<> 149:156823d33999 681
<> 149:156823d33999 682 SD->CTL |= SDH_CTL_CTLRST_Msk; // SD software reset
<> 149:156823d33999 683 while(SD->CTL & SDH_CTL_CTLRST_Msk);
<> 149:156823d33999 684
<> 149:156823d33999 685 SD->CTL &= ~((0xFF) | (SDH_CTL_CLKKEEP1_Msk)); // disable SD clock output
<> 149:156823d33999 686
<> 149:156823d33999 687 if(u32CardDetSrc & SD_PORT0) {
<> 149:156823d33999 688 memset(&SD0, 0, sizeof(SD_INFO_T));
<> 149:156823d33999 689 } else if(u32CardDetSrc & SD_PORT1) {
<> 149:156823d33999 690 memset(&SD1, 0, sizeof(SD_INFO_T));
<> 149:156823d33999 691 }
<> 149:156823d33999 692
<> 149:156823d33999 693 }
<> 149:156823d33999 694
<> 149:156823d33999 695 /**
<> 149:156823d33999 696 * @brief This function use to initial SD card.
<> 149:156823d33999 697 *
<> 149:156823d33999 698 * @param[in] u32CardNum Select initial SD0 or SD1. ( \ref SD_PORT0 / \ref SD_PORT1)
<> 149:156823d33999 699 *
<> 149:156823d33999 700 * @return None
<> 149:156823d33999 701 */
<> 149:156823d33999 702 void SD_Probe(uint32_t u32CardNum)
<> 149:156823d33999 703 {
<> 149:156823d33999 704 // Disable FMI/SD host interrupt
<> 149:156823d33999 705 SD->GINTEN = 0;
<> 149:156823d33999 706
<> 149:156823d33999 707 SD->CTL &= ~SDH_CTL_SDNWR_Msk;
<> 149:156823d33999 708 SD->CTL |= 0x09 << SDH_CTL_SDNWR_Pos; // set SDNWR = 9
<> 149:156823d33999 709 SD->CTL &= ~SDH_CTL_BLKCNT_Msk;
<> 149:156823d33999 710 SD->CTL |= 0x01 << SDH_CTL_BLKCNT_Pos; // set BLKCNT = 1
<> 149:156823d33999 711 SD->CTL &= ~SDH_CTL_DBW_Msk; // SD 1-bit data bus
<> 149:156823d33999 712
<> 149:156823d33999 713 if(!(SD_CardDetection(u32CardNum)))
<> 149:156823d33999 714 return;
<> 149:156823d33999 715
<> 149:156823d33999 716 if (u32CardNum == SD_PORT0) {
<> 149:156823d33999 717 if (SD_Init(&SD0) < 0)
<> 149:156823d33999 718 return;
<> 149:156823d33999 719
<> 149:156823d33999 720 /* divider */
<> 149:156823d33999 721 if (SD0.CardType == SD_TYPE_MMC)
<> 149:156823d33999 722 SD_Set_clock(20000);
<> 149:156823d33999 723 else
<> 149:156823d33999 724 SD_Set_clock(SD_FREQ);
<> 149:156823d33999 725
<> 149:156823d33999 726 SD_Get_SD_info(&SD0, &SD_DiskInfo0);
<> 149:156823d33999 727
<> 149:156823d33999 728 if (SD_SelectCardType(&SD0))
<> 149:156823d33999 729 return;
<> 149:156823d33999 730
<> 149:156823d33999 731 sd0_ok = 1;
<> 149:156823d33999 732 } else if (u32CardNum == SD_PORT1) {
<> 149:156823d33999 733 if (SD_Init(&SD1) < 0)
<> 149:156823d33999 734 return;
<> 149:156823d33999 735
<> 149:156823d33999 736 /* divider */
<> 149:156823d33999 737 if (SD1.CardType == SD_TYPE_MMC)
<> 149:156823d33999 738 SD_Set_clock(20000);
<> 149:156823d33999 739 else
<> 149:156823d33999 740 SD_Set_clock(SD_FREQ);
<> 149:156823d33999 741
<> 149:156823d33999 742 SD_Get_SD_info(&SD1, &SD_DiskInfo1);
<> 149:156823d33999 743
<> 149:156823d33999 744 if (SD_SelectCardType(&SD1))
<> 149:156823d33999 745 return;
<> 149:156823d33999 746
<> 149:156823d33999 747 sd1_ok = 1;
<> 149:156823d33999 748 }
<> 149:156823d33999 749
<> 149:156823d33999 750
<> 149:156823d33999 751 }
<> 149:156823d33999 752
<> 149:156823d33999 753 /**
<> 149:156823d33999 754 * @brief This function use to read data from SD card.
<> 149:156823d33999 755 *
<> 149:156823d33999 756 * @param[in] u32CardNum Select card: SD0 or SD1. ( \ref SD_PORT0 / \ref SD_PORT1)
<> 149:156823d33999 757 * @param[out] pu8BufAddr The buffer to receive the data from SD card.
<> 149:156823d33999 758 * @param[in] u32StartSec The start read sector address.
<> 149:156823d33999 759 * @param[in] u32SecCount The the read sector number of data
<> 149:156823d33999 760 *
<> 149:156823d33999 761 * @return None
<> 149:156823d33999 762 */
<> 149:156823d33999 763 uint32_t SD_Read(uint32_t u32CardNum, uint8_t *pu8BufAddr, uint32_t u32StartSec, uint32_t u32SecCount)
<> 149:156823d33999 764 {
<> 149:156823d33999 765 char volatile bIsSendCmd = FALSE, buf;
<> 149:156823d33999 766 unsigned int volatile reg;
<> 149:156823d33999 767 int volatile i, loop, status;
<> 149:156823d33999 768 uint32_t blksize = SD_BLOCK_SIZE;
<> 149:156823d33999 769
<> 149:156823d33999 770 SD_INFO_T *pSD;
<> 149:156823d33999 771
<> 149:156823d33999 772 if(u32CardNum == SD_PORT0)
<> 149:156823d33999 773 pSD = &SD0;
<> 149:156823d33999 774 else
<> 149:156823d33999 775 pSD = &SD1;
<> 149:156823d33999 776
<> 149:156823d33999 777 //--- check input parameters
<> 149:156823d33999 778 if (u32SecCount == 0) {
<> 149:156823d33999 779 return SD_SELECT_ERROR;
<> 149:156823d33999 780 }
<> 149:156823d33999 781
<> 149:156823d33999 782 if ((status = SD_SDCmdAndRsp(pSD, 7, pSD->RCA, 0)) != Successful)
<> 149:156823d33999 783 return status;
<> 149:156823d33999 784 SD_CheckRB();
<> 149:156823d33999 785
<> 149:156823d33999 786 SD->BLEN = blksize - 1; // the actual byte count is equal to (SDBLEN+1)
<> 149:156823d33999 787
<> 149:156823d33999 788 if ( (pSD->CardType == SD_TYPE_SD_HIGH) || (pSD->CardType == SD_TYPE_EMMC) )
<> 149:156823d33999 789 SD->CMDARG = u32StartSec;
<> 149:156823d33999 790 else
<> 149:156823d33999 791 SD->CMDARG = u32StartSec * blksize;
<> 149:156823d33999 792
<> 149:156823d33999 793 SD->DMASA = (uint32_t)pu8BufAddr;
<> 149:156823d33999 794
<> 149:156823d33999 795 loop = u32SecCount / 255;
<> 149:156823d33999 796 for (i=0; i<loop; i++) {
<> 149:156823d33999 797 #ifdef _SD_USE_INT_
<> 149:156823d33999 798 _sd_SDDataReady = FALSE;
<> 149:156823d33999 799 #endif //_SD_USE_INT_
<> 149:156823d33999 800
<> 149:156823d33999 801 reg = SD->CTL & ~SDH_CTL_CMDCODE_Msk;
<> 149:156823d33999 802 reg = reg | 0xff0000; // set BLK_CNT to 255
<> 149:156823d33999 803 if (bIsSendCmd == FALSE) {
<> 149:156823d33999 804 SD->CTL = reg|(18<<8)|(SDH_CTL_COEN_Msk | SDH_CTL_RIEN_Msk | SDH_CTL_DIEN_Msk);
<> 149:156823d33999 805 bIsSendCmd = TRUE;
<> 149:156823d33999 806 } else
<> 149:156823d33999 807 SD->CTL = reg | SDH_CTL_DIEN_Msk;
<> 149:156823d33999 808
<> 149:156823d33999 809 #ifdef _SD_USE_INT_
<> 149:156823d33999 810 while(!_sd_SDDataReady)
<> 149:156823d33999 811 #else
<> 149:156823d33999 812 while(1)
<> 149:156823d33999 813 #endif //_SD_USE_INT_
<> 149:156823d33999 814 {
<> 149:156823d33999 815 if(_sd_SDDataReady) break;
<> 149:156823d33999 816
<> 149:156823d33999 817 #ifndef _SD_USE_INT_
<> 149:156823d33999 818 if ((SD->INTSTS & SDH_INTSTS_BLKDIF_Msk) && (!(SD->CTL & SDH_CTL_DIEN_Msk))) {
<> 149:156823d33999 819 SD->INTSTS = SDH_INTSTS_BLKDIF_Msk;
<> 149:156823d33999 820 break;
<> 149:156823d33999 821 }
<> 149:156823d33999 822 #endif
<> 149:156823d33999 823 if (pSD->IsCardInsert == FALSE)
<> 149:156823d33999 824 return SD_NO_SD_CARD;
<> 149:156823d33999 825 }
<> 149:156823d33999 826
<> 149:156823d33999 827 if (!(SD->INTSTS & SDH_INTSTS_CRC7_Msk)) { // check CRC7
<> 149:156823d33999 828 //printf("sdioSD_Read_in_blksize(): response error!\n");
<> 149:156823d33999 829 return SD_CRC7_ERROR;
<> 149:156823d33999 830 }
<> 149:156823d33999 831
<> 149:156823d33999 832 if (!(SD->INTSTS & SDH_INTSTS_CRC16_Msk)) { // check CRC16
<> 149:156823d33999 833 //printf("sdioSD_Read_in_blksize() :read data error!\n");
<> 149:156823d33999 834 return SD_CRC16_ERROR;
<> 149:156823d33999 835 }
<> 149:156823d33999 836 }
<> 149:156823d33999 837
<> 149:156823d33999 838 loop = u32SecCount % 255;
<> 149:156823d33999 839 if (loop != 0) {
<> 149:156823d33999 840 #ifdef _SD_USE_INT_
<> 149:156823d33999 841 _sd_SDDataReady = FALSE;
<> 149:156823d33999 842 #endif //_SD_USE_INT_
<> 149:156823d33999 843
<> 149:156823d33999 844 reg = SD->CTL & (~SDH_CTL_CMDCODE_Msk);
<> 149:156823d33999 845 reg = reg & (~SDH_CTL_BLKCNT_Msk);
<> 149:156823d33999 846 reg |= (loop << 16); // setup SDCR_BLKCNT
<> 149:156823d33999 847
<> 149:156823d33999 848 if (bIsSendCmd == FALSE) {
<> 149:156823d33999 849 SD->CTL = reg|(18<<8)|(SDH_CTL_COEN_Msk | SDH_CTL_RIEN_Msk | SDH_CTL_DIEN_Msk);
<> 149:156823d33999 850 bIsSendCmd = TRUE;
<> 149:156823d33999 851 } else
<> 149:156823d33999 852 SD->CTL = reg | SDH_CTL_DIEN_Msk;
<> 149:156823d33999 853
<> 149:156823d33999 854 #ifdef _SD_USE_INT_
<> 149:156823d33999 855 while(!_sd_SDDataReady)
<> 149:156823d33999 856 #else
<> 149:156823d33999 857 while(1)
<> 149:156823d33999 858 #endif //_SD_USE_INT_
<> 149:156823d33999 859 {
<> 149:156823d33999 860
<> 149:156823d33999 861 #ifndef _SD_USE_INT_
<> 149:156823d33999 862 if ((SD->INTSTS & SDH_INTSTS_BLKDIF_Msk) && (!(SD->CTL & SDH_CTL_DIEN_Msk))) {
<> 149:156823d33999 863 SD->INTSTS = SDH_INTSTS_BLKDIF_Msk;
<> 149:156823d33999 864 break;
<> 149:156823d33999 865 }
<> 149:156823d33999 866 #endif
<> 149:156823d33999 867
<> 149:156823d33999 868 if (pSD->IsCardInsert == FALSE)
<> 149:156823d33999 869 return SD_NO_SD_CARD;
<> 149:156823d33999 870 }
<> 149:156823d33999 871
<> 149:156823d33999 872 if (!(SD->INTSTS & SDH_INTSTS_CRC7_Msk)) { // check CRC7
<> 149:156823d33999 873 //printf("sdioSD_Read_in_blksize(): response error!\n");
<> 149:156823d33999 874 return SD_CRC7_ERROR;
<> 149:156823d33999 875 }
<> 149:156823d33999 876
<> 149:156823d33999 877 if (!(SD->INTSTS & SDH_INTSTS_CRC16_Msk)) { // check CRC16
<> 149:156823d33999 878 //printf("sdioSD_Read_in_blksize(): read data error!\n");
<> 149:156823d33999 879 return SD_CRC16_ERROR;
<> 149:156823d33999 880 }
<> 149:156823d33999 881 }
<> 149:156823d33999 882
<> 149:156823d33999 883 if (SD_SDCmdAndRsp(pSD, 12, 0, 0)) { // stop command
<> 149:156823d33999 884 //printf("stop command fail !!\n");
<> 149:156823d33999 885 return SD_CRC7_ERROR;
<> 149:156823d33999 886 }
<> 149:156823d33999 887 SD_CheckRB();
<> 149:156823d33999 888
<> 149:156823d33999 889 SD_SDCommand(pSD, 7, 0);
<> 149:156823d33999 890 SD->CTL |= SDH_CTL_CLK8OEN_Msk;
<> 149:156823d33999 891 while(SD->CTL & SDH_CTL_CLK8OEN_Msk);
<> 149:156823d33999 892
<> 149:156823d33999 893 return Successful;
<> 149:156823d33999 894 }
<> 149:156823d33999 895
<> 149:156823d33999 896
<> 149:156823d33999 897 /**
<> 149:156823d33999 898 * @brief This function use to write data to SD card.
<> 149:156823d33999 899 *
<> 149:156823d33999 900 * @param[in] u32CardNum Select card: SD0 or SD1. ( \ref SD_PORT0 / \ref SD_PORT1)
<> 149:156823d33999 901 * @param[in] pu8BufAddr The buffer to send the data to SD card.
<> 149:156823d33999 902 * @param[in] u32StartSec The start write sector address.
<> 149:156823d33999 903 * @param[in] u32SecCount The the write sector number of data.
<> 149:156823d33999 904 *
<> 149:156823d33999 905 * @return \ref SD_SELECT_ERROR : u32SecCount is zero. \n
<> 149:156823d33999 906 * \ref SD_NO_SD_CARD : SD card be removed. \n
<> 149:156823d33999 907 * \ref SD_CRC_ERROR : CRC error happen. \n
<> 149:156823d33999 908 * \ref SD_CRC7_ERROR : CRC7 error happen. \n
<> 149:156823d33999 909 * \ref Successful : Write data to SD card success.
<> 149:156823d33999 910 */
<> 149:156823d33999 911 uint32_t SD_Write(uint32_t u32CardNum, uint8_t *pu8BufAddr, uint32_t u32StartSec, uint32_t u32SecCount)
<> 149:156823d33999 912 {
<> 149:156823d33999 913 char volatile bIsSendCmd = FALSE;
<> 149:156823d33999 914 unsigned int volatile reg;
<> 149:156823d33999 915 int volatile i, loop, status;
<> 149:156823d33999 916
<> 149:156823d33999 917 SD_INFO_T *pSD;
<> 149:156823d33999 918
<> 149:156823d33999 919 if(u32CardNum == SD_PORT0)
<> 149:156823d33999 920 pSD = &SD0;
<> 149:156823d33999 921 else
<> 149:156823d33999 922 pSD = &SD1;
<> 149:156823d33999 923
<> 149:156823d33999 924
<> 149:156823d33999 925 //--- check input parameters
<> 149:156823d33999 926 if (u32SecCount == 0) {
<> 149:156823d33999 927 return SD_SELECT_ERROR;
<> 149:156823d33999 928 }
<> 149:156823d33999 929
<> 149:156823d33999 930 if ((status = SD_SDCmdAndRsp(pSD, 7, pSD->RCA, 0)) != Successful)
<> 149:156823d33999 931 return status;
<> 149:156823d33999 932
<> 149:156823d33999 933 SD_CheckRB();
<> 149:156823d33999 934
<> 149:156823d33999 935 // According to SD Spec v2.0, the write CMD block size MUST be 512, and the start address MUST be 512*n.
<> 149:156823d33999 936 SD->BLEN = SD_BLOCK_SIZE - 1; // set the block size
<> 149:156823d33999 937
<> 149:156823d33999 938 if ((pSD->CardType == SD_TYPE_SD_HIGH) || (pSD->CardType == SD_TYPE_EMMC))
<> 149:156823d33999 939 SD->CMDARG = u32StartSec;
<> 149:156823d33999 940 else
<> 149:156823d33999 941 SD->CMDARG = u32StartSec * SD_BLOCK_SIZE; // set start address for SD CMD
<> 149:156823d33999 942
<> 149:156823d33999 943 SD->DMASA = (uint32_t)pu8BufAddr;
<> 149:156823d33999 944 loop = u32SecCount / 255; // the maximum block count is 0xFF=255 for register SDCR[BLK_CNT]
<> 149:156823d33999 945 for (i=0; i<loop; i++) {
<> 149:156823d33999 946 #ifdef _SD_USE_INT_
<> 149:156823d33999 947 _sd_SDDataReady = FALSE;
<> 149:156823d33999 948 #endif //_SD_USE_INT_
<> 149:156823d33999 949
<> 149:156823d33999 950 reg = SD->CTL & 0xff00c080;
<> 149:156823d33999 951 reg = reg | 0xff0000; // set BLK_CNT to 0xFF=255
<> 149:156823d33999 952 if (!bIsSendCmd) {
<> 149:156823d33999 953 SD->CTL = reg|(25<<8)|(SDH_CTL_COEN_Msk | SDH_CTL_RIEN_Msk | SDH_CTL_DOEN_Msk);
<> 149:156823d33999 954 bIsSendCmd = TRUE;
<> 149:156823d33999 955 } else
<> 149:156823d33999 956 SD->CTL = reg | SDH_CTL_DOEN_Msk;
<> 149:156823d33999 957
<> 149:156823d33999 958 #ifdef _SD_USE_INT_
<> 149:156823d33999 959 while(!_sd_SDDataReady)
<> 149:156823d33999 960 #else
<> 149:156823d33999 961 while(1)
<> 149:156823d33999 962 #endif //_SD_USE_INT_
<> 149:156823d33999 963 {
<> 149:156823d33999 964 #ifndef _SD_USE_INT_
<> 149:156823d33999 965 if ((SD->INTSTS & SDH_INTSTS_BLKDIF_Msk) && (!(SD->CTL & SDH_CTL_DOEN_Msk))) {
<> 149:156823d33999 966 SD->INTSTS = SDH_INTSTS_BLKDIF_Msk;
<> 149:156823d33999 967 break;
<> 149:156823d33999 968 }
<> 149:156823d33999 969 #endif
<> 149:156823d33999 970 if (pSD->IsCardInsert == FALSE)
<> 149:156823d33999 971 return SD_NO_SD_CARD;
<> 149:156823d33999 972 }
<> 149:156823d33999 973
<> 149:156823d33999 974 if ((SD->INTSTS & SDH_INTSTS_CRCIF_Msk) != 0) { // check CRC
<> 149:156823d33999 975 SD->INTSTS = SDH_INTSTS_CRCIF_Msk;
<> 149:156823d33999 976 return SD_CRC_ERROR;
<> 149:156823d33999 977 }
<> 149:156823d33999 978 }
<> 149:156823d33999 979
<> 149:156823d33999 980 loop = u32SecCount % 255;
<> 149:156823d33999 981 if (loop != 0) {
<> 149:156823d33999 982 #ifdef _SD_USE_INT_
<> 149:156823d33999 983 _sd_SDDataReady = FALSE;
<> 149:156823d33999 984 #endif //_SD_USE_INT_
<> 149:156823d33999 985
<> 149:156823d33999 986 reg = (SD->CTL & 0xff00c080) | (loop << 16);
<> 149:156823d33999 987 if (!bIsSendCmd) {
<> 149:156823d33999 988 SD->CTL = reg|(25<<8)|(SDH_CTL_COEN_Msk | SDH_CTL_RIEN_Msk | SDH_CTL_DOEN_Msk);
<> 149:156823d33999 989 bIsSendCmd = TRUE;
<> 149:156823d33999 990 } else
<> 149:156823d33999 991 SD->CTL = reg | SDH_CTL_DOEN_Msk;
<> 149:156823d33999 992
<> 149:156823d33999 993 #ifdef _SD_USE_INT_
<> 149:156823d33999 994 while(!_sd_SDDataReady)
<> 149:156823d33999 995 #else
<> 149:156823d33999 996 while(1)
<> 149:156823d33999 997 #endif //_SD_USE_INT_
<> 149:156823d33999 998 {
<> 149:156823d33999 999 #ifndef _SD_USE_INT_
<> 149:156823d33999 1000 if ((SD->INTSTS & SDH_INTSTS_BLKDIF_Msk) && (!(SD->CTL & SDH_CTL_DOEN_Msk))) {
<> 149:156823d33999 1001 SD->INTSTS = SDH_INTSTS_BLKDIF_Msk;
<> 149:156823d33999 1002 break;
<> 149:156823d33999 1003 }
<> 149:156823d33999 1004 #endif
<> 149:156823d33999 1005 if (pSD->IsCardInsert == FALSE)
<> 149:156823d33999 1006 return SD_NO_SD_CARD;
<> 149:156823d33999 1007 }
<> 149:156823d33999 1008
<> 149:156823d33999 1009 if ((SD->INTSTS & SDH_INTSTS_CRCIF_Msk) != 0) { // check CRC
<> 149:156823d33999 1010 SD->INTSTS = SDH_INTSTS_CRCIF_Msk;
<> 149:156823d33999 1011 return SD_CRC_ERROR;
<> 149:156823d33999 1012 }
<> 149:156823d33999 1013 }
<> 149:156823d33999 1014 SD->INTSTS = SDH_INTSTS_CRCIF_Msk;
<> 149:156823d33999 1015
<> 149:156823d33999 1016 if (SD_SDCmdAndRsp(pSD, 12, 0, 0)) { // stop command
<> 149:156823d33999 1017 return SD_CRC7_ERROR;
<> 149:156823d33999 1018 }
<> 149:156823d33999 1019 SD_CheckRB();
<> 149:156823d33999 1020
<> 149:156823d33999 1021 SD_SDCommand(pSD, 7, 0);
<> 149:156823d33999 1022 SD->CTL |= SDH_CTL_CLK8OEN_Msk;
<> 149:156823d33999 1023 while(SD->CTL & SDH_CTL_CLK8OEN_Msk);
<> 149:156823d33999 1024
<> 149:156823d33999 1025 return Successful;
<> 149:156823d33999 1026 }
<> 149:156823d33999 1027
<> 149:156823d33999 1028
<> 149:156823d33999 1029 /*@}*/ /* end of group NUC472_442_SD_EXPORTED_FUNCTIONS */
<> 149:156823d33999 1030
<> 149:156823d33999 1031 /*@}*/ /* end of group NUC472_442_SD_Driver */
<> 149:156823d33999 1032
<> 149:156823d33999 1033 /*@}*/ /* end of group NUC472_442_Device_Driver */
<> 149:156823d33999 1034
<> 149:156823d33999 1035 /*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/
<> 149:156823d33999 1036
<> 149:156823d33999 1037
<> 149:156823d33999 1038
<> 149:156823d33999 1039
<> 149:156823d33999 1040
<> 149:156823d33999 1041
<> 149:156823d33999 1042
<> 149:156823d33999 1043