From 8e550d087c7b76ccaa782a5ce87ebfe1c119f27c Mon Sep 17 00:00:00 2001 From: patacongo Date: Thu, 8 Apr 2010 01:20:55 +0000 Subject: Add bus width logic git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2577 42af7a65-404d-4744-a932-0658087f49c3 --- nuttx/arch/arm/src/sam3u/sam3u_hsmci.c | 84 ++++++++++++++-------------------- 1 file changed, 34 insertions(+), 50 deletions(-) (limited to 'nuttx') 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; } -- cgit v1.2.3