DSTATUS disk_initialize (void) { BYTE n, cmd, ty, ocr[4]; UINT tmr; #if _PF_USE_WRITE if (CardType && MMC_SEL) disk_writep(0, 0); /* Finalize write process if it is in progress */ #endif init_spi(); /* Initialize ports to control MMC */ DESELECT(); for (n = 100; n; n--) rcv_spi(); /* 80*10 dummy clocks with CS=H */ ty = 0; if (send_cmd(CMD0, 0) == 1) { /* Enter Idle state */ if (send_cmd(CMD8, 0x1AA) == 1) { /* SDv2 */ for (n = 0; n < 4; n++) ocr[n] = rcv_spi(); /* Get trailing return value of R7 resp */ if (ocr[2] == 0x01 && ocr[3] == 0xAA) { /* The card can work at vdd range of 2.7-3.6V */ for (tmr = 10000; tmr && send_cmd(ACMD41, 1UL << 30); tmr--) dly_100us(); /* Wait for leaving idle state (ACMD41 with HCS bit) */ if (tmr && send_cmd(CMD58, 0) == 0) { /* Check CCS bit in the OCR */ for (n = 0; n < 4; n++) ocr[n] = rcv_spi(); ty = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2; /* SDv2 (HC or SC) */ } } } else { /* SDv1 or MMCv3 */ if (send_cmd(ACMD41, 0) <= 1) { ty = CT_SD1; cmd = ACMD41; /* SDv1 */ } else { ty = CT_MMC; cmd = CMD1; /* MMCv3 */ } for (tmr = 10000; tmr && send_cmd(cmd, 0); tmr--) dly_100us(); /* Wait for leaving idle state */ if (!tmr || send_cmd(CMD16, 512) != 0) /* Set R/W block length to 512 */ ty = 0; } } CardType = ty; DESELECT(); rcv_spi(); //full speed SPI SPCR = (1<<MSTR)|(1<<SPE); SPSR = 0x01; /* SPI clk 2X */ return ty ? 0 : STA_NOINIT; }
DSTATUS disk_initialize (void) { BYTE n, cmd, ty, ocr[4]; UINT tmr; init_spi(); /* Initialize ports to control MMC */ for (n = 100; n; n--) dly_100us(); /* 10ms delay */ for (n = 10; n; n--) deselect(); /* 80 Dummy clocks with CS=H */ ty = 0; if (send_cmd(CMD0, 0) == 1) { /* Enter Idle state */ if (send_cmd(CMD8, 0x1AA) == 1) { /* SDv2 */ for (n = 0; n < 4; n++) ocr[n] = rcv_spi(); /* Get trailing return value of R7 resp */ if (ocr[2] == 0x01 && ocr[3] == 0xAA) { /* The card can work at vdd range of 2.7-3.6V */ for (tmr = 10000; tmr && send_cmd(ACMD41, 1UL << 30); tmr--) dly_100us(); /* Wait for leaving idle state (ACMD41 with HCS bit) */ if (tmr && send_cmd(CMD58, 0) == 0) { /* Check CCS bit in the OCR */ for (n = 0; n < 4; n++) ocr[n] = rcv_spi(); ty = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2; /* SDv2 (HC or SC) */ } } } else { /* SDv1 or MMCv3 */ if (send_cmd(ACMD41, 0) <= 1) { ty = CT_SD1; cmd = ACMD41; /* SDv1 */ } else { ty = CT_MMC; cmd = CMD1; /* MMCv3 */ } for (tmr = 10000; tmr && send_cmd(cmd, 0); tmr--) dly_100us(); /* Wait for leaving idle state */ if (!tmr || send_cmd(CMD16, 512) != 0) /* Set R/W block length to 512 */ ty = 0; } } CardType = ty; deselect(); return ty ? 0 : STA_NOINIT; }
DRESULT disk_writep ( const BYTE *buff, /* Pointer to the bytes to be written (NULL:Initiate/Finalize sector write) */ DWORD sa /* Number of bytes to send, Sector number (LBA) or zero */ ) { // BYTE buf; DRESULT res; WORD bc; static WORD wc; res = RES_ERROR; if (buff) { /* Send data bytes */ bc = (WORD)sa; while (bc && wc) { /* Send data bytes to the card */ xmit_spi(*buff++); wc--; bc--; } res = RES_OK; } else { if (sa) { /* Initiate sector write process */ if (!(CardType & CT_BLOCK)) sa *= 512; /* Convert to byte address if needed */ if (send_cmd(CMD24, sa) == 0) { /* WRITE_SINGLE_BLOCK */ xmit_spi(0xFF); xmit_spi(0xFE); /* Data block header */ wc = 512; /* Set byte counter */ res = RES_OK; } } else { /* Finalize sector write process */ bc = wc + 2; while (bc--) xmit_spi(0); /* Fill left bytes and CRC with zeros */ if ((rcv_spi() & 0x1F) == 0x05) { /* Receive data resp and wait for end of write process in timeout of 500ms */ // for (bc = 5000; buf!= 0xFF && bc; bc--){ // dly_100us(); /* Wait ready */ // buf=rcv_spi() ; // } for (bc = 5000; rcv_spi() != 0xFF && bc; bc--) dly_100us(); /* Wait ready */ if (bc) res = RES_OK; } DESELECT(); rcv_spi(); } } return res; }