Fix doc path
[opentx.git] / radio / src / targets / sky9x / diskio.cpp
blob161d90adc7bc9567198464609fa488b550f58594
1 /*
2 * Copyright (C) OpenTX
4 * Based on code named
5 * th9x - http://code.google.com/p/th9x
6 * er9x - http://code.google.com/p/er9x
7 * gruvin9x - http://code.google.com/p/gruvin9x
9 * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
21 /*-----------------------------------------------------------------------*/
22 /* MMCv3/SDv1/SDv2 (in SPI mode) control module (C)ChaN, 2010 */
23 /*-----------------------------------------------------------------------*/
24 /* Only rcvr_spi(), xmit_spi(), sdPoll10ms() and some macros */
25 /* are platform dependent. */
26 /*-----------------------------------------------------------------------*/
28 #include "opentx.h"
29 #include "diskio.h"
31 #define CARD_TYPE_bmHC (1 << 0) /**< Bit for High-Capacity(Density) */
32 #define CARD_TYPE_bmSDMMC (0x3 << 1) /**< Bits mask for SD/MMC */
33 #define CARD_TYPE_bmUNKNOWN (0x0 << 1) /**< Bits for Unknown card */
34 #define CARD_TYPE_bmSD (0x1 << 1) /**< Bits for SD */
35 #define CARD_TYPE_bmMMC (0x2 << 1) /**< Bits for MMC */
36 #define CARD_TYPE_bmSDIO (1 << 3) /**< Bit for SDIO */
37 /** Card can not be identified */
38 #define CARD_UNKNOWN (0)
39 /** SD Card (0x2) */
40 #define CARD_SD (CARD_TYPE_bmSD)
41 /** SD High Capacity Card (0x3) */
42 #define CARD_SDHC (CARD_TYPE_bmSD|CARD_TYPE_bmHC)
43 /** MMC Card (0x4) */
44 #define CARD_MMC (CARD_TYPE_bmMMC)
45 /** MMC High-Density Card (0x5) */
46 #define CARD_MMCHD (CARD_TYPE_bmMMC|CARD_TYPE_bmHC)
47 /** SDIO only card (0x8) */
48 #define CARD_SDIO (CARD_TYPE_bmSDIO)
49 /** SDIO Combo, with SD embedded (0xA) */
50 #define CARD_SDCOMBO (CARD_TYPE_bmSDIO|CARD_SD)
51 /** SDIO Combo, with SDHC embedded (0xB) */
52 #define CARD_SDHCCOMBO (CARD_TYPE_bmSDIO|CARD_SDHC)
54 #define STATUS_READY_FOR_DATA (1UL << 8)
55 #define STATUS_TRAN (4UL << 9)
56 #define STATUS_STATE (0xFUL << 9)
58 /** Bit mask for data errors */
59 #define STATUS_ERRORS_DATA ((uint32_t)(HSMCI_SR_UNRE \
60 | HSMCI_SR_OVRE \
61 /*| HSMCI_SR_BLKOVRE*/ \
62 /*| HSMCI_SR_CSTOE*/ \
63 | HSMCI_SR_DTOE \
64 | HSMCI_SR_DCRCE))
67 uint32_t Card_ID[4] ;
68 uint32_t Card_SCR[2] ;
69 uint32_t Card_CSD[4] ;
70 int32_t Card_state = SD_ST_STARTUP ;
71 volatile uint32_t Card_initialized = 0;
72 uint32_t Sd_rca ;
73 uint32_t Cmd_A41_resp ;
74 uint8_t cardType;
75 uint32_t transSpeed;
77 /*-----------------------------------------------------------------------*/
78 /* Lock / unlock functions */
79 /*-----------------------------------------------------------------------*/
81 #if !defined(BOOT)
82 static OS_MutexID ioMutex;
83 volatile int mutexCheck = 0;
84 int ff_cre_syncobj (BYTE vol, _SYNC_t *mutex)
86 *mutex = ioMutex;
87 return 1;
90 int ff_req_grant (_SYNC_t mutex)
92 CoEnterMutexSection(mutex);
93 return 1;
96 void ff_rel_grant (_SYNC_t mutex)
98 CoLeaveMutexSection(mutex);
101 int ff_del_syncobj (_SYNC_t mutex)
103 return 1;
105 #endif
107 //------------------------------------------------------------------------------
108 /// Get Trans Speed Value (Kbit/s)
109 /// \param tranSpeed The TRAN_SPEED value from SD(IO)/MMC enum information.
110 /// \param unitList Transfer rate units (Kbit/s), 4 units listed.
111 /// \param nbUnits Transfer rate units list size.
112 /// \param codeList Time value codes list, 16 codes listed.
113 //------------------------------------------------------------------------------
114 static unsigned int MmcGetTranSpeed(unsigned int tranSpeed,
115 const unsigned int* unitList, unsigned int nbUnits,
116 const unsigned int* codeList)
118 unsigned int unit, value;
119 unit = tranSpeed & 0x7;
120 if (unit < nbUnits) unit = unitList[unit];
121 else return 0;
122 value = (tranSpeed >> 3) & 0xF;
123 if (value < 16) value = codeList[value];
124 else return 0;
125 return (unit * value);
128 //------------------------------------------------------------------------------
129 /// Get Trans Speed Value
130 /// \param pSd
131 //------------------------------------------------------------------------------
132 uint32_t GetTransSpeedValue()
134 // CSD register, TRANS_SPEED bit
135 const unsigned int units[4] = {10, 100, 1000, 10000 }; // *Kbit/s
136 /* const unsigned int values_emmc[16] = {0, 10, 12, 13, 15, 20,
137 26, 30, 35, 40, 45, 52,
138 55, 60, 70, 80}; */
139 const unsigned int values_sdmmc[16] = {0, 10, 12, 13, 15, 20,
140 25, 30, 35, 40, 45, 50,
141 55, 60, 70, 80};
142 #if 0
143 unsigned int unit, value;
144 unit = (SD_CSD_TRAN_SPEED(pSd) & 0x7);
145 if(unit < 4) unit = units[unit];
146 else return;
147 value = (SD_CSD_TRAN_SPEED(pSd) >> 3) & 0xF;
148 if (value < 16) {
149 if (pSd->cardType >= CARD_MMC && SD_CID_BGA(pSd) == 1) {
150 value = values_emmc[value];
152 else
153 value = values_sdmmc[value];
155 else return;
156 pSd->transSpeed = (unit * value);
157 #else
158 transSpeed = MmcGetTranSpeed(SD_CSD_TRAN_SPEED(Card_CSD),
159 units, 4,
160 values_sdmmc);
161 #endif
162 /*if (pSd->cardType >= CARD_MMC && SD_EXTCSD_HS_TIMING(pSd)) {
163 pSd->transSpeed *= 2;
165 TRACE_ERROR("-I- SD/MMC TRANS SPEED %d KBit/s\r\n", transSpeed);
166 transSpeed *= 1000;
167 return transSpeed;
171 * Configure the MCI CLKDIV in the MCI_MR register. The max. for MCI clock is
172 * MCK/2 and corresponds to CLKDIV = 0
173 * \param mciSpeed MCI clock speed in Hz, 0 will not change current speed.
174 * \return The actual speed used, 0 for fail.
176 uint32_t sdSetSpeed(uint32_t mciSpeed )
178 uint32_t mciMr;
179 uint32_t clkdiv, divLimit;
181 mciMr = HSMCI->HSMCI_MR & (~(uint32_t)HSMCI_MR_CLKDIV_Msk);
182 /* Multimedia Card Interface clock (MCCK or MCI_CK) is Master Clock (MCK)
183 * divided by (2*(CLKDIV+1))
184 * mciSpeed = MCK / (2*(CLKDIV+1)) */
185 if (mciSpeed > 0) {
187 #if 1
188 divLimit = (Master_frequency / 2 / mciSpeed);
189 if ((Master_frequency / 2) % mciSpeed) divLimit ++;
191 clkdiv = (Master_frequency / 2 / mciSpeed);
192 if (mciSpeed && clkdiv < divLimit)
193 clkdiv = divLimit;
194 if (clkdiv > 0)
195 clkdiv -= 1;
196 #else
197 clkdiv = (Master_frequency / 2 / mciSpeed);
198 /* Speed should not bigger than expired one */
199 if (mciSpeed < Master_frequency / 2 / clkdiv) {
200 clkdiv++;
202 if (clkdiv > 0) {
203 clkdiv -= 1;
205 #endif
207 else {
208 clkdiv = 0;
211 /* Actual MCI speed */
212 mciSpeed = Master_frequency / 2 / (clkdiv + 1);
213 /* Modify MR */
214 HSMCI->HSMCI_MR = mciMr | clkdiv;
216 return mciSpeed;
219 #if 0
220 void SD_SetBlklen( uint32_t blklen )
222 uint32_t mciMr;
223 uint32_t clkdiv;
225 mciMr = HSMCI->HSMCI_MR & (~(uint32_t)HSMCI_MR_BLKLEN);
226 /* Modify MR */
227 HSMCI->HSMCI_MR = mciMr | blklen << 16 ;
229 #endif
231 #if 0
233 * Reset MCI HW interface and disable it.
234 * \param keepSettings Keep old register settings, including
235 * _MR, _SDCR, _DTOR, _CSTOR, _DMA and _CFG.
237 void SD_Reset( uint8_t keepSettings)
239 Hsmci *pMciHw = HSMCI ;
241 if (keepSettings)
243 uint32_t mr, sdcr, dtor, cstor;
244 uint32_t cfg;
245 mr = pMciHw->HSMCI_MR;
246 sdcr = pMciHw->HSMCI_SDCR;
247 dtor = pMciHw->HSMCI_DTOR;
248 cstor = pMciHw->HSMCI_CSTOR;
249 cfg = pMciHw->HSMCI_CFG;
250 pMciHw->HSMCI_CR = HSMCI_CR_SWRST ; // Reset
251 pMciHw->HSMCI_CR = HSMCI_CR_MCIDIS; // Disable
252 pMciHw->HSMCI_MR = mr;
253 pMciHw->HSMCI_SDCR = sdcr;
254 pMciHw->HSMCI_DTOR = dtor;
255 pMciHw->HSMCI_CSTOR = cstor;
256 pMciHw->HSMCI_CFG = cfg;
258 else
260 pMciHw->HSMCI_CR = HSMCI_CR_SWRST ; // Reset
261 pMciHw->HSMCI_CR = HSMCI_CR_MCIDIS; // Disable
264 #endif
266 const char SD_NORESPONSE[] = "No response";
268 const char * sdCommand(uint32_t cmd, uint32_t arg)
270 uint32_t i;
271 Hsmci *phsmci = HSMCI;
273 if (SD_CARD_PRESENT()) {
274 phsmci->HSMCI_ARGR = arg;
275 phsmci->HSMCI_CMDR = cmd;
277 for (i = 0; i < 50000; i += 1) {
278 if (phsmci->HSMCI_SR & HSMCI_SR_CMDRDY) {
279 return 0;
282 return SD_NORESPONSE;
284 else {
285 return "No Sdcard";
289 #define SDMMC_POWER_ON_INIT (0 | HSMCI_CMDR_TRCMD_NO_DATA \
290 | HSMCI_CMDR_SPCMD_INIT \
291 | HSMCI_CMDR_OPDCMD )
293 const char * sdPowerOn()
295 return sdCommand(SDMMC_POWER_ON_INIT, 0);
298 #define SDMMC_GO_IDLE_STATE (0 | HSMCI_CMDR_TRCMD_NO_DATA \
299 | HSMCI_CMDR_SPCMD_STD )
301 const char * sdCmd0()
303 return sdCommand(SDMMC_GO_IDLE_STATE, 0);
306 #if 0
307 #define SDIO_SEND_OP_COND (5 | HSMCI_CMDR_SPCMD_STD \
308 | HSMCI_CMDR_TRCMD_NO_DATA \
309 | HSMCI_CMDR_RSPTYP_48_BIT \
310 | HSMCI_CMDR_OPDCMD )
312 const char * sdCmd5(uint32_t *pIo)
314 const char * result = sdCommand(SDIO_SEND_OP_COND, *pIo);
315 if (result)
316 return result;
317 *pIo = HSMCI->HSMCI_RSPR[0];
318 return 0;
320 #endif
322 #define SD_SEND_IF_COND (8 | HSMCI_CMDR_TRCMD_NO_DATA \
323 | HSMCI_CMDR_SPCMD_STD \
324 | HSMCI_CMDR_RSPTYP_48_BIT \
325 | HSMCI_CMDR_OPDCMD /* BSS difference */ \
326 | HSMCI_CMDR_MAXLAT )
328 const char * sdCmd8(uint8_t supplyVoltage)
330 return sdCommand(SD_SEND_IF_COND, (supplyVoltage << 8) | (0xAA));
333 #define SDMMC_APP_CMD (55| HSMCI_CMDR_SPCMD_STD \
334 | HSMCI_CMDR_RSPTYP_48_BIT \
335 | HSMCI_CMDR_TRCMD_NO_DATA \
336 | HSMCI_CMDR_MAXLAT)
338 const char * sdCmd55()
340 return sdCommand(SDMMC_APP_CMD, Sd_rca);
343 #define SDMMC_SEND_STATUS_CMD (13 | HSMCI_CMDR_TRCMD_NO_DATA \
344 | HSMCI_CMDR_SPCMD_STD \
345 | HSMCI_CMDR_RSPTYP_48_BIT \
346 | HSMCI_CMDR_MAXLAT )
348 const char * sdCmd13(unsigned int *status)
350 const char *result = sdCommand(SDMMC_SEND_STATUS_CMD, Sd_rca);
351 if (result)
352 return result;
353 *status = HSMCI->HSMCI_RSPR[0];
354 return 0;
357 #define SDMMC_SET_BLOCKLEN (16 | HSMCI_CMDR_TRCMD_NO_DATA \
358 | HSMCI_CMDR_SPCMD_STD \
359 | HSMCI_CMDR_RSPTYP_48_BIT \
360 | HSMCI_CMDR_MAXLAT_64 )
362 uint32_t sdCmd16()
364 Hsmci *phsmci = HSMCI;
366 if (SD_CARD_PRESENT()) {
367 phsmci->HSMCI_BLKR = ( ( 512 ) << 16 ) | 1 ;
368 phsmci->HSMCI_ARGR = 512;
369 phsmci->HSMCI_CMDR = SDMMC_SET_BLOCKLEN;
371 while(1) {
372 if (phsmci->HSMCI_SR & HSMCI_SR_CMDRDY) {
373 break;
376 return phsmci->HSMCI_RSPR[0];
378 else {
379 return 0;
383 #define SD_SD_SEND_OP_COND (41| HSMCI_CMDR_SPCMD_STD \
384 | HSMCI_CMDR_RSPTYP_48_BIT \
385 | HSMCI_CMDR_TRCMD_NO_DATA \
386 /*| HSMCI_CMDR_OPDCMD_OPENDRAIN */ )
388 const char * sdCmd41(uint32_t arg, uint32_t * status)
390 const char * result = sdCommand(SD_SD_SEND_OP_COND, arg);
391 if (result)
392 return result;
393 *status = HSMCI->HSMCI_RSPR[0];
394 return 0;
397 #define OCR_VDD_27_28 ((uint32_t)(1 << 15))
398 #define OCR_VDD_28_29 ((uint32_t)(1 << 16))
399 #define OCR_VDD_29_30 ((uint32_t)(1 << 17))
400 #define OCR_VDD_30_31 ((uint32_t)(1 << 18))
401 #define OCR_VDD_31_32 ((uint32_t)(1 << 19))
402 #define OCR_VDD_32_33 ((uint32_t)(1 << 20))
403 #define OCR_VDD_33_34 ((uint32_t)(1 << 21))
405 #define SDMMC_HOST_VOLTAGE_RANGE (OCR_VDD_27_28 +\
406 OCR_VDD_28_29 +\
407 OCR_VDD_29_30 +\
408 OCR_VDD_30_31 +\
409 OCR_VDD_31_32 +\
410 OCR_VDD_32_33 +\
411 OCR_VDD_32_33) /* not in SAM3S reference code */
413 #define OCR_POWER_UP_BUSY (1UL << 31)
415 const char * sdMemInit(uint8_t hcs, uint32_t *pCCS)
417 const char * result;
418 uint32_t arg;
419 uint32_t status;
420 do {
421 result = sdCmd55();
422 if (result)
423 return result;
424 arg = SDMMC_HOST_VOLTAGE_RANGE;
425 if (hcs) arg |= OCR_SD_CCS;
426 result = sdCmd41(arg, &status);
427 if (result)
428 return result;
429 *pCCS = (status & OCR_SD_CCS);
430 } while ((status & OCR_POWER_UP_BUSY) != OCR_POWER_UP_BUSY);
431 return 0;
434 // Get Card ID
435 const char * sdCmd2()
437 const char * result = sdCommand(0x00001082, 0);
438 if (result)
439 return result;
441 Hsmci *phsmci = HSMCI ;
442 Card_ID[0] = phsmci->HSMCI_RSPR[0] ;
443 Card_ID[1] = phsmci->HSMCI_RSPR[1] ;
444 Card_ID[2] = phsmci->HSMCI_RSPR[2] ;
445 Card_ID[3] = phsmci->HSMCI_RSPR[3] ;
446 return 0;
449 // Get new RCA
450 const char * sdCmd3()
452 const char * result = sdCommand(0x00001043, 0);
453 if (result)
454 return result;
455 Sd_rca = HSMCI->HSMCI_RSPR[0];
456 return 0;
459 // Get CSD
460 const char * sdCmd9()
462 const char * result = sdCommand(0x00001089, Sd_rca);
463 if (result)
464 return result;
466 Hsmci *phsmci = HSMCI ;
467 Card_CSD[0] = phsmci->HSMCI_RSPR[0] ;
468 Card_CSD[1] = phsmci->HSMCI_RSPR[1] ;
469 Card_CSD[2] = phsmci->HSMCI_RSPR[2] ;
470 Card_CSD[3] = phsmci->HSMCI_RSPR[3] ;
471 return 0;
474 /** Cmd7 MCI, ac, R1/R1b */
475 #define SDMMC_SELECT_CARD (7 | HSMCI_CMDR_TRCMD_NO_DATA \
476 | HSMCI_CMDR_SPCMD_STD \
477 | HSMCI_CMDR_RSPTYP_R1B \
478 | HSMCI_CMDR_MAXLAT )
480 const char * sdCmd7()
482 return sdCommand(SDMMC_SELECT_CARD, Sd_rca);
485 #define SD_SEND_SCR (51 | HSMCI_CMDR_SPCMD_STD | HSMCI_CMDR_RSPTYP_48_BIT \
486 | HSMCI_CMDR_TRCMD_START_DATA | HSMCI_CMDR_TRDIR_READ \
487 | HSMCI_CMDR_TRTYP_SINGLE | HSMCI_CMDR_MAXLAT)
489 #define SD_READ_SINGLE_BLOCK (17 | HSMCI_CMDR_SPCMD_STD | HSMCI_CMDR_RSPTYP_48_BIT \
490 | HSMCI_CMDR_TRCMD_START_DATA | HSMCI_CMDR_TRDIR_READ \
491 | HSMCI_CMDR_TRTYP_SINGLE | HSMCI_CMDR_MAXLAT)
493 #define SD_WRITE_SINGLE_BLOCK (24 | HSMCI_CMDR_SPCMD_STD \
494 | HSMCI_CMDR_RSPTYP_48_BIT \
495 | HSMCI_CMDR_TRCMD_START_DATA \
496 | HSMCI_CMDR_TRDIR_WRITE \
497 | HSMCI_CMDR_TRTYP_SINGLE \
498 | HSMCI_CMDR_MAXLAT)
500 // Get SCR
501 const char * sdAcmd51()
503 const char * result;
504 result = sdCmd55();
505 if (result)
506 return result;
508 Hsmci *phsmci = HSMCI ;
509 // Block size = 64/ 8, nblocks = 1
510 phsmci->HSMCI_BLKR = ( ( 64 / 8 ) << 16 ) | 1 ;
511 phsmci->HSMCI_ARGR = 0 ;
512 phsmci->HSMCI_CMDR = SD_SEND_SCR ;
514 uint8_t scrLen = 0;
515 uint32_t i;
516 for ( i = 0 ; i < 50000 ; i += 1 ) {
517 if ( phsmci->HSMCI_SR & HSMCI_SR_RXRDY )
518 Card_SCR[scrLen++] = __REV(phsmci->HSMCI_RDR) ;
519 if ( ( phsmci->HSMCI_SR & ( HSMCI_SR_CMDRDY | HSMCI_SR_XFRDONE ) ) == ( HSMCI_SR_CMDRDY | HSMCI_SR_XFRDONE ) )
520 return 0;
522 return "No response";
525 #define SD_SET_BUS_WIDTH (6 | HSMCI_CMDR_SPCMD_STD | HSMCI_CMDR_RSPTYP_48_BIT \
526 | HSMCI_CMDR_MAXLAT)
528 void sdEnableHsMode(uint8_t enable)
530 Hsmci *phsmci = HSMCI;
531 if (enable)
532 phsmci->HSMCI_CFG |= HSMCI_CFG_HSMODE;
533 else
534 phsmci->HSMCI_CFG &= ~HSMCI_CFG_HSMODE;
537 void sdSetBusWidth(uint32_t busWidth)
539 Hsmci *phsmci = HSMCI;
540 phsmci->HSMCI_SDCR = (HSMCI->HSMCI_SDCR & ~HSMCI_SDCR_SDCBUS_Msk) | busWidth;
543 // Set bus width to 4 bits, set speed to 9 MHz
544 const char * sdAcmd6()
546 const char * result;
547 result = sdCmd55() ;
548 if (result)
549 return result;
551 result = sdCommand(SD_SET_BUS_WIDTH, 2);
552 if (result)
553 return result;
555 sdSetBusWidth( HSMCI_SDCR_SDCBUS_4 ) ;
557 GetTransSpeedValue();
558 sdSetSpeed(transSpeed/*9000000*/);
560 // TODO + Cmd6? sdEnableHsMode(1);
562 if (Cmd_A41_resp & OCR_SD_CCS)
563 sdCmd16();
565 return 0;
568 #if 0
569 /** SDIO CMD52, R5 */
570 #define SDIO_IO_RW_DIRECT (52| HSMCI_CMDR_SPCMD_STD \
571 | HSMCI_CMDR_TRCMD_NO_DATA \
572 | HSMCI_CMDR_RSPTYP_48_BIT \
573 | HSMCI_CMDR_MAXLAT)
575 static const char * sdCmd52(uint8_t wrFlag,
576 uint8_t funcNb,
577 uint8_t rdAfterWr,
578 uint32_t addr,
579 uint32_t *status)
581 typedef struct
583 uint32_t data:8, /**< [ 7: 0] data for writing */
584 stuff0:1, /**< [ 8] reserved */
585 regAddress:17, /**< [25: 9] register address */
586 stuff1:1, /**< [ 26] reserved */
587 rawFlag:1, /**< [ 27] Read after Write flag */
588 functionNum:3, /**< [30:28] Number of the function */
589 rwFlag:1; /**< [ 31] Direction, 1:write, 0:read. */
590 } SdioCmd52Arg;
592 SdioCmd52Arg pArg52;
593 pArg52.rwFlag = wrFlag;
594 pArg52.functionNum = funcNb;
595 pArg52.rawFlag = rdAfterWr;
596 pArg52.regAddress = addr;
598 const char * result = sdCommand(SDIO_IO_RW_DIRECT, *(uint32_t*)&pArg52);
599 if (result)
600 return result;
601 *status = HSMCI->HSMCI_RSPR[0];
602 return 0;
605 const char * sdSwReset(uint32_t retry)
607 uint32_t i;
608 const char * result = 0;
610 for (i = 0; i < retry; i++) {
611 result = sdCmd0(0);
612 if (result != SD_NORESPONSE)
613 break;
615 return result;
617 #endif
620 * \brief Run the SD/MMC/SDIO Mode initialization sequence.
621 * This function runs the initialization procedure and the identification
622 * process. Then it leaves the card in ready state. The following procedure must
623 * check the card type and continue to put the card into tran(for memory card)
624 * or cmd(for io card) state for data exchange.
625 * \param pSd Pointer to a SD card driver instance.
626 * \return 0 if successful; otherwise returns an \ref sdmmc_rc "SD_ERROR code".
629 #define SDIO_CIA 0 /**< SDIO Function 0 (CIA) */
630 #define SDIO_IOA_REG 0x06 /**< I/O Abort */
632 /** SDIO state (in R5) */
633 #define SDIO_R5_ERROR (1UL << 11)/**< General error */
634 #define SDIO_R5_FUNC_NUM (1UL << 10)/**< Invalid function number */
635 #define SDIO_R5_OUT_OF_RANGE (1UL << 9) /**< Argument out of range */
637 /** Status bits mask for SDIO R5 */
638 #define STATUS_SDIO_R5 (0/*SDIO_R5_STATE*/ \
639 | SDIO_R5_ERROR \
640 | SDIO_R5_FUNC_NUM \
641 | SDIO_R5_OUT_OF_RANGE)
644 #define OCR_SDIO_MP (1UL << 27)
645 #define OCR_SDIO_NF (7UL << 28)
647 #if 0
648 const char * sdIdentify()
650 uint8_t mem = 0, io = 0, f8 = 0, mp = 1;
651 uint32_t status, ccs=0;
652 const char * result;
654 /* Reset HC to default HS and BusMode */
655 sdEnableHsMode(0);
656 sdSetBusWidth(HSMCI_SDCR_SDCBUS_1);
658 #if 0
659 /* Reset SDIO: CMD52, write 1 to RES bit in CCCR (bit 3 of register 6) */
660 result = sdCmd52(1, SDIO_CIA, 0, SDIO_IOA_REG, &status);
661 if (result)
662 return result;
663 if (status & STATUS_SDIO_R5)
664 return "Identify.52 error";
665 #endif
667 /* Reset MEM: CMD0 */
668 result = sdSwReset(1);
669 if (result)
670 return result;
672 /* CMD8 is newly added in the Physical Layer Specification Version 2.00 to
673 * support multiple voltage ranges and used to check whether the card
674 * supports supplied voltage. The version 2.00 host shall issue CMD8 and
675 * verify voltage before card initialization.
676 * The host that does not support CMD8 shall supply high voltage range... */
677 result = sdCmd8(1);
678 if (result == 0) f8 = 1;
679 else if (result == SD_NORESPONSE) CoTickDelay(1); /* 2ms delay after "no response" */
680 else return "Identify.8 error";
682 #if 0
683 /* CMD5 is newly added for SDIO initialize & power on */
684 status = 0;
685 result = sdCmd5(&status);
686 if (!result && (status & OCR_SDIO_NF) > 0) {
687 unsigned int cmd5Retries = 10000;
688 do {
689 status &= SDMMC_HOST_VOLTAGE_RANGE;
690 result = sdCmd5(&status);
691 if (status & OCR_POWER_UP_BUSY) break;
692 } while(!result && cmd5Retries --);
693 if (result)
694 return "Identify.5 error";
695 io = 1;
696 /* IO only ?*/
697 mp = ((status & OCR_SDIO_MP) > 0);
699 #endif
701 /* Has memory: SD/MMC/COMBO */
702 /*if (mp) */
704 /* Try SD memory initialize */
705 result = sdMemInit(f8, &ccs);
706 if (result) {
707 //unsigned int cmd1Retries = 10000;
708 /* Try MMC initialize */
709 result = sdSwReset(10);
710 if (result)
711 return "Reset error";
712 /* TODO ccs = 1;
713 do { result = sdCmd1(&ccs); } while(result && cmd1Retries -- > 0);
714 if (error) {
715 TRACE_ERROR("SdMmcIdentify.Cmd1: %u\n\r", error);
716 return SDMMC_ERROR;
718 else if (ccs) cardType = CARD_MMCHD;
719 else cardType = CARD_MMC;
721 return "TODO error";
722 /* MMC card identification OK */
723 return 0;
725 // mem = 1;
727 /* SD(IO) + MEM ? */
728 /* if (!mem) {
729 if (io) cardType = CARD_SDIO;
730 else
731 return "Unknown SD";
732 } */
733 /* SD(HC) combo */
734 /*else if (io)
735 cardType = ccs ? CARD_SDHCCOMBO : CARD_SDCOMBO;*/
736 /* SD(HC) */
737 //else
738 cardType = ccs ? CARD_SDHC : CARD_SD;
740 return 0;
743 const char * sdEnum()
745 uint8_t mem , io;
746 const char * result;
747 uint32_t ioSpeed = 0, memSpeed = 0;
748 uint8_t hsExec = 0, bwExec = 0;
750 /* - has Memory/IO/High-Capacity - */
751 mem = ((cardType & CARD_TYPE_bmSDMMC) > 0);
752 io = ((cardType & CARD_TYPE_bmSDIO) > 0);
754 /* For MEMORY cards:
755 * The host then issues the command ALL_SEND_CID (CMD2) to the card to get
756 * its unique card identification (CID) number.
757 * Card that is unidentified (i.e. which is in Ready State) sends its CID
758 * number as the response (on the CMD line). */
759 if (mem) {
760 result = sdCmd2();
761 if (result)
762 return result;
765 /* For MEMORY and SDIO cards:
766 * Thereafter, the host issues CMD3 (SEND_RELATIVE_ADDR) asks the
767 * card to publish a new relative card address (RCA), which is shorter than
768 * CID and which is used to address the card in the future data transfer
769 * mode. Once the RCA is received the card state changes to the Stand-by
770 * State. At this point, if the host wants to assign another RCA number, it
771 * can ask the card to publish a new number by sending another CMD3 command
772 * to the card. The last published RCA is the actual RCA number of the
773 * card. */
774 result = sdCmd3();
775 if (result)
776 return result;
778 /* For MEMORY cards:
779 * SEND_CSD (CMD9) to obtain the Card Specific Data (CSD register),
780 * e.g. block length, card storage capacity, etc... */
781 if (mem) {
782 result = sdCmd9();
783 if (result)
784 return result;
787 /* Now select the card, to TRAN state */
788 error = MmcSelectCard(pSd, pSd->cardAddress, 0);
789 if (error) {
790 TRACE_ERROR("SdMmcInit.SelCard(%d)\n\r", error);
791 return error;
794 /* - Now in TRAN, obtain extended setup information - */
796 /* If the card support EXT_CSD, read it! */
797 TRACE_INFO("Card Type %d, CSD_STRUCTURE %d\n\r",
798 pSd->cardType, SD_CSD_STRUCTURE(pSd));
800 /* Get extended information of the card */
801 SdMmcUpdateInformation(pSd, 0, 1);
803 /* Calculate transfer speed */
804 if (io) ioSpeed = SdioGetMaxSpeed(pSd);
805 if (mem) memSpeed = SdmmcGetMaxSpeed(pSd);
806 /* Combo, min speed */
807 if (io && mem) {
808 pSd->transSpeed = (ioSpeed > memSpeed) ? memSpeed : ioSpeed;
810 /* SDIO only */
811 else if (io) {
812 pSd->transSpeed = ioSpeed;
814 /* Memory card only */
815 else if (mem) {
816 pSd->transSpeed = memSpeed;
818 pSd->transSpeed *= 1000;
820 /* Enable more bus width Mode */
821 error = SdMmcDesideBuswidth(pSd);
822 if (!error) bwExec = 1;
823 else if (error != SDMMC_ERROR_NOT_SUPPORT) {
824 TRACE_ERROR("SdmmcEnum.DesideBusWidth: %u\n\r", error);
825 return SDMMC_ERROR;
828 /* Enable High-Speed Mode */
829 error = SdMmcEnableHighSpeed(pSd);
830 if (!error) hsExec = 1;
831 else if (error != SDMMC_ERROR_NOT_SUPPORT) {
832 TRACE_ERROR("SdmmcEnum.EnableHS: %u\n\r", error);
833 return SDMMC_ERROR;
836 /* In HS mode transfer speed *2 */
837 if (hsExec) pSd->transSpeed *= 2;
839 /* Update card information since status changed */
840 if (bwExec || hsExec) SdMmcUpdateInformation(pSd, hsExec, 1);
841 return 0;
844 void sdInit()
846 TRACE("sdInit");
848 const char * result;
849 uint8_t i;
851 /* Clear CID, CSD, EXT_CSD data */
852 for (i = 0; i < 4; i++) Card_ID[i] = 0;
853 for (i = 0; i < 4; i++) Card_CSD[i] = 0;
854 // TODO for (i = 0; i < 512/4; i++) pSd->extData[i] = 0;
856 /* Set low speed for device identification (LS device max speed) */
857 sdSetSpeed(400000);
859 /* Initialization delay: The maximum of 1 msec, 74 clock cycles and supply
860 * ramp up time. Supply ramp up time provides the time that the power is
861 * built up to the operating level (the bus master supply voltage) and the
862 * time to wait until the SD card can accept the first command.
865 /* Power On Init Special Command */
866 result = sdPowerOn();
867 if (result)
868 return;
870 /* After power-on or CMD0, all cards?
871 * CMD lines are in input mode, waiting for start bit of the next command.
872 * The cards are initialized with a default relative card address
873 * (RCA=0x0000) and with a default driver stage register setting
874 * (lowest speed, highest driving current capability).
876 result = sdIdentify();
877 if (result) {
878 return;
881 #if 0
882 result = sdEnum();
883 if (result) {
884 return;
887 /* In the case of a Standard Capacity SD Memory Card, this command sets the
888 * block length (in bytes) for all following block commands
889 * (read, write, lock).
890 * Default block length is fixed to 512 Bytes.
891 * Set length is valid for memory access commands only if partial block read
892 * operation are allowed in CSD.
893 * In the case of a High Capacity SD Memory Card, block length set by CMD16
894 * command does not affect the memory read and write commands. Always 512
895 * Bytes fixed block length is used. This command is effective for
896 * LOCK_UNLOCK command.
897 * In both cases, if block length is set larger than 512Bytes, the card sets
898 * the BLOCK_LEN_ERROR bit. */
899 if (pSd->cardType == CARD_SD) {
900 error = Cmd16(pSd, SDMMC_BLOCK_SIZE);
901 if (error) {
902 pSd->optCmdBitMap &= ~SD_CMD16_SUPPORT;
903 TRACE_INFO("SD_Init.Cmd16 (%d)\n\r", error);
904 TRACE_INFO("Fail to set BLK_LEN, default is 512\n\r");
908 /* Reset status for R/W */
909 pSd->state = SD_STATE_READY;
911 /* If MMC Card & get size from EXT_CSD */
912 if ((pSd->cardType & CARD_TYPE_bmSDMMC) == CARD_TYPE_bmMMC
913 && SD_CSD_C_SIZE(pSd) == 0xFFF) {
914 pSd->blockNr = SD_EXTCSD_BLOCKNR(pSd);
915 /* Block number less than 0x100000000/512 */
916 if (pSd->blockNr > 0x800000)
917 pSd->totalSize = 0xFFFFFFFF;
918 else
919 pSd->totalSize = SD_EXTCSD_TOTAL_SIZE(pSd);
921 /* If SD CSD v2.0 */
922 else if((pSd->cardType & CARD_TYPE_bmSDMMC) == CARD_TYPE_bmSD
923 && SD_CSD_STRUCTURE(pSd) >= 1) {
924 pSd->blockNr = SD_CSD_BLOCKNR_HC(pSd);
925 pSd->totalSize = 0xFFFFFFFF;
927 /* Normal SD/MMC card */
928 else if (pSd->cardType & CARD_TYPE_bmSDMMC) {
929 pSd->totalSize = SD_CSD_TOTAL_SIZE(pSd);
930 pSd->blockNr = SD_CSD_BLOCKNR(pSd);
933 if (pSd->cardType == CARD_UNKNOWN) {
934 return SDMMC_ERROR_NOT_INITIALIZED;
936 /* Automatically select the max clock */
937 clock = SdmmcSetSpeed(pSd, pSd->transSpeed);
938 TRACE_WARNING_WP("-I- Set SD/MMC clock to %dK\n\r", clock/1000);
939 pSd->accSpeed = clock;
940 #endif
942 #endif
944 uint8_t sdErrorCount = 0;
945 FATFS g_FATFS_Obj = { 0 };
947 void sdInit()
949 Sd_rca = 0;
950 sdErrorCount = 0;
952 if (!SD_CARD_PRESENT()) {
953 Card_state = SD_ST_EMPTY;
954 Card_initialized = 1;
955 return;
958 sdCmd0();
959 CoTickDelay(5); // 10ms
960 sdCmd8(1);
962 #if 0
963 uint8_t i;
964 uint32_t status;
965 for (i=0; i<100; i++)
966 sdCmd5(&status);
967 #endif
969 sdMemInit(1, &Cmd_A41_resp);
971 uint8_t retry;
972 for (retry=0; retry<10; retry++) {
973 if (!sdCmd2()) break;
974 CoTickDelay(1); // 2ms
977 if (retry == 10) {
978 Card_state = SD_ST_READY;
979 Card_initialized = 1;
980 return;
983 for (retry=0; retry<10; retry++) {
984 if (!sdCmd3()) break;
985 CoTickDelay(1); // 2ms
988 if (retry == 10) {
989 Card_state = SD_ST_IDENT;
990 Card_initialized = 1;
991 return;
994 sdCmd9();
995 sdCmd7(); // Select Card
997 sdAcmd51();
998 sdAcmd6(); // Set bus width to 4 bits, and speed to 9 MHz
1000 // Should check the card can do this ****
1001 Card_state = SD_ST_DATA;
1003 if (f_mount(&g_FATFS_Obj, "", 1) == FR_OK) {
1004 // call sdGetFreeSectors() now because f_getfree() takes a long time first time it's called
1005 sdGetFreeSectors();
1006 Card_state = SD_ST_MOUNTED;
1009 Card_initialized = 1;
1012 void sdDone()
1014 if (sdMounted()) {
1015 audioQueue.stopSD();
1016 f_mount(NULL, "", 0); // unmount SD
1020 // Checks for card ready for read/write
1021 // returns 1 for YES, 0 for NO
1022 uint32_t sd_card_ready( void )
1024 return SD_CARD_PRESENT() && Card_state >= SD_ST_DATA;
1027 uint32_t sdMounted( void )
1029 return SD_CARD_PRESENT() && Card_state == SD_ST_MOUNTED;
1032 uint32_t sd_read_block(uint32_t block_no, uint32_t *data)
1034 unsigned int status = 0;
1036 // TRACE_ERROR("read block %d", block_no);
1038 if (sd_card_ready()) {
1040 // Wait for card to be ready for data transfers
1041 do {
1042 sdCmd13(&status);
1044 while (((status & STATUS_READY_FOR_DATA) == 0)
1045 || ((status & STATUS_STATE) != STATUS_TRAN) );
1047 // Block size = 512, nblocks = 1
1048 HSMCI->HSMCI_BLKR = ((512) << 16) | 1;
1049 HSMCI->HSMCI_MR = (HSMCI->HSMCI_MR & (~(HSMCI_MR_BLKLEN_Msk|HSMCI_MR_FBYTE))) | (HSMCI_MR_PDCMODE|HSMCI_MR_WRPROOF|HSMCI_MR_RDPROOF) | (512 << 16);
1050 HSMCI->HSMCI_ARGR = (Cmd_A41_resp & OCR_SD_CCS ? block_no : (block_no << 9));
1051 HSMCI->HSMCI_RPR = (uint32_t)data;
1052 HSMCI->HSMCI_RCR = 512 / 4;
1053 HSMCI->HSMCI_PTCR = HSMCI_PTCR_RXTEN;
1054 HSMCI->HSMCI_CMDR = SD_READ_SINGLE_BLOCK;
1056 while (!(HSMCI->HSMCI_SR & HSMCI_SR_CMDRDY));
1058 (void) HSMCI->HSMCI_RSPR[0];
1060 while (1) {
1061 if ((HSMCI->HSMCI_SR & (HSMCI_SR_ENDRX|HSMCI_SR_XFRDONE)) == (HSMCI_SR_ENDRX|HSMCI_SR_XFRDONE)) {
1062 break;
1066 /* Disable PDC */
1067 HSMCI->HSMCI_MR &= ~(uint32_t)HSMCI_MR_PDCMODE;
1068 HSMCI->HSMCI_PTCR = HSMCI_PTCR_RXTDIS | HSMCI_PTCR_TXTDIS;
1070 return 1;
1073 // TRACE_ERROR("ok %.2X %.4Xd\n\r", HSMCI->HSMCI_SR, HSMCI->HSMCI_RSPR[0]);
1075 return 0;
1078 uint32_t sd_write_block( uint32_t block_no, uint32_t *data )
1080 unsigned int status = 0;
1082 if (sd_card_ready()) {
1084 // TRACE_ERROR("write block %d", block_no);
1086 // Wait for card to be ready for data transfers
1087 do {
1088 sdCmd13(&status);
1089 } while ((status & STATUS_READY_FOR_DATA) == 0);
1091 // Block size = 512, nblocks = 1
1092 HSMCI->HSMCI_BLKR = ((512) << 16) | 1;
1093 HSMCI->HSMCI_MR = (HSMCI->HSMCI_MR & (~(HSMCI_MR_BLKLEN_Msk|HSMCI_MR_FBYTE))) | (HSMCI_MR_PDCMODE|HSMCI_MR_WRPROOF) | (512 << 16);
1094 HSMCI->HSMCI_ARGR = (Cmd_A41_resp & OCR_SD_CCS ? block_no : (block_no << 9));
1095 HSMCI->HSMCI_TPR = (uint32_t)data;
1096 HSMCI->HSMCI_TCR = 512 / 4;
1097 HSMCI->HSMCI_CMDR = SD_WRITE_SINGLE_BLOCK;
1099 while (!(HSMCI->HSMCI_SR & HSMCI_SR_CMDRDY));
1101 (void) HSMCI->HSMCI_RSPR[0];
1103 HSMCI->HSMCI_PTCR = HSMCI_PTCR_TXTEN;
1105 while (1) {
1106 if ((HSMCI->HSMCI_SR & (HSMCI_SR_NOTBUSY|HSMCI_SR_XFRDONE)) == (HSMCI_SR_NOTBUSY|HSMCI_SR_XFRDONE)) {
1107 break;
1111 /* Disable PDC */
1112 HSMCI->HSMCI_PTCR = HSMCI_PTCR_RXTDIS | HSMCI_PTCR_TXTDIS;
1113 HSMCI->HSMCI_MR &= ~(uint32_t)HSMCI_MR_PDCMODE;
1115 return 1;
1118 return 0;
1122 Notes on SD card:
1124 1) CMD8 fails and CMD58 fails: must be MMC, thus initialize using CMD1
1125 2) CMD8 fails and CMD58 passes: must be Ver1.x Standard Capacity SD Memory Card
1126 3) CMD8 passes and CMD58 passes (CCS = 0): must be Ver2.00 or later Standard Capacity SD Memory Card
1127 4) CMD8 passes and CMD58 passes (CCS = 1): must be Ver2.00 or later High Capacity SD Memory Card
1128 5) CMD8 passes and CMD58 passes but indicates non compatible voltage range: unusable card
1130 On card present
1131 1. Send CMD 55 (resp 48bit)
1132 followed by ACMD41 (resp48bit)
1133 until bit 31 of response is '1'
1135 2. Send CMD 2 (resp 136bit) - card ID
1137 3. Send CMD 3 (resp 48 bit) - new RCA returned
1139 4. Send CMD 9 (resp 136) - CSD
1141 5. Send CMD 7 (resp 48) -
1143 6. Send CMD 55 (resp 48bit)
1144 followed by ACMD51 (resp48bit) - SCR stored as 2 32 bit values
1146 Now decide what the card can do!
1148 7. Set block length
1150 8. Set bus width
1152 9. Read block 0
1156 /*-----------------------------------------------------------------------*/
1157 /* Initialize Disk Drive */
1158 /*-----------------------------------------------------------------------*/
1160 DSTATUS disk_initialize (
1161 BYTE drv /* Physical drive nmuber (0) */
1164 if (drv) return STA_NOINIT; /* Supports only single drive */
1165 if ( sd_card_ready() == 0 ) return RES_NOTRDY;
1166 return RES_OK;
1169 /*-----------------------------------------------------------------------*/
1170 /* Get Disk Status */
1171 /*-----------------------------------------------------------------------*/
1173 DSTATUS disk_status (
1174 BYTE drv /* Physical drive number (0) */
1177 if (drv) return STA_NOINIT; /* Supports only single drive */
1178 if ( sd_card_ready() == 0 ) return RES_NOTRDY;
1179 return RES_OK;
1182 /*-----------------------------------------------------------------------*/
1183 /* Read Sector(s) */
1184 /*-----------------------------------------------------------------------*/
1186 uint32_t dma_sd_buffer[512/4];
1188 DRESULT disk_read (
1189 BYTE drv, /* Physical drive nmuber (0) */
1190 BYTE *buff, /* Pointer to the data buffer to store read data */
1191 DWORD sector, /* Start sector number (LBA) */
1192 UINT count /* Sector count (1..255) */
1195 uint32_t result ;
1197 if (drv || !count) return RES_PARERR;
1199 if ( sd_card_ready() == 0 ) return RES_NOTRDY;
1201 do {
1202 result = sd_read_block(sector, dma_sd_buffer) ;
1203 if (result) {
1204 memcpy(buff, dma_sd_buffer, 512);
1205 sector += 1 ;
1206 buff += 512 ;
1207 count -= 1 ;
1209 else {
1210 count = 1 ; // Flag error
1211 break ;
1213 } while ( count ) ;
1215 if (!count)
1216 return RES_OK;
1218 if (++sdErrorCount > 3)
1219 Card_state = SD_ST_ERR;
1221 return RES_ERROR;
1225 /*-----------------------------------------------------------------------*/
1226 /* Write Sector(s) */
1227 /*-----------------------------------------------------------------------*/
1229 extern const char * warningText;
1231 DRESULT disk_write (
1232 BYTE drv, /* Physical drive nmuber (0) */
1233 const BYTE *buff, /* Pointer to the data to be written */
1234 DWORD sector, /* Start sector number (LBA) */
1235 UINT count /* Sector count (1..255) */
1238 uint32_t result ;
1240 if (drv || !count) return RES_PARERR;
1242 if ( sd_card_ready() == 0 ) return RES_NOTRDY;
1244 do {
1246 while (1) {
1248 memcpy(dma_sd_buffer, buff, 512);
1250 result = sd_write_block(sector, dma_sd_buffer) ;
1252 sd_read_block(sector, dma_sd_buffer) ;
1254 if (!memcmp(dma_sd_buffer, buff, 512))
1255 break;
1256 else {
1257 TRACE_ERROR("Block %d ko SR=%.2X\r\n", sector, HSMCI->HSMCI_SR);
1258 // DUMP(buff, 512);
1259 // DUMP(copy, 512);
1263 if (result) {
1264 sector += 1 ;
1265 buff += 512 ;
1266 count -= 1 ;
1268 else {
1269 count = 1 ; // Flag error
1270 break ;
1272 } while ( count ) ;
1274 if (!count) {
1275 return RES_OK;
1278 if (++sdErrorCount > 3)
1279 Card_state = SD_ST_ERR;
1281 return RES_ERROR;
1286 /*-----------------------------------------------------------------------*/
1287 /* Miscellaneous Functions */
1288 /*-----------------------------------------------------------------------*/
1290 DRESULT disk_ioctl (
1291 BYTE drv, /* Physical drive nmuber (0) */
1292 BYTE ctrl, /* Control code */
1293 void *buff /* Buffer to send/receive control data */
1296 DRESULT res;
1298 if (drv) return RES_PARERR;
1300 res = RES_ERROR;
1302 if (ctrl == CTRL_POWER) {
1303 #if 0
1304 switch (ptr[0]) {
1305 case 0: /* Sub control code (POWER_OFF) */
1306 power_off(); /* Power off */
1307 res = RES_OK;
1308 break;
1309 case 1: /* Sub control code (POWER_GET) */
1310 ptr[1] = (BYTE)power_status();
1311 res = RES_OK;
1312 break;
1313 default :
1314 res = RES_PARERR;
1316 #endif
1318 else {
1319 switch (ctrl) {
1320 case CTRL_SYNC : /* Make sure that no pending write process. Do not remove this or written sector might not left updated. */
1321 res = RES_OK;
1322 break;
1324 case GET_SECTOR_COUNT : /* Get number of sectors on the disk (DWORD) */
1325 *(DWORD*)buff = SD_GET_BLOCKNR();
1326 res = RES_OK;
1327 break;
1329 case GET_SECTOR_SIZE : /* Get R/W sector size (WORD) */
1330 *(WORD*)buff = 512;
1331 res = RES_OK;
1332 break;
1334 case GET_BLOCK_SIZE : /* Get erase block size in unit of sector (DWORD) */
1335 *(WORD*)buff = 1;
1336 res = RES_OK;
1337 break;
1339 #if 0
1340 case MMC_GET_TYPE : /* Get card type flags (1 byte) */
1341 *ptr = CardType;
1342 res = RES_OK;
1343 break;
1345 case MMC_GET_CSD : /* Receive CSD as a data block (16 bytes) */
1346 if (send_cmd(CMD9, 0) == 0 /* READ_CSD */
1347 && rcvr_datablock(ptr, 16))
1348 res = RES_OK;
1349 break;
1351 case MMC_GET_CID : /* Receive CID as a data block (16 bytes) */
1352 if (send_cmd(CMD10, 0) == 0 /* READ_CID */
1353 && rcvr_datablock(ptr, 16))
1354 res = RES_OK;
1355 break;
1357 case MMC_GET_OCR : /* Receive OCR as an R3 resp (4 bytes) */
1358 if (send_cmd(CMD58, 0) == 0) { /* READ_OCR */
1359 for (n = 4; n; n--) *ptr++ = rcvr_spi();
1360 res = RES_OK;
1362 break;
1364 case MMC_GET_SDSTAT : /* Receive SD statsu as a data block (64 bytes) */
1365 if (send_cmd(ACMD13, 0) == 0) { /* SD_STATUS */
1366 rcvr_spi();
1367 if (rcvr_datablock(ptr, 64))
1368 res = RES_OK;
1370 break;
1371 #endif
1372 default:
1373 res = RES_PARERR;
1374 break;
1376 // BSS deselect();
1379 return res;