drivers/mmcsd: Added support for MMC(eMMC) bigger than 2 GB (Tested with IMXRT1050EVKB and samsung eMMC 16GB). arch/arm/src/imxrt: IMXRT uSDHC driver cmd line reset logic modified.

This commit is contained in:
Ivan Ucherdzhiev
2019-08-21 09:23:29 -06:00
committed by Gregory Nutt
parent fe6f9b1f24
commit 19c070e0d1
5 changed files with 428 additions and 111 deletions
+6 -1
View File
@@ -4,6 +4,7 @@
* Copyright (C) 2018-2019 Gregory Nutt. All rights reserved. * Copyright (C) 2018-2019 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org> * Author: Gregory Nutt <gnutt@nuttx.org>
* Dave Marples <dave@marples.net> * Dave Marples <dave@marples.net>
* Ivan Ucherdzhiev <ivanucherdjiev@gmail.com>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -2021,7 +2022,11 @@ static int imxrt_sendcmd(FAR struct sdio_dev_s *dev, uint32_t cmd,
if ((getreg32(priv->addr + IMXRT_USDHC_IRQSTAT_OFFSET) & USDHC_RESPERR_INTS) != 0) if ((getreg32(priv->addr + IMXRT_USDHC_IRQSTAT_OFFSET) & USDHC_RESPERR_INTS) != 0)
{ {
putreg32(USDHC_SYSCTL_RSTC, priv->addr + IMXRT_USDHC_SYSCTL_OFFSET); modifyreg32(priv->addr + IMXRT_USDHC_SYSCTL_OFFSET, 0, USDHC_SYSCTL_RSTC);
while ((getreg32(priv->addr + IMXRT_USDHC_SYSCTL_OFFSET) &
USDHC_SYSCTL_RSTC) != 0)
{
}
} }
timeout = USDHC_CMDTIMEOUT; timeout = USDHC_CMDTIMEOUT;
+3 -2
View File
@@ -62,7 +62,7 @@
#define MMCSD_CARDTYPE_MMC 1 /* Bit 0: MMC card */ #define MMCSD_CARDTYPE_MMC 1 /* Bit 0: MMC card */
#define MMCSD_CARDTYPE_SDV1 2 /* Bit 1: SD version 1.x */ #define MMCSD_CARDTYPE_SDV1 2 /* Bit 1: SD version 1.x */
#define MMCSD_CARDTYPE_SDV2 4 /* Bit 2: SD version 2.x with byte addressing */ #define MMCSD_CARDTYPE_SDV2 4 /* Bit 2: SD version 2.x with byte addressing */
#define MMCSD_CARDTYPE_BLOCK 8 /* Bit 3: SD version 2.x with block addressing */ #define MMCSD_CARDTYPE_BLOCK 8 /* Bit 3: SD version 2.x or MMC with block addressing */
#define IS_MMC(t) (((t) & MMCSD_CARDTYPE_MMC) != 0) #define IS_MMC(t) (((t) & MMCSD_CARDTYPE_MMC) != 0)
#define IS_SD(t) (((t) & (MMCSD_CARDTYPE_SDV1|MMCSD_CARDTYPE_SDV2)) != 0) #define IS_SD(t) (((t) & (MMCSD_CARDTYPE_SDV1|MMCSD_CARDTYPE_SDV2)) != 0)
@@ -81,7 +81,8 @@
#undef EXTERN #undef EXTERN
#if defined(__cplusplus) #if defined(__cplusplus)
#define EXTERN extern "C" #define EXTERN extern "C"
extern "C" { extern "C"
{
#else #else
#define EXTERN extern #define EXTERN extern
#endif #endif
+323 -16
View File
@@ -1,9 +1,10 @@
/**************************************************************************** /****************************************************************************
* drivers/mmcsd/mmcsd_sdio.c * drivers/mmcsd/mmcsd_sdio.c
* *
* Copyright (C) 2009-2013, 2016-2018 Gregory Nutt. All rights reserved. * Copyright (C) 2009-2013, 2016-2019 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org> * Author: Gregory Nutt <gnutt@nuttx.org>
* Bob Feretich <bob.fereich@rafresearch.com> * Bob Feretich <bob.fereich@rafresearch.com>
* Ivan Ucherdzhiev <ivanucherdjiev@gmail.com>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -245,6 +246,7 @@ static void mmcsd_mediachange(FAR void *arg);
static int mmcsd_widebus(FAR struct mmcsd_state_s *priv); static int mmcsd_widebus(FAR struct mmcsd_state_s *priv);
#ifdef CONFIG_MMCSD_MMCSUPPORT #ifdef CONFIG_MMCSD_MMCSUPPORT
static int mmcsd_mmcinitialize(FAR struct mmcsd_state_s *priv); static int mmcsd_mmcinitialize(FAR struct mmcsd_state_s *priv);
static int mmcsd_mmcreadextCSD (FAR struct mmcsd_state_s *priv);
#endif #endif
static int mmcsd_sdinitialize(FAR struct mmcsd_state_s *priv); static int mmcsd_sdinitialize(FAR struct mmcsd_state_s *priv);
static int mmcsd_cardidentify(FAR struct mmcsd_state_s *priv); static int mmcsd_cardidentify(FAR struct mmcsd_state_s *priv);
@@ -656,6 +658,49 @@ static void mmcsd_decodeCSD(FAR struct mmcsd_state_s *priv, uint32_t csd[4])
if (IS_BLOCK(priv->type)) if (IS_BLOCK(priv->type))
{ {
#ifdef CONFIG_MMCSD_MMCSUPPORT
if (IS_MMC(priv->type))
{
/* Block addressed MMC:
*
* C_SIZE: 73:64 from Word 2 and 63:62 from Word 3
*/
/* If the card is MMC and it has Block addressing
* then the correct number of blocks should already be
* read from extended CSD register.
*/
uint16_t csize = ((csd[1] & 0x03ff) << 2) | ((csd[2] >> 30) & 3);
uint8_t csizemult = (csd[2] >> 15) & 7;
priv->blockshift = readbllen;
priv->blocksize = (1 << readbllen);
#ifdef CONFIG_HAVE_LONG_LONG
priv->capacity = ((uint64_t)(priv->nblocks)) << readbllen;
#else
priv->capacity = (priv->nblocks << readbllen);
#endif
if (priv->blocksize > 512)
{
priv->blocksize = 512;
priv->blockshift = 9;
}
decoded.u.mmc.csize = csize;
decoded.u.mmc.vddrcurrmin = (csd[2] >> 27) & 7;
decoded.u.mmc.vddrcurrmax = (csd[2] >> 24) & 7;
decoded.u.mmc.vddwcurrmin = (csd[2] >> 21) & 7;
decoded.u.mmc.vddwcurrmax = (csd[2] >> 18) & 7;
decoded.u.mmc.csizemult = csizemult;
decoded.u.mmc.er.mmc22.sectorsize = (csd[2] >> 10) & 0x1f;
decoded.u.mmc.er.mmc22.ergrpsize = (csd[2] >> 5) & 0x1f;
decoded.u.mmc.mmcwpgrpsize = csd[2] & 0x1f;
}
else
#endif
{
/* Block addressed SD: /* Block addressed SD:
* *
* C_SIZE: 69:64 from Word 2 and 63:48 from Word 3 * C_SIZE: 69:64 from Word 2 and 63:48 from Word 3
@@ -682,6 +727,7 @@ static void mmcsd_decodeCSD(FAR struct mmcsd_state_s *priv, uint32_t csd[4])
decoded.u.sdblock.sdwpgrpsize = csd[2] & 0x7f; decoded.u.sdblock.sdwpgrpsize = csd[2] & 0x7f;
#endif #endif
} }
}
else else
{ {
/* Byte addressed SD: /* Byte addressed SD:
@@ -792,12 +838,30 @@ static void mmcsd_decodeCSD(FAR struct mmcsd_state_s *priv, uint32_t csd[4])
if (IS_BLOCK(priv->type)) if (IS_BLOCK(priv->type))
{ {
#ifdef CONFIG_MMCSD_MMCSUPPORT
if (IS_MMC(priv->type))
{
finfo(" MMC Block Addressing:\n");
finfo(" C_SIZE: %d C_SIZE_MULT: %d\n",
decoded.u.mmc.csize, decoded.u.mmc.csizemult);
finfo(" VDD_R_CURR_MIN: %d VDD_R_CURR_MAX: %d\n",
decoded.u.mmc.vddrcurrmin, decoded.u.mmc.vddrcurrmax);
finfo(" VDD_W_CURR_MIN: %d VDD_W_CURR_MAX: %d\n",
decoded.u.mmc.vddwcurrmin, decoded.u.mmc.vddwcurrmax);
finfo(" MMC_SECTOR_SIZE: %d MMC_ER_GRP_SIZE: %d MMC_WP_GRP_SIZE: %d\n",
decoded.u.mmc.er.mmc22.sectorsize, decoded.u.mmc.er.mmc22.ergrpsize,
decoded.u.mmc.mmcwpgrpsize);
}
else
#endif
{
finfo(" SD Block Addressing:\n"); finfo(" SD Block Addressing:\n");
finfo(" C_SIZE: %d SD_ER_BLK_EN: %d\n", finfo(" C_SIZE: %d SD_ER_BLK_EN: %d\n",
decoded.u.sdblock.csize, decoded.u.sdblock.sderblen); decoded.u.sdblock.csize, decoded.u.sdblock.sderblen);
finfo(" SD_SECTOR_SIZE: %d SD_WP_GRP_SIZE: %d\n", finfo(" SD_SECTOR_SIZE: %d SD_WP_GRP_SIZE: %d\n",
decoded.u.sdblock.sdsectorsize, decoded.u.sdblock.sdwpgrpsize); decoded.u.sdblock.sdsectorsize, decoded.u.sdblock.sdwpgrpsize);
} }
}
else if (IS_SD(priv->type)) else if (IS_SD(priv->type))
{ {
finfo(" SD Byte Addressing:\n"); finfo(" SD Byte Addressing:\n");
@@ -808,7 +872,8 @@ static void mmcsd_decodeCSD(FAR struct mmcsd_state_s *priv, uint32_t csd[4])
finfo(" VDD_W_CURR_MIN: %d VDD_W_CURR_MAX: %d\n", finfo(" VDD_W_CURR_MIN: %d VDD_W_CURR_MAX: %d\n",
decoded.u.sdbyte.vddwcurrmin, decoded.u.sdbyte.vddwcurrmax); decoded.u.sdbyte.vddwcurrmin, decoded.u.sdbyte.vddwcurrmax);
finfo(" SD_ER_BLK_EN: %d SD_SECTOR_SIZE: %d (SD) SD_WP_GRP_SIZE: %d\n", finfo(" SD_ER_BLK_EN: %d SD_SECTOR_SIZE: %d (SD) SD_WP_GRP_SIZE: %d\n",
decoded.u.sdbyte.sderblen, decoded.u.sdbyte.sdsectorsize, decoded.u.sdbyte.sdwpgrpsize); decoded.u.sdbyte.sderblen, decoded.u.sdbyte.sdsectorsize,
decoded.u.sdbyte.sdwpgrpsize);
} }
#ifdef CONFIG_MMCSD_MMCSUPPORT #ifdef CONFIG_MMCSD_MMCSUPPORT
else if (IS_MMC(priv->type)) else if (IS_MMC(priv->type))
@@ -847,7 +912,7 @@ static void mmcsd_decodeCSD(FAR struct mmcsd_state_s *priv, uint32_t csd[4])
* Name: mmcsd_decodeCID * Name: mmcsd_decodeCID
* *
* Description: * Description:
* Show the contents of the Card Indentification Data (CID) (for debug * Show the contents of the Card Identification Data (CID) (for debug
* purposes only) * purposes only)
* *
****************************************************************************/ ****************************************************************************/
@@ -2569,7 +2634,8 @@ static int mmcsd_mmcinitialize(FAR struct mmcsd_state_s *priv)
* sending its CID (only one card completes the response at a time). The * sending its CID (only one card completes the response at a time). The
* driver should send CMD2 and assign an RCAs until no response to * driver should send CMD2 and assign an RCAs until no response to
* ALL_SEND_CID is received. CMD2 causes transition to identification state/ * ALL_SEND_CID is received. CMD2 causes transition to identification state/
* card-identification mode */ * card-identification mode.
*/
mmcsd_sendcmdpoll(priv, MMCSD_CMD2, 0); mmcsd_sendcmdpoll(priv, MMCSD_CMD2, 0);
ret = SDIO_RECVR2(priv->dev, MMCSD_CMD2, cid); ret = SDIO_RECVR2(priv->dev, MMCSD_CMD2, cid);
@@ -2622,8 +2688,6 @@ static int mmcsd_mmcinitialize(FAR struct mmcsd_state_s *priv)
return ret; return ret;
} }
mmcsd_decodeCSD(priv, csd);
/* Set the Driver Stage Register (DSR) if (1) a CONFIG_MMCSD_DSR has been /* Set the Driver Stage Register (DSR) if (1) a CONFIG_MMCSD_DSR has been
* provided and (2) the card supports a DSR register. If no DSR value * provided and (2) the card supports a DSR register. If no DSR value
* the card default value (0x0404) will be used. * the card default value (0x0404) will be used.
@@ -2631,12 +2695,165 @@ static int mmcsd_mmcinitialize(FAR struct mmcsd_state_s *priv)
(void)mmcsd_sendcmd4(priv); (void)mmcsd_sendcmd4(priv);
/* Send CMD7 with the argument == RCA in order to select the card
* and send it in data-trasfer mode. Since we are supporting
* only a single card, we just leave the card selected all of the time.
*/
mmcsd_sendcmdpoll(priv, MMCSD_CMD7S, (uint32_t)priv->rca << 16);
ret = mmcsd_recvR1(priv, MMCSD_CMD7S);
if (ret != OK)
{
ferr("ERROR: mmcsd_recvR1 for CMD7 failed: %d\n", ret);
return ret;
}
/* CSD Decoding for MMC should be done after entering in data-transfer mode
* because if the card has block addressing then extended CSD register
* must be read in order to get the right number of blocks and capacity,
* but it has to be done in data-transfer mode.
*/
if (IS_BLOCK(priv->type))
{
ret = mmcsd_mmcreadextCSD(priv);
if (ret != OK)
{
ferr("ERROR: Failed to determinate number of blocks: %d\n", ret);
return ret;
}
}
mmcsd_decodeCSD(priv, csd);
/* Select high speed MMC clocking (which may depend on the DSR setting) */ /* Select high speed MMC clocking (which may depend on the DSR setting) */
SDIO_CLOCK(priv->dev, CLOCK_MMC_TRANSFER); SDIO_CLOCK(priv->dev, CLOCK_MMC_TRANSFER);
up_udelay(MMCSD_CLK_DELAY); up_udelay(MMCSD_CLK_DELAY);
return OK; return OK;
} }
/****************************************************************************
* Name: mmcsd_mmcreadextCSD
*
* Description:
* MMC card is detected with block addressing and this function will read
* the correct number of blocks and capacity. Returns OK if ext CSD is read
* correctly or error in not.
*
****************************************************************************/
static int mmcsd_mmcreadextCSD (FAR struct mmcsd_state_s *priv)
{
int ret;
uint8_t buffer[512];
DEBUGASSERT(priv != NULL);
/* Check if the card is locked */
if (priv->locked)
{
ferr("ERROR: Card is locked\n");
return -EPERM;
}
#if defined(CONFIG_SDIO_DMA) && defined(CONFIG_ARCH_HAVE_SDIO_PREFLIGHT)
/* If we think we are going to perform a DMA transfer, make sure that we
* will be able to before we commit the card to the operation.
*/
if ((priv->caps & SDIO_CAPS_DMASUPPORTED) != 0)
{
ret = SDIO_DMAPREFLIGHT(priv->dev, buffer, priv->blocksize);
if (ret != OK)
{
return ret;
}
}
#endif
/* Verify that the card is ready for the transfer. The card may still be
* busy from the preceding write transfer. It would be simpler to check
* for write busy at the end of each write, rather than at the beginning of
* each read AND write, but putting the busy-wait at the beginning of the
* transfer allows for more overlap and, hopefully, better performance
*/
ret = mmcsd_transferready(priv);
if (ret != OK)
{
ferr("ERROR: Card not ready: %d\n", ret);
return ret;
}
/* Select the block size for the card */
ret = mmcsd_setblocklen(priv, 512);
if (ret != OK)
{
ferr("ERROR: mmcsd_setblocklen failed: %d\n", ret);
return ret;
}
/* Configure SDIO controller hardware for the read transfer */
SDIO_BLOCKSETUP(priv->dev, 512, 1);
SDIO_WAITENABLE(priv->dev,
SDIOWAIT_TRANSFERDONE | SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR);
#ifdef CONFIG_SDIO_DMA
if ((priv->caps & SDIO_CAPS_DMASUPPORTED) != 0)
{
ret = SDIO_DMARECVSETUP(priv->dev, buffer, 512);
if (ret != OK)
{
finfo("SDIO_DMARECVSETUP: error %d\n", ret);
return ret;
}
}
else
#endif
{
SDIO_RECVSETUP(priv->dev, buffer, 512);
}
/* Send CMD8 in data-transfer mode to obtain the
* extended Card Specific Data (CSD) register, e.g., block length, card storage
* capacity, etc.
*/
mmcsd_sendcmdpoll(priv, MMC_CMD8, 0);
ret = mmcsd_recvR1(priv, MMC_CMD8);
if (ret != OK)
{
ferr("ERROR: Could not get MMC extended CSD register: %d\n", ret);
return ret;
}
/* Then wait for the data transfer to complete */
ret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR,
MMCSD_BLOCK_RDATADELAY);
#ifdef CONFIG_SDIO_DMA
SDIO_DMADELYDINVLDT(priv->dev, buffer, 512);
#endif
if (ret != OK)
{
ferr("ERROR: CMD17 transfer failed: %d\n", ret);
return ret;
}
priv->nblocks = (buffer[215] << 24) | (buffer[214] << 16) |
(buffer[213] << 8) | buffer[212];
finfo("MMC ext CSD read succsesfully, number of block %d\n",
priv->nblocks);
/* Return value: One sector read */
return OK;
}
#endif #endif
/**************************************************************************** /****************************************************************************
@@ -2798,6 +3015,7 @@ static int mmcsd_cardidentify(FAR struct mmcsd_state_s *priv)
{ {
uint32_t response; uint32_t response;
uint32_t sdcapacity = MMCSD_ACMD41_STDCAPACITY; uint32_t sdcapacity = MMCSD_ACMD41_STDCAPACITY;
uint32_t mmccapacity = MMCSD_R3_HIGHCAPACITY;
clock_t start; clock_t start;
clock_t elapsed; clock_t elapsed;
int ret; int ret;
@@ -2832,6 +3050,65 @@ static int mmcsd_cardidentify(FAR struct mmcsd_state_s *priv)
mmcsd_sendcmdpoll(priv, MMCSD_CMD0, 0); mmcsd_sendcmdpoll(priv, MMCSD_CMD0, 0);
up_udelay(MMCSD_IDLE_DELAY); up_udelay(MMCSD_IDLE_DELAY);
#ifdef CONFIG_MMCSD_MMCSUPPORT
/* send CMD3 which is supported only by MMC.
* if there is valid response then the card
* is definetly of MMC type
*/
mmcsd_sendcmdpoll(priv, MMC_CMD1, MMCSD_VDD_33_34 | mmccapacity);
ret = SDIO_RECVR3(priv->dev, MMC_CMD1, &response);
/* Was the operating range set successfully */
if (ret != OK)
{
ferr("ERROR: CMD1 RECVR3: %d\n", ret);
}
else
{
/* CMD1 succeeded... this must be an MMC card */
finfo("MMC card detected\n");
priv->type = MMCSD_CARDTYPE_MMC;
/* Now, check if this is a MMC card/chip that supports block
* addressing
*/
if ((response & MMCSD_R3_HIGHCAPACITY) != 0)
{
finfo("MMC card/chip with block addressing\n");
mmccapacity = MMCSD_R3_HIGHCAPACITY;
priv->type |= MMCSD_CARDTYPE_BLOCK;
}
else
{
mmccapacity = MMCSD_R3_STDCAPACITY;
}
/* Check if the card is busy. Very confusing, BUSY is set LOW
* if the card has not finished its initialization, so it really
* means NOT busy.
*/
if ((response & MMCSD_CARD_BUSY) != 0)
{
/* NO.. We really should check the current state to see if the
* MMC successfully made it to the IDLE state, but at least for now,
* we will simply assume that that is the case.
*
* Then break out of the look with an MMC card identified
*/
finfo("MMC card/chip ready!\n");
return OK;
}
}
if (!IS_MMC(priv->type))
{
#endif
/* Check for SDHC Version 2.x. Send CMD8 to verify SD card interface /* Check for SDHC Version 2.x. Send CMD8 to verify SD card interface
* operating condition. CMD 8 is reserved on SD version 1.0 and MMC. * operating condition. CMD 8 is reserved on SD version 1.0 and MMC.
* *
@@ -2872,6 +3149,7 @@ static int mmcsd_cardidentify(FAR struct mmcsd_state_s *priv)
return -EIO; return -EIO;
} }
} }
}
/* At this point, type is either UNKNOWN or SDV2. Try sending /* At this point, type is either UNKNOWN or SDV2. Try sending
* CMD55 and (maybe) ACMD41 for up to 1 second or until the card * CMD55 and (maybe) ACMD41 for up to 1 second or until the card
@@ -2887,9 +3165,8 @@ static int mmcsd_cardidentify(FAR struct mmcsd_state_s *priv)
* an earlier pass through through this loop. In that case, we should * an earlier pass through through this loop. In that case, we should
* skip the SD-specific commands. * skip the SD-specific commands.
*/ */
#ifdef CONFIG_MMCSD_MMCSUPPORT #ifdef CONFIG_MMCSD_MMCSUPPORT
if (priv->type != MMCSD_CARDTYPE_MMC) if (!IS_MMC(priv->type))
#endif #endif
{ {
/* Send CMD55 with argument = 0 */ /* Send CMD55 with argument = 0 */
@@ -2973,7 +3250,7 @@ static int mmcsd_cardidentify(FAR struct mmcsd_state_s *priv)
*/ */
#ifdef CONFIG_MMCSD_MMCSUPPORT #ifdef CONFIG_MMCSD_MMCSUPPORT
if (priv->type == MMCSD_CARDTYPE_UNKNOWN || priv->type == MMCSD_CARDTYPE_MMC) if (IS_MMC(priv->type))
{ {
/* Send the MMC CMD1 to specify the operating voltage. CMD1 causes /* Send the MMC CMD1 to specify the operating voltage. CMD1 causes
* transition to ready state/ card-identification mode. NOTE: If the * transition to ready state/ card-identification mode. NOTE: If the
@@ -2988,7 +3265,7 @@ static int mmcsd_cardidentify(FAR struct mmcsd_state_s *priv)
* go back to the standby state). * go back to the standby state).
*/ */
mmcsd_sendcmdpoll(priv, MMC_CMD1, MMCSD_VDD_33_34); mmcsd_sendcmdpoll(priv, MMC_CMD1, MMCSD_VDD_33_34 | mmccapacity);
ret = SDIO_RECVR3(priv->dev, MMC_CMD1, &response); ret = SDIO_RECVR3(priv->dev, MMC_CMD1, &response);
/* Was the operating range set successfully */ /* Was the operating range set successfully */
@@ -3001,9 +3278,22 @@ static int mmcsd_cardidentify(FAR struct mmcsd_state_s *priv)
{ {
/* CMD1 succeeded... this must be an MMC card */ /* CMD1 succeeded... this must be an MMC card */
finfo("CMD1 succeeded, assuming MMC card\n");
priv->type = MMCSD_CARDTYPE_MMC; priv->type = MMCSD_CARDTYPE_MMC;
/* Now, check if this is a MMC card/chip that supports block
* addressing
*/
if ((response & MMCSD_R3_HIGHCAPACITY) != 0)
{
mmccapacity = MMCSD_R3_HIGHCAPACITY;
priv->type |= MMCSD_CARDTYPE_BLOCK;
}
else
{
mmccapacity = MMCSD_R3_STDCAPACITY;
}
/* Check if the card is busy. Very confusing, BUSY is set LOW /* Check if the card is busy. Very confusing, BUSY is set LOW
* if the card has not finished its initialization, so it really * if the card has not finished its initialization, so it really
* means NOT busy. * means NOT busy.
@@ -3018,6 +3308,7 @@ static int mmcsd_cardidentify(FAR struct mmcsd_state_s *priv)
* Then break out of the look with an MMC card identified * Then break out of the look with an MMC card identified
*/ */
finfo("MMC card/chip ready!\n");
break; break;
} }
} }
@@ -3101,18 +3392,34 @@ static int mmcsd_probe(FAR struct mmcsd_state_s *priv)
switch (priv->type) switch (priv->type)
{ {
case MMCSD_CARDTYPE_SDV1: /* Bit 1: SD version 1.x */ /* Bit 1: SD version 1.x */
case MMCSD_CARDTYPE_SDV2: /* SD version 2.x with byte addressing */
case MMCSD_CARDTYPE_SDV2 | MMCSD_CARDTYPE_BLOCK: /* SD version 2.x with block addressing */ case MMCSD_CARDTYPE_SDV1:
/* SD version 2.x with byte addressing */
case MMCSD_CARDTYPE_SDV2:
/* SD version 2.x with block addressing */
case MMCSD_CARDTYPE_SDV2 | MMCSD_CARDTYPE_BLOCK:
ret = mmcsd_sdinitialize(priv); ret = mmcsd_sdinitialize(priv);
break; break;
case MMCSD_CARDTYPE_MMC: /* MMC card */ /* MMC card with byte addressing */
case MMCSD_CARDTYPE_MMC:
/* MMC card with block addressing */
case MMCSD_CARDTYPE_MMC | MMCSD_CARDTYPE_BLOCK:
#ifdef CONFIG_MMCSD_MMCSUPPORT #ifdef CONFIG_MMCSD_MMCSUPPORT
ret = mmcsd_mmcinitialize(priv); ret = mmcsd_mmcinitialize(priv);
break; break;
#endif #endif
case MMCSD_CARDTYPE_UNKNOWN: /* Unknown card type */ /* Unknown card type */
case MMCSD_CARDTYPE_UNKNOWN:
default: default:
ferr("ERROR: Internal confusion: %d\n", priv->type); ferr("ERROR: Internal confusion: %d\n", priv->type);
ret = -EPERM; ret = -EPERM;
+2 -1
View File
@@ -1,7 +1,7 @@
/******************************************************************************************** /********************************************************************************************
* drivers/mmcsd/mmcsd_sdio.h * drivers/mmcsd/mmcsd_sdio.h
* *
* Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved. * Copyright (C) 2009, 2011, 2019 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org> * Author: Gregory Nutt <gnutt@nuttx.org>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@@ -150,6 +150,7 @@
#define MMCSD_VDD_35_36 ((uint32_t)1 << 23) /* VDD voltage 3.5-3.6 */ #define MMCSD_VDD_35_36 ((uint32_t)1 << 23) /* VDD voltage 3.5-3.6 */
#define MMCSD_R3_HIGHCAPACITY ((uint32_t)1 << 30) /* true: Card supports block addressing */ #define MMCSD_R3_HIGHCAPACITY ((uint32_t)1 << 30) /* true: Card supports block addressing */
#define MMCSD_CARD_BUSY ((uint32_t)1 << 31) /* Card power-up busy bit */ #define MMCSD_CARD_BUSY ((uint32_t)1 << 31) /* Card power-up busy bit */
#define MMCSD_R3_STDCAPACITY ((uint32_t)0)
/* R6 Card Status bit definitions */ /* R6 Card Status bit definitions */
+7 -4
View File
@@ -1,7 +1,8 @@
/**************************************************************************** /****************************************************************************
* include/nuttx/sdio.h * include/nuttx/sdio.h
* *
* Copyright (C) 2009, 2011-2013, 2017 Gregory Nutt. All rights reserved. * Copyright (C) 2009, 2011-2013, 2017, 2019 Gregory Nutt. All rights
* reserved.
* Author: Gregory Nutt <gnutt@nuttx.org> * Author: Gregory Nutt <gnutt@nuttx.org>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@@ -118,8 +119,9 @@
# define MMCSD_CMDIDX6 6 /* HS_SWITCH: Checks switchable function */ # define MMCSD_CMDIDX6 6 /* HS_SWITCH: Checks switchable function */
# define MMCSD_CMDIDX7 7 /* SELECT/DESELECT CARD # define MMCSD_CMDIDX7 7 /* SELECT/DESELECT CARD
* -Addressed Command, R1 response 31:16=RCA */ * -Addressed Command, R1 response 31:16=RCA */
# define SD_CMDIDX8 8 /* IF_COND: Sends SD Memory Card interface condition # define MMCSD_CMDIDX8 8 /* SD: IF_COND: Sends SD Memory Card interface condition
* R7 response */ * R7 response;
* MMC: get extended CSD register 512 bytes R1 response */
# define MMCSD_CMDIDX9 9 /* SEND_CSD: Asks card to send its card specific data (CSD) # define MMCSD_CMDIDX9 9 /* SEND_CSD: Asks card to send its card specific data (CSD)
* -Addressed Command, R2 response 31:16=RCA */ * -Addressed Command, R2 response 31:16=RCA */
# define MMCSD_CMDIDX10 10 /* SEND_CID: Asks card to send its card identification (CID) # define MMCSD_CMDIDX10 10 /* SEND_CID: Asks card to send its card identification (CID)
@@ -274,7 +276,8 @@
#define MMCSD_CMD6 (MMCSD_CMDIDX6 |MMCSD_R1_RESPONSE |MMCSD_RDDATAXFR) #define MMCSD_CMD6 (MMCSD_CMDIDX6 |MMCSD_R1_RESPONSE |MMCSD_RDDATAXFR)
#define MMCSD_CMD7S (MMCSD_CMDIDX7 |MMCSD_R1B_RESPONSE|MMCSD_NODATAXFR) #define MMCSD_CMD7S (MMCSD_CMDIDX7 |MMCSD_R1B_RESPONSE|MMCSD_NODATAXFR)
#define MMCSD_CMD7D (MMCSD_CMDIDX7 |MMCSD_NO_RESPONSE |MMCSD_NODATAXFR) /* No response when de-selecting card */ #define MMCSD_CMD7D (MMCSD_CMDIDX7 |MMCSD_NO_RESPONSE |MMCSD_NODATAXFR) /* No response when de-selecting card */
#define SD_CMD8 (SD_CMDIDX8 |MMCSD_R7_RESPONSE |MMCSD_NODATAXFR) #define SD_CMD8 (MMCSD_CMDIDX8 |MMCSD_R7_RESPONSE |MMCSD_NODATAXFR)
#define MMC_CMD8 (MMCSD_CMDIDX8 |MMCSD_R1_RESPONSE |MMCSD_RDDATAXFR)
#define MMCSD_CMD9 (MMCSD_CMDIDX9 |MMCSD_R2_RESPONSE |MMCSD_NODATAXFR) #define MMCSD_CMD9 (MMCSD_CMDIDX9 |MMCSD_R2_RESPONSE |MMCSD_NODATAXFR)
#define MMCSD_CMD10 (MMCSD_CMDIDX10|MMCSD_R2_RESPONSE |MMCSD_NODATAXFR) #define MMCSD_CMD10 (MMCSD_CMDIDX10|MMCSD_R2_RESPONSE |MMCSD_NODATAXFR)
#define MMC_CMD11 (MMC_CMDIDX11 |MMCSD_R1_RESPONSE |MMCSD_RDSTREAM ) #define MMC_CMD11 (MMC_CMDIDX11 |MMCSD_R1_RESPONSE |MMCSD_RDSTREAM )