📄 sdc_diskio.c
字号:
if (Stat & STA_NODISK) return Stat; /* No card in the socket */
MMC_SPI_Config();
MMC_POWERON(); /* Force socket power on */
for(Timer1=50; Timer1; );
SPI_LowSpeed();
MMC_DESELECT();
/* Wait for enter Idle state in timeout of 5000 msec */
Timer1 = 500;
do{
for (n = 10; n; n--) SPI_ReadWrite_Byte(0xff); /* 80 dummy clocks */
}
while((Send_Command(CMD0,0) != 1) && Timer1);
ty = 0;
Timer1 = 200; /* Initialization timeout of 2000 msec */
if (Send_Command(CMD8, 0x1AA) == 1) { /* 检查是否支持SDC Ver2 */
for (n = 0; n < 4; n++)
ocr[n] = SPI_ReadWrite_Byte(0xff); /* 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 */
/* Wait for leaving idle state (ACMD41 with HCS bit) */
while (Timer1 && Send_Command(ACMD41, 1UL << 30));
if (Timer1 && Send_Command(CMD58, 0) == 0) {
/* Check CCS bit in the OCR */
for (n = 0; n < 4; n++)
ocr[n] = SPI_ReadWrite_Byte(0xff);
/* When CCS bit is set R/W in block address insted of byte address */
ty = (ocr[0] & 0x40) ? 12 : 4;
}
}
} else {
/* SDSC or MMC */
if (Send_Command(ACMD41, 0) <= 1) { /* initialize successful will response 0x00 */
ty = 2; cmd = ACMD41; /* SDv1 */
} else {
ty = 1; cmd = CMD1; /* MMC */
}
while (Timer1 && Send_Command(cmd, 0)); /* Wait for leaving idle state */
if (!Timer1 || Send_Command(CMD16, 512) != 0) /* Set R/W block length to 512 */
ty = 0;
}
CardType = ty;
SPI_HighSpeed();
SPI_Release();
if (ty) {
/* Initialization succeded */
Stat &= ~STA_NOINIT;
USART1_Puts("Initialization succeded.\n");
} else {
/* Initialization failed */
MMC_POWEROFF();
USART1_Puts("Initialization failed.\n");
}
return Stat;
}
/*-----------------------------------------------------------------------*/
/* Get Disk Status */
/*-----------------------------------------------------------------------*/
DSTATUS disk_status (
BYTE drv /* Physical drive nmuber (0) */
)
{
if (drv) return STA_NOINIT; /* Supports only single drive */
return Stat;
}
/*-----------------------------------------------------------------------*/
/* Read Sector(s) */
/*-----------------------------------------------------------------------*/
DRESULT disk_read (
BYTE drv, /* Physical drive nmuber (0) */
BYTE *buff, /* Pointer to the data buffer to store read data */
DWORD sector, /* Start sector number (LBA) */
BYTE count /* Sector count (1..255) */
)
{
if (drv || !count) return RES_PARERR;
if (Stat & STA_NOINIT) return RES_NOTRDY;
if (!(CardType & 8)) sector *= 512; /* Convert to byte address if needed */
if (count == 1) { /* Single block read */
if ((Send_Command(CMD17, sector) == 0) /* READ_SINGLE_BLOCK */
&& Receive_DataBlock(buff, 512))
count = 0;
}
else { /* Multiple block read */
if (Send_Command(CMD18, sector) == 0) { /* READ_MULTIPLE_BLOCK */
do {
if (!Receive_DataBlock(buff, 512)) break;
buff += 512;
} while (--count);
Send_Command(CMD12, 0); /* STOP_TRANSMISSION */
}
}
SPI_Release();
return count ? RES_ERROR : RES_OK;
}
/*-----------------------------------------------------------------------*/
/* Write Sector(s) */
/*-----------------------------------------------------------------------*/
#if _READONLY == 0
DRESULT disk_write (
BYTE drv, /* Physical drive nmuber (0) */
const BYTE *buff, /* Pointer to the data to be written */
DWORD sector, /* Start sector number (LBA) */
BYTE count /* Sector count (1..255) */
)
{
if (drv || !count) return RES_PARERR;
if (Stat & STA_NOINIT) return RES_NOTRDY;
if (Stat & STA_PROTECT) return RES_WRPRT;
if (!(CardType & 8)) sector *= 512; /* Convert to byte address if needed */
if (count == 1) { /* Single block write */
if ((Send_Command(CMD24, sector) == 0) /* WRITE_BLOCK */
&& Transmit_DataBlock(buff, 0xFE))
count = 0;
}
else { /* Multiple block write */
if (CardType & 6) Send_Command(ACMD23, count);
if (Send_Command(CMD25, sector) == 0) { /* WRITE_MULTIPLE_BLOCK */
do {
if (!Transmit_DataBlock(buff, 0xFC)) break;
buff += 512;
} while (--count);
if (!Transmit_DataBlock(0, 0xFD)) /* STOP_TRAN token */
count = 1; /* faild */
}
}
SPI_Release();
return count ? RES_ERROR : RES_OK;
}
#endif /* _READONLY == 0 */
/*-----------------------------------------------------------------------*/
/* Miscellaneous Functions */
/*-----------------------------------------------------------------------*/
#if _USE_IOCTL != 0
DRESULT disk_ioctl (
BYTE drv, /* Physical drive nmuber (0) */
BYTE ctrl, /* Control code */
void *buff /* Buffer to send/receive control data */
)
{
DRESULT res;
BYTE n, csd[16], *ptr = buff;
WORD csize;
if (drv) return RES_PARERR;
res = RES_ERROR;
if (ctrl == CTRL_POWER) {
switch (*ptr) {
case 0: /* Sub control code == 0 (POWER_OFF) */
if (chk_power())
MMC_POWEROFF(); /* Power off */
res = RES_OK;
break;
case 1: /* Sub control code == 1 (POWER_ON) */
MMC_POWERON(); /* Power on */
res = RES_OK;
break;
case 2: /* Sub control code == 2 (POWER_GET) */
*(ptr+1) = (BYTE)chk_power();
res = RES_OK;
break;
default :
res = RES_PARERR;
}
}
else {
if (Stat & STA_NOINIT) return RES_NOTRDY;
switch (ctrl) {
case CTRL_SYNC : /* Make sure that no pending write process */
MMC_SELECT();
if (Wait_Ready() == 0xFF)
res = RES_OK;
break;
case GET_SECTOR_COUNT : /* Get number of sectors on the disk (DWORD) */
if ((Send_Command(CMD9, 0) == 0) && Receive_DataBlock(csd, 16)) {
if ((csd[0] >> 6) == 1) { /* SDC ver 2.00 */
csize = csd[9] + ((WORD)csd[8] << 8) + 1;
*(DWORD*)buff = (DWORD)csize << 10;
} else { /* SDC ver 1.XX or MMC*/
n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2;
csize = (csd[8] >> 6) + ((WORD)csd[7] << 2) + ((WORD)(csd[6] & 3) << 10) + 1;
*(DWORD*)buff = (DWORD)csize << (n - 9);
}
res = RES_OK;
}
break;
case GET_SECTOR_SIZE : /* Get R/W sector size (WORD) */
*(WORD*)buff = 512;
res = RES_OK;
break;
case GET_BLOCK_SIZE : /* Get erase block size in unit of sector (DWORD) */
if (CardType & 4) { /* SDC ver 2.00 */
if (Send_Command(ACMD13, 0) == 0) { /* Read SD status */
SPI_ReadWrite_Byte(0xff);
if (Receive_DataBlock(csd, 16)) { /* Read partial block */
for (n = 64 - 16; n; n--) SPI_ReadWrite_Byte(0xff); /* Purge trailing data */
*(DWORD*)buff = 16UL << (csd[10] >> 4);
res = RES_OK;
}
}
} else { /* SDC ver 1.XX or MMC */
if ((Send_Command(CMD9, 0) == 0) && Receive_DataBlock(csd, 16)) { /* Read CSD */
if (CardType & 2) { /* SDC ver 1.XX */
*(DWORD*)buff = (((csd[10] & 63) << 1) + ((WORD)(csd[11] & 128) >> 7) + 1) << ((csd[13] >> 6) - 1);
} else { /* MMC */
*(DWORD*)buff = ((WORD)((csd[10] & 124) >> 2) + 1) * (((csd[11] & 3) << 3) + ((csd[11] & 224) >> 5) + 1);
}
res = RES_OK;
}
}
break;
case MMC_GET_TYPE : /* Get card type flags (1 byte) */
*ptr = CardType;
res = RES_OK;
break;
case MMC_GET_CSD : /* Receive CSD as a data block (16 bytes) */
if (Send_Command(CMD9, 0) == 0 /* READ_CSD */
&& Receive_DataBlock(ptr, 16))
res = RES_OK;
break;
case MMC_GET_CID : /* Receive CID as a data block (16 bytes) */
if (Send_Command(CMD10, 0) == 0 /* READ_CID */
&& Receive_DataBlock(ptr, 16))
res = RES_OK;
break;
case MMC_GET_OCR : /* Receive OCR as an R3 resp (4 bytes) */
if (Send_Command(CMD58, 0) == 0) { /* READ_OCR */
for (n = 4; n; n--) *ptr++ = SPI_ReadWrite_Byte(0xff);
res = RES_OK;
}
break;
case MMC_GET_SDSTAT : /* Receive SD statsu as a data block (64 bytes) */
if (Send_Command(ACMD13, 0) == 0) { /* SD_STATUS */
SPI_ReadWrite_Byte(0xff);
if (Receive_DataBlock(ptr, 64))
res = RES_OK;
}
break;
default:
res = RES_PARERR;
}
}
SPI_Release();
return res;
}
#endif /* _USE_IOCTL != 0 */
DWORD get_fattime (void)
{
return 0;
}
/*-----------------------------------------------------------------------*/
/* Device Timer Interrupt Procedure (Platform dependent) */
/*-----------------------------------------------------------------------*/
/* This function must be called in period of 10ms */
/*
void disk_timerproc (void)
{
static BYTE pv;
BYTE n, s;
n = Timer1; // 100Hz decrement timer
if (n) Timer1 = --n;
n = Timer2;
if (n) Timer2 = --n;
n = pv;
pv = SOCKPORT & (SOCKWP | SOCKINS); // Sample socket switch
if (n == pv) { // Have contacts stabled?
s = Stat;
if (pv & SOCKWP) // WP is H (write protected)
s |= STA_PROTECT;
else // WP is L (write enabled)
s &= ~STA_PROTECT;
if (pv & SOCKINS) // INS = H (Socket empty)
s |= (STA_NODISK | STA_NOINIT);
else // INS = L (Card inserted)
s &= ~STA_NODISK;
Stat = s;
}
}
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -