|
|
|
@ -80,7 +80,7 @@ extern unsigned long xtimer_now(void);
|
|
|
|
|
|
|
|
|
|
---------------------------------------------------------------------------*/ |
|
|
|
|
|
|
|
|
|
static volatile DSTATUS Stat = STA_NOINIT; /* Disk status */ |
|
|
|
|
static volatile diskio_sta_t Stat = DISKIO_STA_NOINIT; /* Disk status */ |
|
|
|
|
|
|
|
|
|
static unsigned short CardRCA; /* Assigned RCA */ |
|
|
|
|
static unsigned char CardType, /* Card type flag */ |
|
|
|
@ -363,7 +363,7 @@ static void power_off(void)
|
|
|
|
|
PINSEL4 &= ~((BIT22 | BIT23) | (BIT24 | BIT25) | (BIT26 | BIT27)); |
|
|
|
|
// Pins should be now configured as standard input (see board_init.c if you accidentally reconfigured them)
|
|
|
|
|
|
|
|
|
|
Stat |= STA_NOINIT; |
|
|
|
|
Stat |= DISKIO_STA_NOINIT; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -523,13 +523,13 @@ static void bswap_cp(unsigned char *dst, const unsigned long *src)
|
|
|
|
|
/*-----------------------------------------------------------------------*/ |
|
|
|
|
/* Initialize Disk Drive */ |
|
|
|
|
/*-----------------------------------------------------------------------*/ |
|
|
|
|
DSTATUS MCI_initialize(void) |
|
|
|
|
diskio_sta_t mci_initialize(void) |
|
|
|
|
{ |
|
|
|
|
unsigned int cmd, n; |
|
|
|
|
unsigned long resp[4]; |
|
|
|
|
unsigned char ty; |
|
|
|
|
|
|
|
|
|
if (Stat & STA_NODISK) { |
|
|
|
|
if (Stat & DISKIO_STA_NODISK) { |
|
|
|
|
return Stat; /* No card in the socket */ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -666,12 +666,12 @@ DSTATUS MCI_initialize(void)
|
|
|
|
|
|
|
|
|
|
MCI_CLOCK = (MCI_CLOCK & 0xF00) | 0x200 | (PCLK / MCLK_RW / 2 - 1); /* Set MCICLK = MCLK_RW, power-save mode */ |
|
|
|
|
|
|
|
|
|
Stat &= ~STA_NOINIT; /* Clear STA_NOINIT */ |
|
|
|
|
Stat &= ~DISKIO_STA_NOINIT; /* Clear DISKIO_STA_NOINIT */ |
|
|
|
|
return Stat; |
|
|
|
|
|
|
|
|
|
di_fail: |
|
|
|
|
power_off(); |
|
|
|
|
Stat |= STA_NOINIT; /* Set STA_NOINIT */ |
|
|
|
|
Stat |= DISKIO_STA_NOINIT; /* Set DISKIO_STA_NOINIT */ |
|
|
|
|
return Stat; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -682,7 +682,7 @@ di_fail:
|
|
|
|
|
/* Get Disk Status */ |
|
|
|
|
/*-----------------------------------------------------------------------*/ |
|
|
|
|
|
|
|
|
|
DSTATUS MCI_status(void) |
|
|
|
|
diskio_sta_t mci_status(void) |
|
|
|
|
{ |
|
|
|
|
return Stat; |
|
|
|
|
} |
|
|
|
@ -699,17 +699,17 @@ DSTATUS MCI_status(void)
|
|
|
|
|
* @param sector Start sector number (LBA) |
|
|
|
|
* @param count Sector count (1..127) |
|
|
|
|
*/ |
|
|
|
|
DRESULT MCI_read(unsigned char *buff, unsigned long sector, unsigned char count) |
|
|
|
|
diskio_result_t mci_read(unsigned char *buff, unsigned long sector, unsigned char count) |
|
|
|
|
{ |
|
|
|
|
unsigned long resp; |
|
|
|
|
unsigned int cmd; |
|
|
|
|
|
|
|
|
|
if (count < 1 || count > 127) { |
|
|
|
|
return RES_PARERR; /* Check parameter */ |
|
|
|
|
return DISKIO_RES_PARERR; /* Check parameter */ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (Stat & STA_NOINIT) { |
|
|
|
|
return RES_NOTRDY; /* Check drive status */ |
|
|
|
|
if (Stat & DISKIO_STA_NOINIT) { |
|
|
|
|
return DISKIO_RES_NOTRDY; /* Check drive status */ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!(CardType & CT_BLOCK)) { |
|
|
|
@ -717,7 +717,7 @@ DRESULT MCI_read(unsigned char *buff, unsigned long sector, unsigned char count)
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!wait_ready(500)) { |
|
|
|
|
return RES_ERROR; /* Make sure that card is tran state */ |
|
|
|
|
return DISKIO_RES_ERROR; /* Make sure that card is tran state */ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ready_reception(count, 512); /* Ready to receive data blocks */ |
|
|
|
@ -738,7 +738,7 @@ DRESULT MCI_read(unsigned char *buff, unsigned long sector, unsigned char count)
|
|
|
|
|
break; /* Abort if any error has occured */ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Copy_al2un(buff, DmaBuff[rp], 512); /* Pop an block */ |
|
|
|
|
copy_al2un(buff, DmaBuff[rp], 512); /* Pop an block */ |
|
|
|
|
|
|
|
|
|
XferRp = rp = (rp + 1) % N_BUF; /* Next DMA buffer */ |
|
|
|
|
|
|
|
|
@ -756,7 +756,7 @@ DRESULT MCI_read(unsigned char *buff, unsigned long sector, unsigned char count)
|
|
|
|
|
|
|
|
|
|
stop_transfer(); /* Close data path */ |
|
|
|
|
|
|
|
|
|
return count ? RES_ERROR : RES_OK; |
|
|
|
|
return count ? DISKIO_RES_ERROR : DISKIO_RES_OK; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -771,22 +771,22 @@ DRESULT MCI_read(unsigned char *buff, unsigned long sector, unsigned char count)
|
|
|
|
|
* @param sector Start sector number (LBA) |
|
|
|
|
* @param count Sector count (1..127) |
|
|
|
|
* */ |
|
|
|
|
DRESULT MCI_write(const unsigned char *buff, unsigned long sector, unsigned char count) |
|
|
|
|
diskio_result_t mci_write(const unsigned char *buff, unsigned long sector, unsigned char count) |
|
|
|
|
{ |
|
|
|
|
unsigned long rc; |
|
|
|
|
unsigned int cmd; |
|
|
|
|
unsigned char wp, xc; |
|
|
|
|
|
|
|
|
|
if (count < 1 || count > 127) { |
|
|
|
|
return RES_PARERR; /* Check parameter */ |
|
|
|
|
return DISKIO_RES_PARERR; /* Check parameter */ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (Stat & STA_NOINIT) { |
|
|
|
|
return RES_NOTRDY; /* Check drive status */ |
|
|
|
|
if (Stat & DISKIO_STA_NOINIT) { |
|
|
|
|
return DISKIO_RES_NOTRDY; /* Check drive status */ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (Stat & STA_PROTECT) { |
|
|
|
|
return RES_WRPRT; /* Check write protection */ |
|
|
|
|
if (Stat & DISKIO_STA_PROTECT) { |
|
|
|
|
return DISKIO_RES_WRPRT; /* Check write protection */ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!(CardType & CT_BLOCK)) { |
|
|
|
@ -794,7 +794,7 @@ DRESULT MCI_write(const unsigned char *buff, unsigned long sector, unsigned char
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!wait_ready(500)) { |
|
|
|
|
return RES_ERROR; /* Make sure that card is tran state */ |
|
|
|
|
return DISKIO_RES_ERROR; /* Make sure that card is tran state */ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (count == 1) { /* Single block write */ |
|
|
|
@ -805,7 +805,7 @@ DRESULT MCI_write(const unsigned char *buff, unsigned long sector, unsigned char
|
|
|
|
|
|
|
|
|
|
if (!send_cmd(cmd, count, 1, &rc) /* Preset number of blocks to write */ |
|
|
|
|
|| (rc & 0xC0580000)) { |
|
|
|
|
return RES_ERROR; |
|
|
|
|
return DISKIO_RES_ERROR; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
cmd = CMD25; |
|
|
|
@ -813,14 +813,14 @@ DRESULT MCI_write(const unsigned char *buff, unsigned long sector, unsigned char
|
|
|
|
|
|
|
|
|
|
if (!send_cmd(cmd, sector, 1, &rc) /* Send a write command */ |
|
|
|
|
|| (rc & 0xC0580000)) { |
|
|
|
|
return RES_ERROR; |
|
|
|
|
return DISKIO_RES_ERROR; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
wp = 0; |
|
|
|
|
xc = count; |
|
|
|
|
|
|
|
|
|
do { /* Fill block FIFO */ |
|
|
|
|
Copy_un2al(DmaBuff[wp], (unsigned char *)(unsigned int)buff, 512); /* Push a block */ |
|
|
|
|
copy_un2al(DmaBuff[wp], (unsigned char *)(unsigned int)buff, 512); /* Push a block */ |
|
|
|
|
wp++; /* Next DMA buffer */ |
|
|
|
|
count--; |
|
|
|
|
buff += 512; /* Next user buffer address */ |
|
|
|
@ -839,7 +839,7 @@ DRESULT MCI_write(const unsigned char *buff, unsigned long sector, unsigned char
|
|
|
|
|
break; /* Abort if block underrun or any MCI error has occured */ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Copy_un2al(DmaBuff[wp], (unsigned char *)(unsigned int)buff, 512); /* Push a block */ |
|
|
|
|
copy_un2al(DmaBuff[wp], (unsigned char *)(unsigned int)buff, 512); /* Push a block */ |
|
|
|
|
XferWp = wp = (wp + 1) % N_BUF; /* Next DMA buffer */ |
|
|
|
|
|
|
|
|
|
if (XferStat & 0xC) { |
|
|
|
@ -862,7 +862,7 @@ DRESULT MCI_write(const unsigned char *buff, unsigned long sector, unsigned char
|
|
|
|
|
send_cmd(CMD12, 0, 1, &rc); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return count ? RES_ERROR : RES_OK; |
|
|
|
|
return count ? DISKIO_RES_ERROR : DISKIO_RES_OK; |
|
|
|
|
} |
|
|
|
|
#endif /* _READONLY */ |
|
|
|
|
|
|
|
|
@ -873,26 +873,26 @@ DRESULT MCI_write(const unsigned char *buff, unsigned long sector, unsigned char
|
|
|
|
|
/* Miscellaneous Functions */ |
|
|
|
|
/*-----------------------------------------------------------------------*/ |
|
|
|
|
|
|
|
|
|
DRESULT MCI_ioctl( |
|
|
|
|
diskio_result_t mci_ioctl( |
|
|
|
|
unsigned char ctrl, /* Control code */ |
|
|
|
|
void *buff /* Buffer to send/receive data block */ |
|
|
|
|
) |
|
|
|
|
{ |
|
|
|
|
DRESULT res; |
|
|
|
|
diskio_result_t res; |
|
|
|
|
unsigned char *ptr = (unsigned char *)buff; |
|
|
|
|
unsigned long resp[4], d, *dp, st, ed; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (Stat & STA_NOINIT) { |
|
|
|
|
return RES_NOTRDY; |
|
|
|
|
if (Stat & DISKIO_STA_NOINIT) { |
|
|
|
|
return DISKIO_RES_NOTRDY; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
res = RES_ERROR; |
|
|
|
|
res = DISKIO_RES_ERROR; |
|
|
|
|
|
|
|
|
|
switch(ctrl) { |
|
|
|
|
case CTRL_SYNC : /* Make sure that all data has been written on the media */ |
|
|
|
|
if (wait_ready(500)) { /* Wait for card enters tarn state */ |
|
|
|
|
res = RES_OK; |
|
|
|
|
res = DISKIO_RES_OK; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
break; |
|
|
|
@ -908,12 +908,12 @@ DRESULT MCI_ioctl(
|
|
|
|
|
*(unsigned long *)buff = d << (b - 9); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
res = RES_OK; |
|
|
|
|
res = DISKIO_RES_OK; |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case GET_SECTOR_SIZE : /* Get sectors on the disk (unsigned short) */ |
|
|
|
|
*(unsigned short *)buff = 512; |
|
|
|
|
res = RES_OK; |
|
|
|
|
res = DISKIO_RES_OK; |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case GET_BLOCK_SIZE : /* Get erase block size in unit of sectors (unsigned long) */ |
|
|
|
@ -929,7 +929,7 @@ DRESULT MCI_ioctl(
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
res = RES_OK; |
|
|
|
|
res = DISKIO_RES_OK; |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case CTRL_ERASE_SECTOR : /* Erase a block of sectors */ |
|
|
|
@ -947,7 +947,7 @@ DRESULT MCI_ioctl(
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (send_cmd(CMD32, st, 1, resp) && send_cmd(CMD33, ed, 1, resp) && send_cmd(CMD38, 0, 1, resp) && wait_ready(30000)) { |
|
|
|
|
res = RES_OK; |
|
|
|
|
res = DISKIO_RES_OK; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
break; |
|
|
|
@ -956,38 +956,38 @@ DRESULT MCI_ioctl(
|
|
|
|
|
switch(ptr[0]) { |
|
|
|
|
case 0: /* Sub control code == 0 (POWER_OFF) */ |
|
|
|
|
power_off(); /* Power off */ |
|
|
|
|
res = RES_OK; |
|
|
|
|
res = DISKIO_RES_OK; |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case 1: /* Sub control code == 1 (POWER_GET) */ |
|
|
|
|
ptr[1] = (unsigned char)power_status(); |
|
|
|
|
res = RES_OK; |
|
|
|
|
res = DISKIO_RES_OK; |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
default : |
|
|
|
|
res = RES_PARERR; |
|
|
|
|
res = DISKIO_RES_PARERR; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case MMC_GET_TYPE : /* Get card type flags (1 byte) */ |
|
|
|
|
*ptr = CardType; |
|
|
|
|
res = RES_OK; |
|
|
|
|
res = DISKIO_RES_OK; |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case MMC_GET_CSD : /* Get CSD (16 bytes) */ |
|
|
|
|
memcpy(buff, &CardInfo[0], 16); |
|
|
|
|
res = RES_OK; |
|
|
|
|
res = DISKIO_RES_OK; |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case MMC_GET_CID : /* Get CID (16 bytes) */ |
|
|
|
|
memcpy(buff, &CardInfo[16], 16); |
|
|
|
|
res = RES_OK; |
|
|
|
|
res = DISKIO_RES_OK; |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case MMC_GET_OCR : /* Get OCR (4 bytes) */ |
|
|
|
|
memcpy(buff, &CardInfo[32], 4); |
|
|
|
|
res = RES_OK; |
|
|
|
|
res = DISKIO_RES_OK; |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case MMC_GET_SDSTAT : /* Receive SD status as a data block (64 bytes) */ |
|
|
|
@ -1000,8 +1000,8 @@ DRESULT MCI_ioctl(
|
|
|
|
|
while ((XferWp == 0) && !(XferStat & 0xC)) {} |
|
|
|
|
|
|
|
|
|
if (!(XferStat & 0xC)) { |
|
|
|
|
Copy_al2un((unsigned char *)buff, DmaBuff[0], 64); |
|
|
|
|
res = RES_OK; |
|
|
|
|
copy_al2un((unsigned char *)buff, DmaBuff[0], 64); |
|
|
|
|
res = DISKIO_RES_OK; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -1012,7 +1012,7 @@ DRESULT MCI_ioctl(
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
default: |
|
|
|
|
res = RES_PARERR; |
|
|
|
|
res = DISKIO_RES_PARERR; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return res; |
|
|
|
|