From 15e7af4e974982d0ccfd8ca2ba8d95335b523464 Mon Sep 17 00:00:00 2001 From: patacongo Date: Fri, 13 Nov 2009 23:30:41 +0000 Subject: [PATCH] Add IOCTLs and card identification logic git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2253 42af7a65-404d-4744-a932-0658087f49c3 --- arch/arm/src/stm32/stm32_sdio.c | 80 +++++++++++++++++++++++++++++++-- 1 file changed, 76 insertions(+), 4 deletions(-) diff --git a/arch/arm/src/stm32/stm32_sdio.c b/arch/arm/src/stm32/stm32_sdio.c index edcd2bdffc6..102127e57d3 100644 --- a/arch/arm/src/stm32/stm32_sdio.c +++ b/arch/arm/src/stm32/stm32_sdio.c @@ -81,7 +81,12 @@ #define STM32_CLCKCR_TRANSFER \ (SDIO_TRANSFER_CLKDIV|SDIO_CLKCR_RISINGEDGE|SDIO_CLKCR_WIDBUS_D1) #define STM32_CLKCR_WIDETRANSFER \ - (SDIO_TRANSFER_CLKDIV|SDIO_CLKCR_RISINGEDGE|SDIO_CLKCR_WIDBUS_D4) + (SDIO_TRANSFER_CLKDIV|SDIO_CLKCR_RISINGEDGE|SDIO_CLKCR_WIDBUS_D4) + +/* Timing */ + +#define SDIO_CMDTIMEOUT 100000 +#define SDIO_LONGTIMEOUT 0x7fffffff /**************************************************************************** * Private Types @@ -139,7 +144,8 @@ static int stm32_attach(FAR struct sdio_dev_s *dev); static void stm32_sendcmd(FAR struct sdio_dev_s *dev, uint32 cmd, uint32 arg); static int stm32_senddata(FAR struct sdio_dev_s *dev, FAR const ubyte *buffer); - + +static int stm32_waitresponseFAR struct sdio_dev_s *dev, uint32 cmd); static int stm32_recvshortcrc(FAR struct sdio_dev_s *dev, uint32 cmd, uint32 *rshort); static int stm32_recvlong(FAR struct sdio_dev_s *dev, uint32 cmd, uint32 rlong[4]); static int stm32_recvshort(FAR struct sdio_dev_s *dev, uint32 cmd, uint32 *rshort); @@ -191,7 +197,8 @@ struct stm32_dev_s g_mmcsd = .setblocklen = stm32_setblocklen, .attach = stm32_attach, .sendcmd = stm32_sendcmd, - .senddata = stm32_senddata, + .senddata = stm32_senddata, + .waitresponse = stm32_waitresponse, .recvR1 = stm32_recvshortcrc, .recvR2 = stm32_recvlong, .recvR3 = stm32_recvshort, @@ -629,6 +636,71 @@ static int stm32_senddata(FAR struct sdio_dev_s *dev, FAR const ubyte *buffer) return -ENOSYS; } +/**************************************************************************** + * Name: stm32_waitresponse + * + * Description: + * Poll-wait for the response to the last command to be ready. + * + * Input Parameters: + * dev - An instance of the MMC/SD device interface + * cmd - The command that was sent. See 32-bit command definitions above. + * + * Returned Value: + * OK is success; a negated errno on failure + * + ****************************************************************************/ + +static int stm32_waitresponseFAR struct sdio_dev_s *dev, uint32 cmd) +{ + sint32 timeout = SDIO_LONGTIMEOUT; + uint32 events; + + switch (cmd & MMCSD_RESPONSE_MASK) + { + case MMCSD_NO_RESPONSE: + timeout = SDIO_CMDTIMEOUT; + events = SDIO_STA_CMDSENT; + break; + + case MMCSD_R1_RESPONSE: + case MMCSD_R1B_RESPONSE: + case MMCSD_R2_RESPONSE: + case MMCSD_R6_RESPONSE: + events = SDIO_STA_CTIMEOUT|SDIO_STA_CCRCFAIL|SDIO_STA_CMDREND; + break; + + case MMCSD_R4_RESPONSE: + case MMCSD_R5_RESPONSE: + return -ENOSYS; + + case MMCSD_R3_RESPONSE: + case MMCSD_R7_RESPONSE: + events = SDIO_STA_CTIMEOUT|SDIO_STA_CMDREND; + timeout = SDIO_CMDTIMEOUT; + break; + + default: + return -EINVAL; + } + + /* Then wait for the response (or timeout) */ + + while ((getreg32(STM32_SDIO_STA) & events) == 0) + { + if (--timeout <= 0) + { + fdbg("ERROR: Timeout cmd=%04x\n", cmd); + return -ETIMEDOUT; + } + } + + /* Clear all the static flags */ + + putreg32(SDIO_ICR_STATICFLAGS, STM32_SDIO_ICR); + return OK; +} + /**************************************************************************** * Name: stm32_recvRx * @@ -817,7 +889,7 @@ static int stm32_recvshort(FAR struct sdio_dev_s *dev, uint32 cmd, uint32 *rshor } #endif - regval = getreg32(STM32_SDIO_STA); + regval = getreg32(STM32_SDIO_STA); if (regval & SDIO_STA_CTIMEOUT) { putreg32(SDIO_ICR_CTIMEOUTC, STM32_SDIO_ICR);