summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2010-04-08 01:20:55 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2010-04-08 01:20:55 +0000
commit8e550d087c7b76ccaa782a5ce87ebfe1c119f27c (patch)
tree0d3c9e05caee7a636e7592ecd7494c75cc9a7712
parentdbcd8d0405401b1d295a515cc165dacaeaf88f30 (diff)
downloadnuttx-8e550d087c7b76ccaa782a5ce87ebfe1c119f27c.tar.gz
nuttx-8e550d087c7b76ccaa782a5ce87ebfe1c119f27c.tar.bz2
nuttx-8e550d087c7b76ccaa782a5ce87ebfe1c119f27c.zip
Add bus width logic
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2577 42af7a65-404d-4744-a932-0658087f49c3
-rwxr-xr-xnuttx/arch/arm/src/sam3u/sam3u_hsmci.c84
1 files changed, 34 insertions, 50 deletions
diff --git a/nuttx/arch/arm/src/sam3u/sam3u_hsmci.c b/nuttx/arch/arm/src/sam3u/sam3u_hsmci.c
index 9aa229bf3..fce1c5f9b 100755
--- a/nuttx/arch/arm/src/sam3u/sam3u_hsmci.c
+++ b/nuttx/arch/arm/src/sam3u/sam3u_hsmci.c
@@ -155,6 +155,9 @@
( HSMCI_INT_UNRE | HSMCI_INT_OVRE | HSMCI_INT_BLKOVRE | HSMCI_INT_CSTOE | \
HSMCI_INT_DTOE | HSMCI_INT_DCRCE )
+#define HSMCI_DATA_TIMEOUT_ERRORS \
+ ( HSMCI_INT_CSTOE | HSMCI_INT_DTOE )
+
#define HSMCI_DATA_DMARECV_ERRORS \
( HSMCI_INT_OVRE | HSMCI_INT_BLKOVRE | HSMCI_INT_CSTOE | HSMCI_INT_DTOE | \
HSMCI_INT_DCRCE )
@@ -985,71 +988,41 @@ static int sam3u_interrupt(int irq, void *context)
while ((enabled = getreg32(SAM3U_HSMCI_SR) & getreg32(SAM3U_HSMCI_IMR)) != 0)
{
/* Handle in progress, interrupt driven data transfers ****************/
+ /* Do any of these interrupts signal the end a data transfer? */
pending = enabled & priv->xfrmask;
if (pending != 0)
{
- /* Handle data end events */
-
- if ((pending & HSMCI_INT_BLKE) != 0)
- {
- /* Terminate the transfer */
-
- sam3u_endtransfer(priv, SDIOWAIT_TRANSFERDONE);
- }
-
- /* Handle data block send/receive CRC failure */
-
- else if ((pending & HSMCI_INT_DCRCFAIL) != 0)
- {
- /* Terminate the transfer with an error */
-
- flldbg("ERROR: Data block CRC failure, remaining: %d\n", priv->remaining);
- sam3u_endtransfer(priv, SDIOWAIT_TRANSFERDONE|SDIOWAIT_ERROR);
- }
-
- /* Handle data timeout error */
+ /* Yes.. the transfer is complete. Did it complete with an error? */
- else if ((pending & HSMCI_INT_DTOE) != 0)
+ if ((pending & HSMCI_DATA_ERRORS) != 0)
{
- /* Terminate the transfer with an error */
+ /* Yes.. Was it some kind of timeout error? */
- flldbg("ERROR: Data timeout, remaining: %d\n", priv->remaining);
- sam3u_endtransfer(priv, SDIOWAIT_TRANSFERDONE|SDIOWAIT_TIMEOUT);
- }
-
- /* Handle RX FIFO overrun error */
+ flldbg("ERROR: enabled: %08x pending: %08x\n", enabled, pending);
+ if ((pending & HSMCI_DATA_TIMEOUT_ERRORS) != 0)
+ {
+ /* Yes.. Terminate with a timeout. */
- else if ((pending & HSMCI_INT_OVRE) != 0)
- {
- /* Terminate the transfer with an error */
+ sam3u_endtransfer(priv, SDIOWAIT_TRANSFERDONE|SDIOWAIT_TIMEOUT);
+ }
+ else
+ {
+ /* No.. Terminate with an I/O error. */
- flldbg("ERROR: RX FIFO overrun, remaining: %d\n", priv->remaining);
- sam3u_endtransfer(priv, SDIOWAIT_TRANSFERDONE|SDIOWAIT_ERROR);
+ sam3u_endtransfer(priv, SDIOWAIT_TRANSFERDONE|SDIOWAIT_ERROR);
+ }
}
-
- /* Handle TX FIFO underrun error */
-
- else if ((pending & HSMCI_INT_UNRE) != 0)
+ else
{
- /* Terminate the transfer with an error */
+ /* No.. Then the transfer must have completed successfully */
- flldbg("ERROR: TX FIFO underrun, remaining: %d\n", priv->remaining);
- sam3u_endtransfer(priv, SDIOWAIT_TRANSFERDONE|SDIOWAIT_ERROR);
+ sam3u_endtransfer(priv, SDIOWAIT_TRANSFERDONE);
}
-
- /* Handle start bit error */
-
- else if ((pending & HSMCI_INT_RENDE) != 0)
- {
- /* Terminate the transfer with an error */
-
- flldbg("ERROR: Start bit, remaining: %d\n", priv->remaining);
- sam3u_endtransfer(priv, SDIOWAIT_TRANSFERDONE|SDIOWAIT_ERROR);
- }
}
/* Handle wait events *************************************************/
+ /* Do any of these interrupts signal wakeup event? */
pending = enabled & priv->waitmask;
if (pending != 0)
@@ -1194,7 +1167,7 @@ static uint8_t sam3u_status(FAR struct sdio_dev_s *dev)
}
/****************************************************************************
- * Name: HSMCI_WIDEBUS
+ * Name: sam3u_widebus
*
* Description:
* Called after change in Bus width has been selected (via ACMD6). Most
@@ -1213,6 +1186,17 @@ static uint8_t sam3u_status(FAR struct sdio_dev_s *dev)
static void sam3u_widebus(FAR struct sdio_dev_s *dev, bool wide)
{
struct sam3u_dev_s *priv = (struct sam3u_dev_s *)dev;
+ uint32_t regval;
+
+ /* Set 1-bit or 4-bit bus by configuring the SDCBUS field of the SDCR register */
+
+ regval = getreg32(SAM3U_HSMCI_SDCR);
+ regval &= ~HSMCI_SDCR_SDCBUS_MASK;
+ regval |= wide ? HSMCI_SDCR_SDCBUS_4BIT : HSMCI_SDCR_SDCBUS_1BIT;
+ putreg32(regval, SAM3U_HSMCI_SDCR);
+
+ /* Remember the setting */
+
priv->widebus = wide;
}