DSTATUS disk_initialize (void)
{
BYTE SDHC = 0;
BYTE ocr[4] = {0,0,0,0};
BYTE ty,cmd;
WORD tmr;
WORD r,i,x;
tmr = 10000;
r = 0;
init_spi();
// 1. with the card NOT selected
DESELECT();
// 2. send 80 clock cycles start up
for ( i=0; i<10; i++)
writeSPI(0xFF);
// 3. now select the card
SELECT();
// 4. send a single RESET command
r = send_cmd(CMD0, 0);
//DESELECT();
if ( r != 1) // must return Idle
return 1; // comand rejected
// 5. send repeatedly INIT until Idle terminates
if (send_cmd(CMD8, 0x1AA) == 1) { /* SDC ver 2.00 */
SDHC = 1;
i = 0;
for (x = 0; x < 4; x++) ocr[x] = rcv_spi();
if (ocr[2] == 0x01 && ocr[3] == 0xAA) { /* The card can work at vdd range of 2.7-3.6V */
while (send_cmd(ACMD41, 1UL << 30)){ /* ACMD41 with HCS bit */
i++;
if(i==tmr) break;
}
if (send_cmd(CMD58, 0) == 0) { /* Check CCS bit */
for (x = 0; x < 4; x++) ocr[x] = rcv_spi();
ty = (ocr[0] & 0x40) ? CT_SD2|CT_BLOCK : CT_SD2; /* SDv2 */
}
}
}else{
if (send_cmd(ACMD41, 0) <= 1) {
ty = CT_SD1;
cmd = ACMD41; /* SDv1 */
} else {
ty = CT_MMC;
cmd = CMD1; /* MMCv3 */
}
for (i=0; i<tmr; i++){
r = send_cmd(cmd, 0); DESELECT();
if ( !r)
break;
}
if ( i == tmr)
return 2; // init timed out
for (i=0; i<tmr; i++){
r = send_cmd(CMD16, 512); DESELECT();
if ( r)
break;
}
if ( i == tmr)
return 2; // init timed out
}
return r;
}