mirror of
https://github.com/apache/nuttx.git
synced 2026-06-06 08:36:24 +08:00
Code complete for STM32 SDIO driver and MMC/SD SDIO driver
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2266 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
@@ -414,7 +414,7 @@ void stm32_dmasetup(DMA_HANDLE handle, uint32 paddr, uint32 maddr, size_t ntrans
|
||||
* half and/or full transfer in the DMA_CCRx register.
|
||||
*/
|
||||
|
||||
regval = dmachan_gettreg(dmach, STM32_DMACHAN_CCR_OFFSET);
|
||||
regval = dmachan_getreg(dmach, STM32_DMACHAN_CCR_OFFSET);
|
||||
regval &= ~(DMA_CCR_MEM2MEM|DMA_CCR_PL_MASK|DMA_CCR_MSIZE_MASK|DMA_CCR_PSIZE_MASK|
|
||||
DMA_CCR_MINC|DMA_CCR_PINC|DMA_CCR_CIRC|DMA_CCR_DIR);
|
||||
ccr &= (DMA_CCR_MEM2MEM|DMA_CCR_PL_MASK|DMA_CCR_MSIZE_MASK|DMA_CCR_PSIZE_MASK|
|
||||
@@ -453,7 +453,7 @@ void stm32_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg, boole
|
||||
* peripheral connected on the channel.
|
||||
*/
|
||||
|
||||
ccr = dmachan_gettreg(dmach, STM32_DMACHAN_CCR_OFFSET);
|
||||
ccr = dmachan_getreg(dmach, STM32_DMACHAN_CCR_OFFSET);
|
||||
ccr |= DMA_CCR_EN;
|
||||
|
||||
/* Once half of the bytes are transferred, the half-transfer flag (HTIF) is
|
||||
|
||||
@@ -445,6 +445,62 @@ EXTERN int stm32_usbpullup(FAR struct usbdev_s *dev, boolean enable);
|
||||
struct usbdev_s;
|
||||
EXTERN void stm32_usbsuspend(FAR struct usbdev_s *dev, boolean resume);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sdio_initialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize SDIO for operation.
|
||||
*
|
||||
* Input Parameters:
|
||||
* slotno - Not used.
|
||||
*
|
||||
* Returned Values:
|
||||
* A reference to an SDIO interface structure. NULL is returned on failures.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
struct sdio_dev_s; /* See include/nuttx/sdio.h */
|
||||
EXTERN FAR struct sdio_dev_s *sdio_initialize(int slotno);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sdio_mediachange
|
||||
*
|
||||
* Description:
|
||||
* Called by board-specific logic -- posssible from an interrupt handler --
|
||||
* in order to signal to the driver that a card has been inserted or
|
||||
* removed from the slot
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - An instance of the SDIO driver device state structure.
|
||||
* cardinslot - TRUE is a card has been detected in the slot; FALSE if a
|
||||
* card has been removed from the slot. Only transitions
|
||||
* (inserted->removed or removed->inserted should be reported)
|
||||
*
|
||||
* Returned Values:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
EXTERN void sdio_mediachange(FAR struct sdio_dev_s *dev, boolean cardinslot);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sdio_wrprotect
|
||||
*
|
||||
* Description:
|
||||
* Called by board-specific logic to report if the card in the slot is
|
||||
* mechanically write protected.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - An instance of the SDIO driver device state structure.
|
||||
* wrprotect - TRUE is a card is writeprotected.
|
||||
*
|
||||
* Returned Values:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
EXTERN void sdio_wrprotect(FAR struct sdio_dev_s *dev, boolean wrprotect);
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
|
||||
+285
-80
File diff suppressed because it is too large
Load Diff
@@ -49,7 +49,13 @@
|
||||
# include <nuttx/spi.h>
|
||||
# include <nuttx/mtd.h>
|
||||
#endif
|
||||
#include <nuttx/mmcsd.h>
|
||||
|
||||
#ifdef CONFIG_STM32_SDIO
|
||||
# include <nuttx/sdio.h>
|
||||
# include <nuttx/mmcsd.h>
|
||||
#endif
|
||||
|
||||
#include "stm32_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-Processor Definitions
|
||||
@@ -63,20 +69,35 @@
|
||||
|
||||
/* PORT and SLOT number probably depend on the board configuration */
|
||||
|
||||
#ifdef CONFIG_ARCH_BOARD_STM3210E_EVAL
|
||||
# define CONFIG_EXAMPLES_NSH_HAVEUSBDEV 1
|
||||
# define CONFIG_EXAMPLES_NSH_HAVEMMCSD 1
|
||||
# if defined(CONFIG_EXAMPLES_NSH_MMCSDSLOTNO) && CONFIG_EXAMPLES_NSH_MMCSDSLOTNO != 0
|
||||
# error "Only one MMC/SD slot"
|
||||
# undef CONFIG_EXAMPLES_NSH_MMCSDSLOTNO
|
||||
# endif
|
||||
# ifndef CONFIG_EXAMPLES_NSH_MMCSDSLOTNO
|
||||
# define CONFIG_EXAMPLES_NSH_MMCSDSLOTNO 0
|
||||
# endif
|
||||
#else
|
||||
/* Add configuration for new STM32 boards here */
|
||||
# error "Unrecognized STM32 board"
|
||||
# undef CONFIG_EXAMPLES_NSH_HAVEUSBDEV
|
||||
# undef CONFIG_EXAMPLES_NSH_HAVEMMCSD
|
||||
#endif
|
||||
|
||||
/* Can't support USB features if USB is not enabled */
|
||||
|
||||
#ifndef CONFIG_USBDEV
|
||||
# undef CONFIG_EXAMPLES_NSH_HAVEUSBDEV
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_EXAMPLES_NSH_MMCSDSLOTNO) && CONFIG_EXAMPLES_NSH_MMCSDSLOTNO != 0
|
||||
# error "Only one MMC/SD slot"
|
||||
# undef CONFIG_EXAMPLES_NSH_MMCSDSLOTNO
|
||||
#endif
|
||||
/* Can't support MMC/SD features if mountpoints are disabled or if SDIO support
|
||||
* is not enabled.
|
||||
*/
|
||||
|
||||
/* Can't support MMC/SD features if mountpoints are disabled */
|
||||
|
||||
#if defined(CONFIG_DISABLE_MOUNTPOINT)
|
||||
#if defined(CONFIG_DISABLE_MOUNTPOINT) || !defined(CONFIG_STM32_SDIO)
|
||||
#error OUCH
|
||||
# undef CONFIG_EXAMPLES_NSH_HAVEMMCSD
|
||||
#endif
|
||||
|
||||
@@ -118,6 +139,10 @@ int nsh_archinitialize(void)
|
||||
FAR struct spi_dev_s *spi;
|
||||
FAR struct mtd_dev_s *mtd;
|
||||
#endif
|
||||
#ifdef CONFIG_EXAMPLES_NSH_HAVEMMCSD
|
||||
FAR struct sdio_dev_s *sdio;
|
||||
int ret;
|
||||
#endif
|
||||
|
||||
/* Configure SPI-based devices */
|
||||
|
||||
@@ -147,13 +172,36 @@ int nsh_archinitialize(void)
|
||||
#endif
|
||||
|
||||
/* Create the SPI FLASH MTD instance */
|
||||
|
||||
/* Here we will eventually need to
|
||||
* 1. Get the SDIO interface instance, and
|
||||
* 2. Bind it to the MMC/SD driver (slot CONFIG_EXAMPLES_NSH_MMCSDSLOTNO,
|
||||
* CONFIG_EXAMPLES_NSH_MMCSDMINOR).
|
||||
/* The M25Pxx is not a give media to implement a file system..
|
||||
* its block sizes are too large
|
||||
*/
|
||||
|
||||
#warning "Missing MMC/SD device configuration"
|
||||
/* Mount the SDIO-based MMC/SD block driver */
|
||||
|
||||
#ifdef CONFIG_EXAMPLES_NSH_HAVEMMCSD
|
||||
/* First, get an instance of the SDIO interface */
|
||||
|
||||
message("nsh_archinitialize: Initializing SDIO slot %d\n",
|
||||
CONFIG_EXAMPLES_NSH_MMCSDSLOTNO);
|
||||
sdio = sdio_initialize(CONFIG_EXAMPLES_NSH_MMCSDSLOTNO);
|
||||
if (!sdio)
|
||||
{
|
||||
message("nsh_archinitialize: Failed to initialize SDIO slot %d\n",
|
||||
CONFIG_EXAMPLES_NSH_MMCSDSLOTNO);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Now bind the SPI interface to the MMC/SD driver */
|
||||
|
||||
message("nsh_archinitialize: Bind SDIO to the MMC/SD driver, minor=%d\n",
|
||||
CONFIG_EXAMPLES_NSH_MMCSDMINOR);
|
||||
ret = mmcsd_slotinitialize(CONFIG_EXAMPLES_NSH_MMCSDMINOR, sdio);
|
||||
if (ret != OK)
|
||||
{
|
||||
message("nsh_archinitialize: Failed to bind SDIO to the MMC/SD driver: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
message("nsh_archinitialize: Successfully bound SDIO to the MMC/SD driver\n");
|
||||
#endif
|
||||
return OK;
|
||||
}
|
||||
|
||||
+112
-47
@@ -161,11 +161,13 @@ static void mmcsd_decodeCID(FAR struct mmcsd_state_s *priv, uint32 cid[4]);
|
||||
static void mmcsd_decodeSCR(FAR struct mmcsd_state_s *priv, uint32 scr[2]);
|
||||
|
||||
static int mmcsd_getR1(FAR struct mmcsd_state_s *priv, FAR uint32 *r1);
|
||||
static int mmcsd_verifystandby(FAR struct mmcsd_state_s *priv);
|
||||
static int mmcsd_verifyidle(FAR struct mmcsd_state_s *priv);
|
||||
static int mmcsd_verifystate(FAR struct mmcsd_state_s *priv, uint32 status);
|
||||
|
||||
/* Transfer helpers *********************************************************/
|
||||
|
||||
static boolean mmcsd_wrprotected(FAR struct mmcsd_state_s *priv);
|
||||
static int mmcsd_eventwait(FAR struct mmcsd_state_s *priv,
|
||||
sdio_eventset_t failevents, uint32 timeout);
|
||||
static int mmcsd_transferready(FAR struct mmcsd_state_s *priv);
|
||||
static int mmcsd_stoptransmission(FAR struct mmcsd_state_s *priv);
|
||||
static int mmcsd_setblocklen(FAR struct mmcsd_state_s *priv,
|
||||
@@ -449,7 +451,7 @@ static int mmcsd_getSCR(FAR struct mmcsd_state_s *priv, uint32 scr[2])
|
||||
|
||||
/* Send ACMD51 SD_APP_SEND_SCR with argument as 0 to start data receipt */
|
||||
|
||||
(void)SDIO_WAITENABLE(priv->dev, SDIOWAIT_TRANSFERDONE);
|
||||
(void)SDIO_WAITENABLE(priv->dev, SDIOWAIT_TRANSFERDONE|SDIOWAIT_TIMEOUT);
|
||||
mmcsd_sendcmdpoll(priv, SD_ACMD51, 0);
|
||||
ret = mmcsd_recvR1(priv, SD_ACMD51);
|
||||
if (ret != OK)
|
||||
@@ -460,7 +462,7 @@ static int mmcsd_getSCR(FAR struct mmcsd_state_s *priv, uint32 scr[2])
|
||||
|
||||
/* Wait for data to be transferred */
|
||||
|
||||
ret = SDIO_EVENTWAIT(priv->dev, MMCSD_SCR_DATADELAY);
|
||||
ret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT, MMCSD_SCR_DATADELAY);
|
||||
if (ret != OK)
|
||||
{
|
||||
fdbg("ERROR: EVENTWAIT for READ DATA failed: %d\n", ret);
|
||||
@@ -905,37 +907,100 @@ static int mmcsd_getR1(FAR struct mmcsd_state_s *priv, FAR uint32 *r1)
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mmcsd_verifystandby
|
||||
* Name: mmcsd_verifystate
|
||||
*
|
||||
* Description:
|
||||
* Verify that the card is in STANDBY state
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int mmcsd_verifystandby(FAR struct mmcsd_state_s *priv)
|
||||
static int mmcsd_verifystate(FAR struct mmcsd_state_s *priv, uint32 state)
|
||||
{
|
||||
#warning "Not implemented"
|
||||
return -ENOSYS;
|
||||
}
|
||||
uint32 r1;
|
||||
int ret;
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mmcsd_verifyidle
|
||||
*
|
||||
* Description:
|
||||
* Verify that the card is in IDLE state
|
||||
*
|
||||
****************************************************************************/
|
||||
/* Get the current R1 status from the card */
|
||||
|
||||
static int mmcsd_verifyidle(FAR struct mmcsd_state_s *priv)
|
||||
{
|
||||
#warning "Not implemented"
|
||||
return -ENOSYS;
|
||||
ret = mmcsd_getR1(priv, &r1);
|
||||
if (ret != OK)
|
||||
{
|
||||
fdbg("ERROR: mmcsd_getR1 failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Now check if the card is in the expected state. */
|
||||
|
||||
if (IS_STATE(r1, state))
|
||||
{
|
||||
/* Yes.. return Success */
|
||||
|
||||
priv->wrbusy = FALSE;
|
||||
return OK;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Transfer Helpers
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mmcsd_wrprotected
|
||||
*
|
||||
* Description:
|
||||
* Return true if the the card is unlocked an not write protected. The
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static boolean mmcsd_wrprotected(FAR struct mmcsd_state_s *priv)
|
||||
{
|
||||
/* Check if the card is locked (priv->locked) or write protected either (1)
|
||||
* via software as reported via the CSD and retained in priv->wrprotect or
|
||||
* (2) via the mechanical write protect on the card (which we get from the
|
||||
* SDIO driver via SDIO_WRPROTECTED)
|
||||
*/
|
||||
|
||||
return (priv->wrprotect || priv->locked || SDIO_WRPROTECTED(priv->dev));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mmcsd_eventwait
|
||||
*
|
||||
* Description:
|
||||
* Wait for the specified events to occur. Check for wakeup on error events.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int mmcsd_eventwait(FAR struct mmcsd_state_s *priv,
|
||||
sdio_eventset_t failevents, uint32 timeout)
|
||||
{
|
||||
sdio_eventset_t wkupevent;
|
||||
|
||||
/* Wait for the set of events enabled by SDIO_EVENTENABLE. */
|
||||
|
||||
wkupevent = SDIO_EVENTWAIT(priv->dev, timeout);
|
||||
|
||||
/* SDIO_EVENTWAIT returns the event set containing the event(s) that ended
|
||||
* the wait. It should always be non-zero, but may contain failure as
|
||||
* well as success events. Check if it contains any failure events.
|
||||
*/
|
||||
|
||||
if ((wkupevent & failevents) != 0)
|
||||
{
|
||||
/* Yes.. the failure event is probably SDIOWAIT_TIMEOUT */
|
||||
|
||||
fdbg("ERROR: Awakened with %02\n", wkupevent);
|
||||
return wkupevent & SDIOWAIT_TIMEOUT ? -ETIMEDOUT : -EIO;
|
||||
}
|
||||
|
||||
/* Since there are no failure events, we must have been awaked by one
|
||||
* (or more) success events.
|
||||
*/
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mmcsd_transferready
|
||||
*
|
||||
@@ -989,7 +1054,7 @@ static int mmcsd_transferready(FAR struct mmcsd_state_s *priv)
|
||||
ret = mmcsd_getR1(priv, &r1);
|
||||
if (ret != OK)
|
||||
{
|
||||
fdbg("ERROR: mmcsd_recvR1 for CMD12 failed: %d\n", ret);
|
||||
fdbg("ERROR: mmcsd_getR1 failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1038,7 +1103,7 @@ static int mmcsd_transferready(FAR struct mmcsd_state_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int stm32_stoptransmission(FAR struct mmcsd_state_s *priv)
|
||||
static int mmcsd_stoptransmission(FAR struct mmcsd_state_s *priv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@@ -1153,7 +1218,7 @@ static ssize_t mmcsd_readsingle(FAR struct mmcsd_state_s *priv,
|
||||
|
||||
/* Configure SDIO controller hardware for the read transfer */
|
||||
|
||||
SDIO_WAITENABLE(priv->dev, SDIOWAIT_TRANSFERDONE);
|
||||
SDIO_WAITENABLE(priv->dev, SDIOWAIT_TRANSFERDONE|SDIOWAIT_TIMEOUT);
|
||||
#ifdef CONFIG_SDIO_DMA
|
||||
if (priv->dma)
|
||||
{
|
||||
@@ -1181,7 +1246,7 @@ static ssize_t mmcsd_readsingle(FAR struct mmcsd_state_s *priv,
|
||||
|
||||
/* Then wait for the data transfer to complete */
|
||||
|
||||
ret = SDIO_EVENTWAIT(priv->dev, MMCSD_BLOCK_DATADELAY);
|
||||
ret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT, MMCSD_BLOCK_DATADELAY);
|
||||
if (ret != OK)
|
||||
{
|
||||
fdbg("ERROR: CMD17 transfer failed: %d\n", ret);
|
||||
@@ -1256,7 +1321,7 @@ static ssize_t mmcsd_readmultiple(FAR struct mmcsd_state_s *priv,
|
||||
|
||||
/* Configure SDIO controller hardware for the read transfer */
|
||||
|
||||
SDIO_WAITENABLE(priv->dev, SDIOWAIT_TRANSFERDONE);
|
||||
SDIO_WAITENABLE(priv->dev, SDIOWAIT_TRANSFERDONE|SDIOWAIT_TIMEOUT);
|
||||
#ifdef CONFIG_SDIO_DMA
|
||||
if (priv->dma)
|
||||
{
|
||||
@@ -1282,7 +1347,7 @@ static ssize_t mmcsd_readmultiple(FAR struct mmcsd_state_s *priv,
|
||||
|
||||
/* Wait for the transfer to complete */
|
||||
|
||||
ret = SDIO_EVENTWAIT(priv->dev, nblocks * MMCSD_BLOCK_DATADELAY);
|
||||
ret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT, nblocks * MMCSD_BLOCK_DATADELAY);
|
||||
if (ret != OK)
|
||||
{
|
||||
fdbg("ERROR: CMD18 transfer failed: %d\n", ret);
|
||||
@@ -1346,9 +1411,11 @@ static ssize_t mmcsd_writesingle(FAR struct mmcsd_state_s *priv,
|
||||
fvdbg("startblock=%d\n", startblock);
|
||||
DEBUGASSERT(priv != NULL && buffer != NULL);
|
||||
|
||||
/* Check if the card is locked or write protected */
|
||||
/* Check if the card is locked or write protected (either via software or
|
||||
* via the mechanical write protect on the card)
|
||||
*/
|
||||
|
||||
if (priv->locked || priv->wrprotect)
|
||||
if (mmcsd_wrprotected(priv))
|
||||
{
|
||||
fdbg("ERROR: Card is locked or write protected\n");
|
||||
return -EPERM;
|
||||
@@ -1403,7 +1470,7 @@ static ssize_t mmcsd_writesingle(FAR struct mmcsd_state_s *priv,
|
||||
|
||||
/* Configure SDIO controller hardware for the write transfer */
|
||||
|
||||
SDIO_WAITENABLE(priv->dev, SDIOWAIT_TRANSFERDONE);
|
||||
SDIO_WAITENABLE(priv->dev, SDIOWAIT_TRANSFERDONE|SDIOWAIT_TIMEOUT);
|
||||
#ifdef CONFIG_SDIO_DMA
|
||||
if (priv->dma)
|
||||
{
|
||||
@@ -1417,7 +1484,7 @@ static ssize_t mmcsd_writesingle(FAR struct mmcsd_state_s *priv,
|
||||
|
||||
/* Wait for the transfer to complete */
|
||||
|
||||
ret = SDIO_EVENTWAIT(priv->dev, MMCSD_BLOCK_DATADELAY);
|
||||
ret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT, MMCSD_BLOCK_DATADELAY);
|
||||
if (ret != OK)
|
||||
{
|
||||
fdbg("ERROR: CMD24 transfer failed: %d\n", ret);
|
||||
@@ -1450,9 +1517,11 @@ static ssize_t mmcsd_writemultiple(FAR struct mmcsd_state_s *priv,
|
||||
fvdbg("startblockr=%d nblocks=%d\n", startblock, nblocks);
|
||||
DEBUGASSERT(priv != NULL && buffer != NULL && nblocks > 1);
|
||||
|
||||
/* Check if the card is locked or write protected */
|
||||
/* Check if the card is locked or write protected (either via software or
|
||||
* via the mechanical write protect on the card)
|
||||
*/
|
||||
|
||||
if (priv->locked || priv->wrprotect)
|
||||
if (mmcsd_wrprotected(priv))
|
||||
{
|
||||
fdbg("ERROR: Card is locked or write protected\n");
|
||||
return -EPERM;
|
||||
@@ -1539,7 +1608,7 @@ static ssize_t mmcsd_writemultiple(FAR struct mmcsd_state_s *priv,
|
||||
|
||||
/* Configure SDIO controller hardware for the write transfer */
|
||||
|
||||
SDIO_WAITENABLE(priv->dev, SDIOWAIT_TRANSFERDONE);
|
||||
SDIO_WAITENABLE(priv->dev, SDIOWAIT_TRANSFERDONE|SDIOWAIT_TIMEOUT);
|
||||
#ifdef CONFIG_SDIO_DMA
|
||||
if (priv->dma)
|
||||
{
|
||||
@@ -1553,7 +1622,7 @@ static ssize_t mmcsd_writemultiple(FAR struct mmcsd_state_s *priv,
|
||||
|
||||
/* Wait for the transfer to complete */
|
||||
|
||||
ret = SDIO_EVENTWAIT(priv->dev, nblocks * MMCSD_BLOCK_DATADELAY);
|
||||
ret =mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT, nblocks * MMCSD_BLOCK_DATADELAY);
|
||||
if (ret != OK)
|
||||
{
|
||||
fdbg("ERROR: CMD18 transfer failed: %d\n", ret);
|
||||
@@ -1768,7 +1837,7 @@ static int mmcsd_geometry(FAR struct inode *inode, struct geometry *geometry)
|
||||
geometry->geo_available = TRUE;
|
||||
geometry->geo_mediachanged = priv->mediachanged;
|
||||
#ifdef CONFIG_FS_WRITABLE
|
||||
geometry->geo_writeenabled = !priv->wrprotect && !priv->locked;
|
||||
geometry->geo_writeenabled = !mmcsd_wrprotected(priv);
|
||||
#else
|
||||
geometry->geo_writeenabled = FALSE;
|
||||
#endif
|
||||
@@ -2047,7 +2116,7 @@ static int mmcsd_mmcinitialize(FAR struct mmcsd_state_s *priv)
|
||||
* Verify that we are in standby state/data-transfer mode
|
||||
*/
|
||||
|
||||
ret = mmcsd_verifystandby(priv);
|
||||
ret = mmcsd_verifystate(priv, MMCSD_R1_STATE_STBY);
|
||||
if (ret != OK)
|
||||
{
|
||||
fdbg("ERROR: Failed to enter standby state\n");
|
||||
@@ -2149,7 +2218,7 @@ static int mmcsd_sdinitialize(FAR struct mmcsd_state_s *priv)
|
||||
* Verify that we are in standby state/data-transfer mode
|
||||
*/
|
||||
|
||||
ret = mmcsd_verifystandby(priv);
|
||||
ret = mmcsd_verifystate(priv, MMCSD_R1_STATE_STBY);
|
||||
if (ret != OK)
|
||||
{
|
||||
fdbg("ERROR: Failed to enter standby state\n");
|
||||
@@ -2452,7 +2521,7 @@ static int mmcsd_cardidentify(FAR struct mmcsd_state_s *priv)
|
||||
}
|
||||
|
||||
/* Verify that we are in IDLE state */
|
||||
|
||||
|
||||
ret = mmcsd_verifystate(priv, MMCSD_R1_STATE_IDLE);
|
||||
if (ret != OK)
|
||||
{
|
||||
@@ -2726,26 +2795,23 @@ static void mmcsd_hwuninitialize(FAR struct mmcsd_state_s *priv)
|
||||
*
|
||||
* Input Parameters:
|
||||
* minor - The MMC/SD minor device number. The MMC/SD device will be
|
||||
* registered as /dev/mmcsdN where N is the minor number
|
||||
* slotno - The slot number to use. This is only meaningful for architectures
|
||||
* that support multiple MMC/SD slots. This value must be in the range
|
||||
* registered as /dev/mmcsdN where N is the minor number
|
||||
* dev - And instance of an MMC/SD interface. The MMC/SD hardware should
|
||||
* be initialized and ready to use.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
int mmcsd_slotinitialize(int minor, FAR struct sdio_dev_s *dev)
|
||||
{
|
||||
FAR struct mmcsd_state_s *priv;
|
||||
char devname[16];
|
||||
int ret = -ENOMEM;
|
||||
|
||||
|
||||
fvdbg("minor: %d\n", minor);
|
||||
|
||||
/* Sanity check */
|
||||
|
||||
#ifdef CONFIG_DEBUG
|
||||
#ifdef CONFIG_DEBUG
|
||||
if (minor < 0 || minor > 255 || !dev)
|
||||
{
|
||||
return -EINVAL;
|
||||
@@ -2780,12 +2846,11 @@ int mmcsd_slotinitialize(int minor, int slotno, FAR struct sdio_dev_s *dev)
|
||||
*/
|
||||
|
||||
if (ret == -ENODEV)
|
||||
{
|
||||
{
|
||||
fdbg("MMC/SD slot is empty\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
fdbg("ERROR: Failed to initialize MMC/SD slot %d: %d\n",
|
||||
{
|
||||
fdbg("ERROR: Failed to initialize MMC/SD slot: %d\n", ret);
|
||||
goto errout_with_alloc;
|
||||
}
|
||||
|
||||
@@ -72,16 +72,13 @@ extern "C" {
|
||||
* Input Parameters:
|
||||
* minor - The MMC/SD minor device number. The MMC/SD device will be
|
||||
* registered as /dev/mmcsdN where N is the minor number
|
||||
* slotno - The slot number to use. This is only meaningful for architectures
|
||||
* that support multiple MMC/SD slots. This value must be in the range
|
||||
* {0, ..., CONFIG_MMCSD_NSLOTS}.
|
||||
* dev - And instance of an MMC/SD interface. The MMC/SD hardware should
|
||||
* be initialized and ready to use.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
struct sdio_dev_s; /* See nuttx/sdio.h */
|
||||
EXTERN int mmcsd_slotinitialize(int minor, int slotno, FAR struct sdio_dev_s *dev);
|
||||
EXTERN int mmcsd_slotinitialize(int minor, FAR struct sdio_dev_s *dev);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mmcsd_spislotinitialize
|
||||
|
||||
+13
-28
@@ -55,8 +55,9 @@
|
||||
#define SDIOWAIT_CMDDONE (1 << 0) /* Bit 0: Command complete */
|
||||
#define SDIOWAIT_RESPONSEDONE (1 << 1) /* Bit 1: Response to command available */
|
||||
#define SDIOWAIT_TRANSFERDONE (1 << 2) /* Bit 2: Data transfer/DMA done */
|
||||
#define SDIOWAIT_TIMEOUT (1 << 3) /* Bit 3: Timeout */
|
||||
|
||||
#define SDIOWAIT_ALLEVENTS 0x07
|
||||
#define SDIOWAIT_ALLEVENTS 0x0f
|
||||
|
||||
/* Media events are used for enable/disable registered event callbacks */
|
||||
|
||||
@@ -525,35 +526,18 @@
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - An instance of the SDIO device interface
|
||||
* timeout - Maximum time in milliseconds to wait. Zero means no timeout.
|
||||
* timeout - Maximum time in milliseconds to wait. Zero means immediate
|
||||
* timeout with no wait. The timeout value is ignored if
|
||||
* SDIOWAIT_TIMEOUT is not included in the waited-for eventset.
|
||||
*
|
||||
* Returned Value:
|
||||
* Event set containing the event(s) that ended the wait. If no events the
|
||||
* returned event set is zero, then the wait was terminated by the timeout.
|
||||
* All events are cleared disabled after the wait concludes.
|
||||
* Event set containing the event(s) that ended the wait. Should always
|
||||
* be non-zero. All events are disabled after the wait concludes.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#define SDIO_EVENTWAIT(dev,timeout) ((dev)->eventwait(dev,timeout))
|
||||
|
||||
/****************************************************************************
|
||||
* Name: SDIO_EVENTS
|
||||
*
|
||||
* Description:
|
||||
* Return the current event set. This supports polling for SDIO (vs.
|
||||
* waiting). Only enabled events need be reported.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - An instance of the SDIO device interface
|
||||
*
|
||||
* Returned Value:
|
||||
* Event set containing the current events (All pending events are cleared
|
||||
* after reading).
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#define SDIO_EVENTS(dev) ((dev)->events(dev))
|
||||
|
||||
/****************************************************************************
|
||||
* Name: SDIO_CALLBACKENABLE
|
||||
*
|
||||
@@ -736,13 +720,14 @@ struct sdio_dev_s
|
||||
int (*recvR6)(FAR struct sdio_dev_s *dev, uint32 cmd, uint32 *R6);
|
||||
int (*recvR7)(FAR struct sdio_dev_s *dev, uint32 cmd, uint32 *R7);
|
||||
|
||||
/* EVENT handler */
|
||||
/* Event/Callback support */
|
||||
|
||||
void (*waitenable)(FAR struct sdio_dev_s *dev, sdio_eventset_t eventset);
|
||||
ubyte (*eventwait)(FAR struct sdio_dev_s *dev, uint32 timeout);
|
||||
ubyte (*events)(FAR struct sdio_dev_s *dev);
|
||||
void (*callbackenable)(FAR struct sdio_dev_s *dev, sdio_eventset_t eventset);
|
||||
int (*registercallback)(FAR struct sdio_dev_s *dev, sdio_mediachange_t callback, void *arg);
|
||||
sdio_eventset_t (*eventwait)(FAR struct sdio_dev_s *dev, uint32 timeout);
|
||||
void (*callbackenable)(FAR struct sdio_dev_s *dev,
|
||||
sdio_eventset_t eventset);
|
||||
int (*registercallback)(FAR struct sdio_dev_s *dev,
|
||||
sdio_mediachange_t callback, void *arg);
|
||||
|
||||
/* DMA */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user