diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2009-11-25 13:50:26 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2009-11-25 13:50:26 +0000 |
commit | beaf6630fced304d34f92f630eeb9b181f6e6567 (patch) | |
tree | ea7bcc4cd5cfec6757ac6eba02c390ac4678c1c6 /nuttx/drivers/mmcsd | |
parent | dd229ba9cc69cb587b587d23c641e0d29afde96a (diff) | |
download | px4-nuttx-beaf6630fced304d34f92f630eeb9b181f6e6567.tar.gz px4-nuttx-beaf6630fced304d34f92f630eeb9b181f6e6567.tar.bz2 px4-nuttx-beaf6630fced304d34f92f630eeb9b181f6e6567.zip |
Fix block read/write return values; SDIO error reporting; slow down clock if interrupt mode
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2278 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/drivers/mmcsd')
-rw-r--r-- | nuttx/drivers/mmcsd/mmcsd_sdio.c | 86 |
1 files changed, 60 insertions, 26 deletions
diff --git a/nuttx/drivers/mmcsd/mmcsd_sdio.c b/nuttx/drivers/mmcsd/mmcsd_sdio.c index 268b336d2..a0db7d76c 100644 --- a/nuttx/drivers/mmcsd/mmcsd_sdio.c +++ b/nuttx/drivers/mmcsd/mmcsd_sdio.c @@ -77,7 +77,14 @@ #define MMCSD_DSR_DELAY (100*1000) /* Time to wait after setting DSR */ #define MMCSD_CLK_DELAY (500*1000) /* Delay after changing clock speeds */ -/* Event delays (all in units of milliseconds) */ +/* Data delays (all in units of milliseconds). + * + * For MMC & SD V1.x, these should be based on Nac = TAAC + NSAC; The maximum + * value of TAAC is 80MS and the maximum value of NSAC is 25.5K clock cycle. + * For SD V2.x, a fixed delay of 100MS is recommend which is preety close to + * the worst case SD V1.x Nac. Here we just use 100MS delay for all data + * transfers. + */ #define MMCSD_SCR_DATADELAY (100) /* Wait up to 100MS to get SCR */ #define MMCSD_BLOCK_DATADELAY (100) /* Wait up to 100MS to get one data block */ @@ -446,7 +453,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|SDIOWAIT_TIMEOUT); + (void)SDIO_WAITENABLE(priv->dev, SDIOWAIT_TRANSFERDONE|SDIOWAIT_TIMEOUT|SDIOWAIT_ERROR); mmcsd_sendcmdpoll(priv, SD_ACMD51, 0); ret = mmcsd_recvR1(priv, SD_ACMD51); if (ret != OK) @@ -457,10 +464,10 @@ static int mmcsd_getSCR(FAR struct mmcsd_state_s *priv, uint32 scr[2]) /* Wait for data to be transferred */ - ret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT, MMCSD_SCR_DATADELAY); + ret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT|SDIOWAIT_ERROR, MMCSD_SCR_DATADELAY); if (ret != OK) { - fdbg("ERROR: EVENTWAIT for READ DATA failed: %d\n", ret); + fdbg("ERROR: mmcsd_eventwait for READ DATA failed: %d\n", ret); } return ret; } @@ -996,11 +1003,11 @@ static int mmcsd_eventwait(FAR struct mmcsd_state_s *priv, { /* Yes.. the failure event is probably SDIOWAIT_TIMEOUT */ - fdbg("ERROR: Awakened with %02\n", wkupevent); + fdbg("ERROR: Awakened with %02x\n", wkupevent); return wkupevent & SDIOWAIT_TIMEOUT ? -ETIMEDOUT : -EIO; } - /* Since there are no failure events, we must have been awaked by one + /* Since there are no failure events, we must have been awakened by one * (or more) success events. */ @@ -1224,7 +1231,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|SDIOWAIT_TIMEOUT); + SDIO_WAITENABLE(priv->dev, SDIOWAIT_TRANSFERDONE|SDIOWAIT_TIMEOUT|SDIOWAIT_ERROR); #ifdef CONFIG_SDIO_DMA if (priv->dma) { @@ -1252,12 +1259,16 @@ static ssize_t mmcsd_readsingle(FAR struct mmcsd_state_s *priv, /* Then wait for the data transfer to complete */ - ret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT, MMCSD_BLOCK_DATADELAY); + ret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT|SDIOWAIT_ERROR, MMCSD_BLOCK_DATADELAY); if (ret != OK) { fdbg("ERROR: CMD17 transfer failed: %d\n", ret); + return ret; } - return ret; + + /* Return value: One sector read */ + + return 1; } /**************************************************************************** @@ -1327,7 +1338,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|SDIOWAIT_TIMEOUT); + SDIO_WAITENABLE(priv->dev, SDIOWAIT_TRANSFERDONE|SDIOWAIT_TIMEOUT|SDIOWAIT_ERROR); #ifdef CONFIG_SDIO_DMA if (priv->dma) { @@ -1353,7 +1364,7 @@ static ssize_t mmcsd_readmultiple(FAR struct mmcsd_state_s *priv, /* Wait for the transfer to complete */ - ret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT, nblocks * MMCSD_BLOCK_DATADELAY); + ret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT|SDIOWAIT_ERROR, nblocks * MMCSD_BLOCK_DATADELAY); if (ret != OK) { fdbg("ERROR: CMD18 transfer failed: %d\n", ret); @@ -1367,7 +1378,10 @@ static ssize_t mmcsd_readmultiple(FAR struct mmcsd_state_s *priv, { fdbg("ERROR: mmcsd_stoptransmission failed: %d\n", ret); } - return ret; + + /* On success, return the number of blocks read */ + + return nblocks; } /**************************************************************************** @@ -1396,6 +1410,9 @@ static ssize_t mmcsd_reload(FAR void *dev, FAR ubyte *buffer, { ret = mmcsd_readmultiple(priv, buffer, startblock, nblocks); } + + /* On success, return the number of blocks read */ + return ret; } #endif @@ -1476,7 +1493,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|SDIOWAIT_TIMEOUT); + SDIO_WAITENABLE(priv->dev, SDIOWAIT_TRANSFERDONE|SDIOWAIT_TIMEOUT|SDIOWAIT_ERROR); #ifdef CONFIG_SDIO_DMA if (priv->dma) { @@ -1488,20 +1505,24 @@ static ssize_t mmcsd_writesingle(FAR struct mmcsd_state_s *priv, SDIO_SENDSETUP(priv->dev, buffer, priv->blocksize); } + /* Flag that a write transfer is pending that we will have to check for + * write complete at the beginning of the next transfer. + */ + + priv->wrbusy = TRUE; + /* Wait for the transfer to complete */ - ret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT, MMCSD_BLOCK_DATADELAY); + ret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT|SDIOWAIT_ERROR, MMCSD_BLOCK_DATADELAY); if (ret != OK) { fdbg("ERROR: CMD24 transfer failed: %d\n", ret); + return ret; } - /* Flag that a write transfer is pending that we will have to check for - * write complete at the beginning of the next transfer. - */ + /* On success, return the number of blocks written */ - priv->wrbusy = TRUE; - return ret; + return 1; } /**************************************************************************** @@ -1614,7 +1635,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|SDIOWAIT_TIMEOUT); + SDIO_WAITENABLE(priv->dev, SDIOWAIT_TRANSFERDONE|SDIOWAIT_TIMEOUT|SDIOWAIT_ERROR); #ifdef CONFIG_SDIO_DMA if (priv->dma) { @@ -1626,9 +1647,15 @@ static ssize_t mmcsd_writemultiple(FAR struct mmcsd_state_s *priv, SDIO_SENDSETUP(priv->dev, buffer, nbytes); } + /* Flag that a write transfer is pending that we will have to check for + * write complete at the beginning of the next transfer. + */ + + priv->wrbusy = TRUE; + /* Wait for the transfer to complete */ - ret =mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT, nblocks * MMCSD_BLOCK_DATADELAY); + ret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT|SDIOWAIT_ERROR, nblocks * MMCSD_BLOCK_DATADELAY); if (ret != OK) { fdbg("ERROR: CMD18 transfer failed: %d\n", ret); @@ -1641,14 +1668,12 @@ static ssize_t mmcsd_writemultiple(FAR struct mmcsd_state_s *priv, if (ret != OK) { fdbg("ERROR: mmcsd_stoptransmission failed: %d\n", ret); + return ret; } - /* Flag that a write transfer is pending that we will have to check for - * write complete at the beginning of the next transfer. - */ + /* On success, return the number of blocks read */ - priv->wrbusy = TRUE; - return ret; + return nblocks; } /**************************************************************************** @@ -1676,6 +1701,9 @@ static ssize_t mmcsd_flush(FAR void *dev, FAR const ubyte *buffer, { ret = mmcsd_writemultiple(priv, buffer, startblock, nblocks); } + + /* On success, return the number of blocks written */ + return ret; } #endif @@ -1768,6 +1796,9 @@ static ssize_t mmcsd_read(FAR struct inode *inode, unsigned char *buffer, #endif mmcsd_givesem(priv); } + + /* On success, return the number of blocks read */ + return ret; } @@ -1805,6 +1836,9 @@ static ssize_t mmcsd_write(FAR struct inode *inode, const unsigned char *buffer, } #endif mmcsd_givesem(priv); + + /* On success, return the number of blocks written */ + return ret; } #endif |