Correct identifies v1.x SD card
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2273 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
081d8a6abc
commit
8c8b5f01b7
@ -111,7 +111,7 @@
|
||||
/* 0x40014000 - 0x40017fff: Reserved */
|
||||
/* AHB bus */
|
||||
|
||||
#define STM32_SDIO_BASE 0x40020000 /* 0x40018000 - 0x400183ff: SDIO */
|
||||
#define STM32_SDIO_BASE 0x40018000 /* 0x40018000 - 0x400183ff: SDIO */
|
||||
/* 0x40018400 - 0x40017fff: Reserved */
|
||||
#define STM32_DMA1_BASE 0x40020000 /* 0x40020000 - 0x400203ff: DMA1 */
|
||||
#define STM32_DMA2_BASE 0x40020400 /* 0x40020000 - 0x400207ff: DMA2 */
|
||||
|
@ -148,19 +148,16 @@
|
||||
/* Event waiting interrupt mask bits */
|
||||
|
||||
#define SDIO_CMDDONE_STA (SDIO_STA_CMDSENT)
|
||||
#define SDIO_CRCRESP_STA (SDIO_STA_CTIMEOUT|SDIO_STA_CCRCFAIL|SDIO_STA_CMDREND)
|
||||
#define SDIO_RESPDONE_STA (SDIO_STA_CTIMEOUT|SDIO_STA_CMDREND)
|
||||
#define SDIO_RESPDONE_STA (SDIO_STA_CTIMEOUT|SDIO_STA_CCRCFAIL|SDIO_STA_CMDREND)
|
||||
#define SDIO_XFRDONE_STA (0)
|
||||
|
||||
#define SDIO_CMDDONE_MASK (SDIO_MASK_CMDSENTIE)
|
||||
#define SDIO_CRCRESP_MASK (SDIO_MASK_CCRCFAILIE|SDIO_MASK_CTIMEOUTIE|\
|
||||
#define SDIO_RESPDONE_MASK (SDIO_MASK_CCRCFAILIE|SDIO_MASK_CTIMEOUTIE|\
|
||||
SDIO_MASK_CMDRENDIE)
|
||||
#define SDIO_RESPDONE_MASK (SDIO_MASK_CTIMEOUTIE|SDIO_MASK_CMDRENDIE)
|
||||
#define SDIO_XFRDONE_MASK (0)
|
||||
|
||||
#define SDIO_CMDDONE_ICR (SDIO_ICR_CMDSENTC)
|
||||
#define SDIO_CRCRESP_ICR (SDIO_ICR_CTIMEOUTC|SDIO_ICR_CCRCFAILC|SDIO_ICR_CMDRENDC)
|
||||
#define SDIO_RESPDONE_ICR (SDIO_ICR_CTIMEOUTC|SDIO_ICR_CMDRENDC)
|
||||
#define SDIO_RESPDONE_ICR (SDIO_ICR_CTIMEOUTC|SDIO_ICR_CCRCFAILC|SDIO_ICR_CMDRENDC)
|
||||
#define SDIO_XFRDONE_ICR (0)
|
||||
|
||||
#define SDIO_WAITALL_ICR (SDIO_ICR_CMDSENTC|SDIO_ICR_CTIMEOUTC|\
|
||||
@ -406,6 +403,7 @@ static inline void stm32_setclkcr(uint32 clkcr)
|
||||
SDIO_CLKCR_WIDBUS_MASK|SDIO_CLKCR_NEGEDGE|SDIO_CLKCR_HWFC_EN);
|
||||
regval |= clkcr;
|
||||
putreg32(regval, STM32_SDIO_CLKCR);
|
||||
fvdbg("CLKCR: %08x\n", getreg32(STM32_SDIO_CLKCR));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -995,7 +993,7 @@ static int stm32_interrupt(int irq, void *context)
|
||||
{
|
||||
/* Is this a response completion event? */
|
||||
|
||||
if ((pending & SDIO_CRCRESP_STA) != 0)
|
||||
if ((pending & SDIO_RESPDONE_STA) != 0)
|
||||
{
|
||||
/* Yes.. Is their a thread waiting for response done? */
|
||||
|
||||
@ -1003,7 +1001,7 @@ static int stm32_interrupt(int irq, void *context)
|
||||
{
|
||||
/* Yes.. wake the thread up */
|
||||
|
||||
putreg32(SDIO_CRCRESP_ICR, STM32_SDIO_ICR);
|
||||
putreg32(SDIO_RESPDONE_ICR|SDIO_CMDDONE_ICR, STM32_SDIO_ICR);
|
||||
stm32_endwait(priv, SDIOWAIT_RESPONSEDONE);
|
||||
}
|
||||
}
|
||||
@ -1089,6 +1087,8 @@ static void stm32_reset(FAR struct sdio_dev_s *dev)
|
||||
/* (Re-)enable clocking */
|
||||
|
||||
putreg32(1, SDIO_CLKCR_CLKEN_BB);
|
||||
fvdbg("CLCKR: %08x POWER: %08x\n",
|
||||
getreg32(STM32_SDIO_CLKCR), getreg32(STM32_SDIO_POWER));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -1261,7 +1261,7 @@ static void stm32_sendcmd(FAR struct sdio_dev_s *dev, uint32 cmd, uint32 arg)
|
||||
|
||||
/* Set WAITRESP bits */
|
||||
|
||||
switch ((cmd & MMCSD_RESPONSE_MASK) >> MMCSD_RESPONSE_SHIFT)
|
||||
switch (cmd & MMCSD_RESPONSE_MASK)
|
||||
{
|
||||
case MMCSD_NO_RESPONSE:
|
||||
regval |= SDIO_CMD_NORESPONSE;
|
||||
@ -1289,7 +1289,10 @@ static void stm32_sendcmd(FAR struct sdio_dev_s *dev, uint32 cmd, uint32 arg)
|
||||
|
||||
/* Write the SDIO CMD */
|
||||
|
||||
putreg32(SDIO_RESPDONE_ICR|SDIO_CMDDONE_ICR, STM32_SDIO_ICR);
|
||||
putreg32(regval, STM32_SDIO_CMD);
|
||||
fvdbg("cmd: %08x arg: %08x regval: %08x\n",
|
||||
cmd, arg, getreg32(STM32_SDIO_CMD));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -1429,7 +1432,7 @@ static int stm32_waitresponse(FAR struct sdio_dev_s *dev, uint32 cmd)
|
||||
case MMCSD_R1B_RESPONSE:
|
||||
case MMCSD_R2_RESPONSE:
|
||||
case MMCSD_R6_RESPONSE:
|
||||
events = SDIO_CRCRESP_STA;
|
||||
events = SDIO_RESPDONE_STA;
|
||||
timeout = SDIO_LONGTIMEOUT;
|
||||
break;
|
||||
|
||||
@ -1453,14 +1456,14 @@ static int stm32_waitresponse(FAR struct sdio_dev_s *dev, uint32 cmd)
|
||||
{
|
||||
if (--timeout <= 0)
|
||||
{
|
||||
fdbg("ERROR: Timeout cmd=%04x\n", cmd);
|
||||
fdbg("ERROR: Timeout cmd: %08x events: %08x STA: %08x\n",
|
||||
cmd, events, getreg32(STM32_SDIO_STA));
|
||||
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear all the static flags */
|
||||
|
||||
putreg32(SDIO_ICR_STATICFLAGS, STM32_SDIO_ICR);
|
||||
putreg32(SDIO_CMDDONE_ICR, STM32_SDIO_ICR);
|
||||
return OK;
|
||||
}
|
||||
|
||||
@ -1492,6 +1495,7 @@ static int stm32_recvshortcrc(FAR struct sdio_dev_s *dev, uint32 cmd, uint32 *rs
|
||||
uint32 respcmd;
|
||||
#endif
|
||||
uint32 regval;
|
||||
int ret = OK;
|
||||
|
||||
/* R1 Command response (48-bit)
|
||||
* 47 0 Start bit
|
||||
@ -1520,62 +1524,60 @@ static int stm32_recvshortcrc(FAR struct sdio_dev_s *dev, uint32 cmd, uint32 *rs
|
||||
if (!rshort)
|
||||
{
|
||||
fdbg("ERROR: rshort=NULL\n");
|
||||
return -EINVAL;
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
/* Check that this is the correct response to this command */
|
||||
|
||||
if ((cmd & MMCSD_RESPONSE_MASK) != MMCSD_R1_RESPONSE &&
|
||||
(cmd & MMCSD_RESPONSE_MASK) != MMCSD_R1B_RESPONSE &&
|
||||
(cmd & MMCSD_RESPONSE_MASK) != MMCSD_R6_RESPONSE)
|
||||
else if ((cmd & MMCSD_RESPONSE_MASK) != MMCSD_R1_RESPONSE &&
|
||||
(cmd & MMCSD_RESPONSE_MASK) != MMCSD_R1B_RESPONSE &&
|
||||
(cmd & MMCSD_RESPONSE_MASK) != MMCSD_R6_RESPONSE)
|
||||
{
|
||||
fdbg("ERROR: Wrong response CMD=%08x\n", cmd);
|
||||
return -EINVAL;
|
||||
ret = -EINVAL;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
/* Verify that the response is available */
|
||||
|
||||
regval = getreg32(STM32_SDIO_STA);
|
||||
if ((regval & SDIO_STA_CTIMEOUT) != 0)
|
||||
{
|
||||
fdbg("ERROR: Command timeout: %08x\n", regval);
|
||||
putreg32(SDIO_ICR_CTIMEOUTC, STM32_SDIO_ICR);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
else if ((regval & SDIO_STA_CCRCFAIL) != 0)
|
||||
{
|
||||
fdbg("ERROR: CRC failuret: %08x\n", regval);
|
||||
putreg32(SDIO_ICR_CCRCFAILC, STM32_SDIO_ICR);
|
||||
return -EIO;
|
||||
}
|
||||
else if ((regval & SDIO_STA_CMDREND) == 0)
|
||||
{
|
||||
fdbg("ERROR: Status is not yet available: %08x\n", regval);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
/* Check response received is of desired command */
|
||||
/* Check if a timeout or CRC error occurred */
|
||||
|
||||
regval = getreg32(STM32_SDIO_STA);
|
||||
if ((regval & SDIO_STA_CTIMEOUT) != 0)
|
||||
{
|
||||
fdbg("ERROR: Command timeout: %08x\n", regval);
|
||||
ret = -ETIMEDOUT;
|
||||
}
|
||||
else if ((regval & SDIO_STA_CCRCFAIL) != 0)
|
||||
{
|
||||
fdbg("ERROR: CRC failuret: %08x\n", regval);
|
||||
ret = -EIO;
|
||||
}
|
||||
#ifdef CONFIG_DEBUG
|
||||
respcmd = getreg32(STM32_SDIO_RESPCMD);
|
||||
if ((ubyte)(respcmd & SDIO_RESPCMD_MASK) != (cmd & MMCSD_CMDIDX_MASK))
|
||||
{
|
||||
fdbg("ERROR: RESCMD=%02x CMD=%08x\n", respcmd, cmd);
|
||||
return -EINVAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check response received is of desired command */
|
||||
|
||||
respcmd = getreg32(STM32_SDIO_RESPCMD);
|
||||
if ((ubyte)(respcmd & SDIO_RESPCMD_MASK) != (cmd & MMCSD_CMDIDX_MASK))
|
||||
{
|
||||
fdbg("ERROR: RESCMD=%02x CMD=%08x\n", respcmd, cmd);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Return the R1 response */
|
||||
/* Clear all pending message completion events and return the R1/R6 response */
|
||||
|
||||
putreg32(SDIO_ICR_STATICFLAGS, STM32_SDIO_ICR);
|
||||
putreg32(SDIO_RESPDONE_ICR|SDIO_CMDDONE_ICR, STM32_SDIO_ICR);
|
||||
*rshort = getreg32(STM32_SDIO_RESP1);
|
||||
return OK;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int stm32_recvlong(FAR struct sdio_dev_s *dev, uint32 cmd, uint32 rlong[4])
|
||||
{
|
||||
uint32 regval;
|
||||
int ret = OK;
|
||||
|
||||
/* R2 CID, CSD register (136-bit)
|
||||
* 135 0 Start bit
|
||||
@ -1592,32 +1594,29 @@ static int stm32_recvlong(FAR struct sdio_dev_s *dev, uint32 cmd, uint32 rlong[4
|
||||
if ((cmd & MMCSD_RESPONSE_MASK) != MMCSD_R2_RESPONSE)
|
||||
{
|
||||
fdbg("ERROR: Wrong response CMD=%08x\n", cmd);
|
||||
return -EINVAL;
|
||||
ret = -EINVAL;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* Check if a timeout or CRC error occurred */
|
||||
|
||||
/* Verify that the response is available */
|
||||
|
||||
regval = getreg32(STM32_SDIO_STA);
|
||||
if (regval & SDIO_STA_CTIMEOUT)
|
||||
{
|
||||
putreg32(SDIO_ICR_CTIMEOUTC, STM32_SDIO_ICR);
|
||||
return -ETIMEDOUT;
|
||||
regval = getreg32(STM32_SDIO_STA);
|
||||
if (regval & SDIO_STA_CTIMEOUT)
|
||||
{
|
||||
fdbg("ERROR: Timeout STA: %08x\n", regval);
|
||||
ret = -ETIMEDOUT;
|
||||
}
|
||||
else if (regval & SDIO_STA_CCRCFAIL)
|
||||
{
|
||||
fdbg("ERROR: CRC fail STA: %08x\n", regval);
|
||||
ret = -EIO;
|
||||
}
|
||||
}
|
||||
else if (regval & SDIO_STA_CCRCFAIL)
|
||||
{
|
||||
putreg32(SDIO_ICR_CCRCFAILC, STM32_SDIO_ICR);
|
||||
return -EIO;
|
||||
}
|
||||
else if ((regval & SDIO_STA_CMDREND) == 0)
|
||||
{
|
||||
fdbg("ERROR: Status is not yet available: %08x\n", regval);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
|
||||
/* Return the long response */
|
||||
|
||||
putreg32(SDIO_ICR_STATICFLAGS, STM32_SDIO_ICR);
|
||||
putreg32(SDIO_RESPDONE_ICR|SDIO_CMDDONE_ICR, STM32_SDIO_ICR);
|
||||
if (rlong)
|
||||
{
|
||||
rlong[0] = getreg32(STM32_SDIO_RESP1);
|
||||
@ -1625,12 +1624,13 @@ static int stm32_recvlong(FAR struct sdio_dev_s *dev, uint32 cmd, uint32 rlong[4
|
||||
rlong[2] = getreg32(STM32_SDIO_RESP3);
|
||||
rlong[3] = getreg32(STM32_SDIO_RESP4);
|
||||
}
|
||||
return OK;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int stm32_recvshort(FAR struct sdio_dev_s *dev, uint32 cmd, uint32 *rshort)
|
||||
{
|
||||
uint32 regval;
|
||||
int ret = OK;
|
||||
|
||||
/* R3 OCR (48-bit)
|
||||
* 47 0 Start bit
|
||||
@ -1648,36 +1648,38 @@ static int stm32_recvshort(FAR struct sdio_dev_s *dev, uint32 cmd, uint32 *rshor
|
||||
(cmd & MMCSD_RESPONSE_MASK) != MMCSD_R7_RESPONSE)
|
||||
{
|
||||
fdbg("ERROR: Wrong response CMD=%08x\n", cmd);
|
||||
return -EINVAL;
|
||||
ret = -EINVAL;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* Check if a timeout occurred (Apparently a CRC error can terminate
|
||||
* a good response)
|
||||
*/
|
||||
|
||||
regval = getreg32(STM32_SDIO_STA);
|
||||
if (regval & SDIO_STA_CTIMEOUT)
|
||||
{
|
||||
putreg32(SDIO_ICR_CTIMEOUTC, STM32_SDIO_ICR);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
else if ((regval & SDIO_STA_CMDREND) == 0)
|
||||
{
|
||||
fdbg("ERROR: Status is not yet available: %08x\n", regval);
|
||||
return -EBUSY;
|
||||
regval = getreg32(STM32_SDIO_STA);
|
||||
if (regval & SDIO_STA_CTIMEOUT)
|
||||
{
|
||||
fdbg("ERROR: Timeout STA: %08x\n", regval);
|
||||
ret = -ETIMEDOUT;
|
||||
}
|
||||
|
||||
/* Return the short response */
|
||||
}
|
||||
|
||||
/* Return the short response */
|
||||
|
||||
putreg32(SDIO_ICR_STATICFLAGS, STM32_SDIO_ICR);
|
||||
putreg32(SDIO_RESPDONE_ICR|SDIO_CMDDONE_ICR, STM32_SDIO_ICR);
|
||||
if (rshort)
|
||||
{
|
||||
*rshort = getreg32(STM32_SDIO_RESP1);
|
||||
}
|
||||
return OK;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* MMC responses not supported */
|
||||
|
||||
static int stm32_recvnotimpl(FAR struct sdio_dev_s *dev, uint32 cmd, uint32 *rnotimpl)
|
||||
{
|
||||
putreg32(SDIO_RESPDONE_ICR|SDIO_CMDDONE_ICR, STM32_SDIO_ICR);
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
@ -1729,7 +1731,7 @@ static void stm32_waitenable(FAR struct sdio_dev_s *dev,
|
||||
|
||||
if ((eventset & SDIOWAIT_RESPONSEDONE) != 0)
|
||||
{
|
||||
waitmask |= SDIO_CRCRESP_MASK;
|
||||
waitmask |= SDIO_RESPDONE_MASK;
|
||||
}
|
||||
|
||||
if ((eventset & SDIOWAIT_TRANSFERDONE) != 0)
|
||||
|
@ -84,12 +84,6 @@
|
||||
|
||||
#define IS_EMPTY(priv) (priv->type == MMCSD_CARDTYPE_UNKNOWN)
|
||||
|
||||
/* Transfer mode */
|
||||
|
||||
#define MMCSDMODE_POLLED 0
|
||||
#define MMCSDMODE_INTERRUPT 1
|
||||
#define MMCSDMODE_DMA 2
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
@ -355,6 +349,7 @@ static int mmcsd_recvR1(FAR struct mmcsd_state_s *priv, uint32 cmd)
|
||||
* indication for later use.
|
||||
*/
|
||||
|
||||
fvdbg("ERROR: R1=%08x\n", r1);
|
||||
priv->locked = ((r1 & MMCSD_R1_CARDISLOCKED) != 0);
|
||||
ret = -EIO;
|
||||
}
|
||||
@ -2298,7 +2293,6 @@ static int mmcsd_cardidentify(FAR struct mmcsd_state_s *priv)
|
||||
/* Assume failure to identify the card */
|
||||
|
||||
priv->type = MMCSD_CARDTYPE_UNKNOWN;
|
||||
priv->mode = MMCSDMODE_POLLED;
|
||||
|
||||
/* Check if there is a card present in the slot. This is normally a matter is
|
||||
* of GPIO sensing.
|
||||
@ -2310,11 +2304,6 @@ static int mmcsd_cardidentify(FAR struct mmcsd_state_s *priv)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Initialize device state structure */
|
||||
|
||||
priv->type = MMCSD_CARDTYPE_SDV1;
|
||||
priv->mode = MMCSDMODE_POLLED;
|
||||
|
||||
/* Set ID mode clocking (<400KHz) */
|
||||
|
||||
SDIO_CLOCK(priv->dev, CLOCK_IDMODE);
|
||||
@ -2381,7 +2370,7 @@ static int mmcsd_cardidentify(FAR struct mmcsd_state_s *priv)
|
||||
if (priv->type != MMCSD_CARDTYPE_MMC)
|
||||
#endif
|
||||
{
|
||||
/* Send CMD55 */
|
||||
/* Send CMD55 with argument = 0 */
|
||||
|
||||
mmcsd_sendcmdpoll(priv, SD_CMD55, 0);
|
||||
ret = mmcsd_recvR1(priv, SD_CMD55);
|
||||
@ -2399,7 +2388,7 @@ static int mmcsd_cardidentify(FAR struct mmcsd_state_s *priv)
|
||||
/* Send ACMD41 */
|
||||
|
||||
mmcsd_sendcmdpoll(priv, SD_ACMD41, MMCSD_ACMD41_VOLTAGEWINDOW|sdcapacity);
|
||||
ret = SDIO_RECVR3(priv->dev, SD_CMD55, &response);
|
||||
ret = SDIO_RECVR3(priv->dev, SD_ACMD41, &response);
|
||||
if (ret != OK)
|
||||
{
|
||||
/* If the error is a timeout, then it is probably an MMC card,
|
||||
@ -2582,7 +2571,7 @@ static int mmcsd_probe(FAR struct mmcsd_state_s *priv)
|
||||
ret = mmcsd_cardidentify(priv);
|
||||
if (ret != OK)
|
||||
{
|
||||
fdbg("ERROR: Failed to initialize card: %d\n");
|
||||
fdbg("ERROR: Failed to initialize card: %d\n", ret);
|
||||
SDIO_CALLBACKENABLE(priv->dev, SDIOMEDIA_INSERTED);
|
||||
}
|
||||
else
|
||||
|
Loading…
Reference in New Issue
Block a user