From 6e0ae1baada885bdb6bfa9e6e1aaa0eb08c67c8c Mon Sep 17 00:00:00 2001 From: Jarielle Catbagan Date: Sun, 2 Aug 2015 21:16:41 -0700 Subject: BBB: am335x_sd.c: Integrate reading and writing functionality in "sd" command --- ports/beagleboneblack/am335x_sd.c | 159 +++++++++++++++++++++++++++++++++++++- 1 file changed, 156 insertions(+), 3 deletions(-) diff --git a/ports/beagleboneblack/am335x_sd.c b/ports/beagleboneblack/am335x_sd.c index 0f20f8e..ac2392c 100644 --- a/ports/beagleboneblack/am335x_sd.c +++ b/ports/beagleboneblack/am335x_sd.c @@ -242,19 +242,172 @@ sdInit(int interface, int verbosity) int sdRead(int interface, char *buf, int blknum, int blkcount) { - return(-1); + uint32_t cmd, arg, resp[4]; + uint32_t *wordptr = (uint32_t *) buf; + int byteindex; + + /* Get the SD card's status via CMD13 */ + arg = (sdrca << 16) & 0xFFFF0000; + cmd = SD_CMD_CMD13_SEND_STATUS | SD_CMD_CMD_TYPE_NORMAL | SD_CMD_DP_NO_DATA_PRESENT | + SD_CMD_CICE_ENABLE | SD_CMD_CCCE_ENABLE | SD_CMD_RSP_TYPE_R1; + if (sdcmd(cmd, arg, resp) == -1) + return(-1); + + /* Ensure that the card is in Transfer State before proceeding */ + if ((resp[0] & SD_RSP10_R1_CURRENT_STATE) != SD_RSP10_R1_CURRENT_STATE_TRANSFER) { + arg = (sdrca << 16) & 0xFFFF0000; + cmd = SD_CMD_CMD7_SELECT_DESELECT_CARD | SD_CMD_CMD_TYPE_NORMAL | + SD_CMD_DP_NO_DATA_PRESENT | SD_CMD_CICE_ENABLE | SD_CMD_CCCE_ENABLE | + SD_CMD_RSP_TYPE_R1B; + if (sdcmd(cmd, arg, resp) == -1) + return(-1); + + /* Wait for the SD card to enter Transfer State */ + do { + arg = (sdrca << 16) & 0xFFFF0000; + cmd = SD_CMD_CMD13_SEND_STATUS | SD_CMD_CMD_TYPE_NORMAL | + SD_CMD_DP_NO_DATA_PRESENT | SD_CMD_CICE_ENABLE | SD_CMD_CCCE_ENABLE | + SD_CMD_RSP_TYPE_R1; + if (sdcmd(cmd, arg, resp) == -1) + return(-1); + } while ((resp[0] & SD_RSP10_R1_CURRENT_STATE) != SD_RSP10_R1_CURRENT_STATE_TRANSFER); + } + + /* Set the block length and the number of blocks to read */ + MMCHS0_REG(SD_BLK) = SD_BLKSIZE | (blkcount << 16); + /* Send CMD18, i.e. read multiple blocks */ + arg = blknum; + cmd = SD_CMD_CMD18_READ_MULTIPLE_BLOCK | SD_CMD_CMD_TYPE_NORMAL | SD_CMD_DP_DATA_PRESENT | + SD_CMD_CICE_ENABLE | SD_CMD_CCCE_ENABLE | SD_CMD_RSP_TYPE_R1 | SD_CMD_MSBS_MULTIPLE | + SD_CMD_DDIR_READ | SD_CMD_ACEN_CMD12_ENABLE | SD_CMD_BCE_ENABLE; + if (sdcmd(cmd, arg, resp) == -1) + return(-1); + + /* Check the data buffer to see if there is data to be read */ + do { + while (!(MMCHS0_REG(SD_STAT) & SD_STAT_BRR)); + + /* Clear the BRR status bit in SD_STAT */ + MMCHS0_REG(SD_STAT) |= SD_STAT_BRR; + + for (byteindex = 0; byteindex < (SD_BLKSIZE / 4); byteindex++) { + *wordptr = (MMCHS0_REG(SD_DATA)); + wordptr++; + } + } while (!(MMCHS0_REG(SD_STAT) & SD_STAT_TC)); + + /* Put the SD card into Stand-by State */ + arg = 0; + cmd = SD_CMD_CMD7_SELECT_DESELECT_CARD | SD_CMD_CMD_TYPE_NORMAL | SD_CMD_DP_NO_DATA_PRESENT | + SD_CMD_CICE_ENABLE | SD_CMD_CCCE_ENABLE | SD_CMD_RSP_TYPE_NO_RESPONSE; + if (sdcmd(cmd, arg, resp) == -1) + return(-1); + + /* Wait for the SD card to enter Stand-by State */ + do { + arg = (sdrca << 16) & 0xFFFF0000; + cmd = SD_CMD_CMD13_SEND_STATUS | SD_CMD_CMD_TYPE_NORMAL | SD_CMD_DP_NO_DATA_PRESENT | + SD_CMD_CICE_ENABLE | SD_CMD_CCCE_ENABLE | SD_CMD_RSP_TYPE_R1; + if (sdcmd(cmd, arg, resp) == -1) + return(-1); + } while ((resp[0] & SD_RSP10_R1_CURRENT_STATE) != SD_RSP10_R1_CURRENT_STATE_STANDBY); + + return(0); } int sdWrite(int interface, char *buf, int blknum, int blkcount) { - return(-1); + uint32_t cmd, arg, resp[4]; + uint32_t *wordptr = (uint32_t *) buf; + int byteindex; + + /* Get the SD card's status by sending CMD13 */ + arg = (sdrca << 16) & 0xFFFF0000; + cmd = SD_CMD_CMD13_SEND_STATUS | SD_CMD_CMD_TYPE_NORMAL | SD_CMD_DP_NO_DATA_PRESENT | + SD_CMD_CICE_ENABLE | SD_CMD_CCCE_ENABLE | SD_CMD_RSP_TYPE_R1; + if (sdcmd(cmd, arg, resp) == -1) + return(-1); + + /* Ensure that the card is in the Transfer State before proceeding */ + if ((resp[0] & SD_RSP10_R1_CURRENT_STATE) != SD_RSP10_R1_CURRENT_STATE_TRANSFER) { + arg = (sdrca << 16) & 0xFFFF0000; + cmd = SD_CMD_CMD7_SELECT_DESELECT_CARD | SD_CMD_CMD_TYPE_NORMAL | + SD_CMD_DP_NO_DATA_PRESENT | SD_CMD_CICE_ENABLE | SD_CMD_CCCE_ENABLE | + SD_CMD_RSP_TYPE_R1B; + if (sdcmd(cmd, arg, resp) == -1) + return(-1); + + /* Wait for SD card to enter Transfer State */ + do { + arg = (sdrca << 16) & 0xFFFF0000; + cmd = SD_CMD_CMD13_SEND_STATUS | SD_CMD_CMD_TYPE_NORMAL | + SD_CMD_DP_NO_DATA_PRESENT | SD_CMD_CICE_ENABLE | SD_CMD_CCCE_ENABLE | + SD_CMD_RSP_TYPE_R1; + if (sdcmd(cmd, arg, resp) == -1) + return(-1); + } while ((resp[0] & SD_RSP10_R1_CURRENT_STATE) != SD_RSP10_R1_CURRENT_STATE_TRANSFER); + } + + /* Set the block length in bytes and the number of blocks to write to the SD card */ + MMCHS0_REG(SD_BLK) = SD_BLKSIZE | ( blkcount << 16); + /* Send CMD25, that is write the number of blocks specified in 'blkcount' from 'buf' to the + * location that is 512 byte aligned in the SD card specified by the block number 'blknum' + */ + arg = blknum; + cmd = SD_CMD_CMD25_WRITE_MULTIPLE_BLOCK | SD_CMD_CMD_TYPE_NORMAL | SD_CMD_DP_DATA_PRESENT | + SD_CMD_CICE_ENABLE | SD_CMD_CCCE_ENABLE | SD_CMD_RSP_TYPE_R1 | SD_CMD_MSBS_MULTIPLE | + SD_CMD_DDIR_WRITE | SD_CMD_ACEN_CMD12_ENABLE | SD_CMD_BCE_ENABLE; + if (sdcmd(cmd, arg, resp) == -1) + return(-1); + + /* Write the data */ + do { + /* Wait until data is ready to be written */ + while (!(MMCHS0_REG(SD_STAT) & (SD_STAT_BWR | SD_STAT_TC))); + + if (MMCHS0_REG(SD_STAT) & SD_STAT_TC) + break; + + /* Clear the BWR status bit in SD_STAT */ + MMCHS0_REG(SD_STAT) |= SD_STAT_BWR; + + for (byteindex = 0; byteindex < (SD_BLKSIZE / 4); byteindex++) + MMCHS0_REG(SD_DATA) = *wordptr++; + } while (!(MMCHS0_REG(SD_STAT) & SD_STAT_TC)); + + /* Put the SD card into Stand-by State */ + arg = 0x00000000; + cmd = SD_CMD_CMD7_SELECT_DESELECT_CARD | SD_CMD_CMD_TYPE_NORMAL | SD_CMD_DP_NO_DATA_PRESENT | + SD_CMD_CICE_ENABLE | SD_CMD_CCCE_ENABLE | SD_CMD_RSP_TYPE_NO_RESPONSE; + if (sdcmd(cmd, arg, resp) == -1) + return(-1); + + /* Wait for SD card to enter Stand-by State */ + do { + arg= (sdrca << 16) & 0xFFFF0000; + cmd = SD_CMD_CMD13_SEND_STATUS | SD_CMD_CMD_TYPE_NORMAL | SD_CMD_DP_NO_DATA_PRESENT | + SD_CMD_CICE_ENABLE | SD_CMD_CCCE_ENABLE | SD_CMD_RSP_TYPE_R1; + if (sdcmd(cmd, arg, resp) == -1) + return(-1); + } while ((resp[0] & SD_RSP10_R1_CURRENT_STATE) != SD_RSP10_R1_CURRENT_STATE_STANDBY); + + return(0); } int sdInstalled(int interface) { - return(-1); + if ((MMCHS0_REG(SD_CON) & SD_CON_CDP) == SD_CON_CDP_ACTIVE_HIGH) + if (MMCHS0_REG(SD_PSTATE) & SD_PSTATE_CINS) + return(1); + else + return(0); + else + if (MMCHS0_REG(SD_PSTATE) & SD_PSTATE_CINS) + return(0); + else + return(1); } int -- cgit v1.2.3