Follow along with the video below to see how to install our site as a web app on your home screen.
Note: This feature may not be available in some browsers.
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;
}
static
DSTATUS MM_disk_initialize (void)
{
BYTE n, ty, cmd, ocr[4];
if (Stat[1] & STA_NODISK) /* No card in the socket */
return Stat[1];
MM_power_on(); /* Force socket power ON */
FCLK_SLOW();
for (n = 10; n; n--) MM_rcvr_spi(); /* 80 dummy clocks */
ty = 0;
if (MM_send_cmd(CMD0, 0) == 1) { /* Enter Idle state */
Timer1 = 100; /* Initialization timeout of 1000 msec */
if (MM_send_cmd(CMD8, 0x1AA) == 1) { /* SDC ver 2.00 */
for (n = 0; n < 4; n++) ocr[n] = MM_rcvr_spi();
if (ocr[2] == 0x01 && ocr[3] == 0xAA) { /* The card can work at vdd range of 2.7-3.6V */
while (Timer1 && MM_send_cmd(ACMD41, 1UL << 30)); /* ACMD41 with HCS bit */
if (Timer1 && MM_send_cmd(CMD58, 0) == 0) { /* Check CCS bit */
for (n = 0; n < 4; n++) ocr[n] = MM_rcvr_spi();
ty = (ocr[0] & 0x40) ? CT_SD2|CT_BLOCK : CT_SD2; /* SDv2 */
}
}
} else { /* SDv1 or MMCv3 */
if (MM_send_cmd(ACMD41, 0) <= 1) {
ty = CT_SD1; cmd = ACMD41; /* SDv1 */
} else {
ty = CT_MMC; cmd = CMD1; /* MMCv3 */
}
while (Timer1 && MM_send_cmd(cmd, 0)); /* Wait for leaving idle state */
if (!Timer1 || MM_send_cmd(CMD16, 512) != 0) /* Select R/W block length */
ty = 0;
}
}
CardType = ty;
MM_release_spi();
if (ty) { /* Initialization succeded */
Stat[1] &= ~STA_NOINIT; /* Clear STA_NOINIT */
FCLK_FAST();
} else { /* Initialization failed */
MM_power_off();
}
return Stat[1];
}
for (n = 10; n; n--) rcvr_spi(); /* 80 dummy clocks */
ty = 0;
if (send_cmd(CMD0, 0) == 1) { /* Enter Idle state */
Timer1 = 100; /* Initialization timeout of 1000 msec */
if (send_cmd(CMD8, 0x1AA) == 1) { /* SDHC */
for (n = 0; n < 4; n++) ocr[n] = rcvr_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 */
while (Timer1-- && send_cmd(ACMD41, 1UL << 30)); /* Wait for leaving idle state (ACMD41 with HCS bit) */
if (Timer1 && send_cmd(CMD58, 0) == 0) { /* Check CCS bit in the OCR */
for (n = 0; n < 4; n++) ocr[n] = rcvr_spi();
ty = (ocr[0] & 0x40) ? 12 : 4;
}
}
} else { /* SDSC or MMC */
if (send_cmd(ACMD41, 0) <= 1) {
ty = 2; cmd = ACMD41; /* SDSC */
} else {
ty = 1; cmd = CMD1; /* MMC */
}
while (Timer1-- && send_cmd(cmd, 0)); /* Wait for leaving idle state */
if (!Timer1 || send_cmd(CMD16, 512) != 0) /* Set R/W block length to 512 */
ty = 0;
}
}
CardType = ty;
release_spi();
FRESULT pf_mount (
FATFS *fs /* Pointer to new file system object (NULL: Unmount) */
)
{
BYTE fmt, buf[36];
DWORD bsect, fsize, tsect, mclst;
BYTE res;
FatFs = 0;
if (!fs) return FR_OK; /* Unregister fs object */
res = disk_initialize();
if (res & STA_NOINIT) /* Check if the drive is ready or not */
return FR_NOT_READY;
/* Search FAT partition on the drive */
bsect = 0;
fmt = check_fs(buf, bsect); /* Check sector 0 as an SFD format */
if (fmt == 1) { /* Not an FAT boot record, it may be FDISK format */
/* Check a partition listed in top of the partition table */
if (disk_readp(buf, bsect, MBR_Table, 16)) { /* 1st partition entry */
fmt = 3;
} else {
if (buf[4]) { /* Is the partition existing? */
bsect = LD_DWORD(&buf[8]); /* Partition offset in LBA */
fmt = check_fs(buf, bsect); /* Check the partition */
}
}
}
if (fmt == 3) return FR_DISK_ERR;
[B][COLOR="Red"] if (fmt) return FR_NO_FILESYSTEM; /* No valid FAT patition is found */[/COLOR][/B]
/* Initialize the file system object */
if (disk_readp(buf, bsect, 13, sizeof(buf))) return FR_DISK_ERR;
fsize = LD_WORD(buf+BPB_FATSz16-13); /* Number of sectors per FAT */
if (!fsize) fsize = LD_DWORD(buf+BPB_FATSz32-13);
fsize *= buf[BPB_NumFATs-13]; /* Number of sectors in FAT area */
fs->fatbase = bsect + LD_WORD(buf+BPB_RsvdSecCnt-13); /* FAT start sector (lba) */
fs->csize = buf[BPB_SecPerClus-13]; /* Number of sectors per cluster */
fs->n_rootdir = LD_WORD(buf+BPB_RootEntCnt-13); /* Nmuber of root directory entries */
tsect = LD_WORD(buf+BPB_TotSec16-13); /* Number of sectors on the file system */
if (!tsect) tsect = LD_DWORD(buf+BPB_TotSec32-13);
mclst = (tsect /* Last cluster# + 1 */
- LD_WORD(buf+BPB_RsvdSecCnt-13) - fsize - fs->n_rootdir / 16
) / fs->csize + 2;
fs->max_clust = (CLUST)mclst;
fmt = FS_FAT12; /* Determine the FAT sub type */
if (mclst >= 0xFF7) fmt = FS_FAT16; /* Number of clusters >= 0xFF5 */
if (mclst >= 0xFFF7) /* Number of clusters >= 0xFFF5 */
#if _FS_FAT32
fmt = FS_FAT32;
#else
return FR_NO_FILESYSTEM;
#endif
fs->fs_type = fmt; /* FAT sub-type */
#if _FS_FAT32
if (fmt == FS_FAT32)
fs->dirbase = LD_DWORD(buf+(BPB_RootClus-13)); /* Root directory start cluster */
else
#endif
fs->dirbase = fs->fatbase + fsize; /* Root directory start sector (lba) */
fs->database = fs->fatbase + fsize + fs->n_rootdir / 16; /* Data start sector (lba) */
fs->flag = 0;
FatFs = fs;
return FR_OK;
}
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;
ty = 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
for (i=0; i<tmr; i++){
r = send_cmd(ACMD41, 1UL << 30);
DESELECT();
if (!r)
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
}
[B][COLOR="Red"] CardType = ty;[/COLOR][/B]
return r;
}
if (!(CardType & CT_BLOCK)) lba *= 512; // Convert to byte address if needed