Squashed commit of the following:

lpc43/54 SDMMC:  Wading through bits trying to make sense out of what is a event want interrupt which deal mostly with commands+responses and what is a data transfer event.  DTO is the only wildcard.  I think this clear now but DMA transfers will fail with CRC error.
    lpc43/54 SDMMC:  DTO is a wait event, not a transfer event.
    lpc43/54 SDMMC:  Significant simplication to previous design.  More debug output.
    lpc43/54 SDMMC:  Don't allow duplicate events in waitmask and xfrmask.
    lpc43/54 SDMMC:  Not all interrupts were being disabled at the end of a transfer.
    lpc43/54 SDMMC:  Defer enabling DMA transfer interrupts until after command has been sent.
This commit is contained in:
Gregory Nutt 2017-12-23 11:42:04 -06:00
parent 6fa734457d
commit b329b8c1e4
2 changed files with 256 additions and 208 deletions

View File

@ -138,27 +138,26 @@
/* Data transfer interrupt mask bits */
#define SDCARD_RECV_MASK (SDMMC_INT_DCRC | SDMMC_INT_RCRC | SDMMC_INT_DRTO | \
SDMMC_INT_RTO | SDMMC_INT_EBE | SDMMC_INT_RXDR | \
SDMMC_INT_SBE)
#define SDCARD_SEND_MASK (SDMMC_INT_DCRC | SDMMC_INT_RCRC | SDMMC_INT_DRTO | \
SDMMC_INT_RTO | SDMMC_INT_EBE | SDMMC_INT_TXDR | \
SDMMC_INT_DTO | SDMMC_INT_SBE)
#define SDCARD_RECV_MASK (SDMMC_INT_DTO | SDMMC_INT_DCRC | SDMMC_INT_DRTO | \
SDMMC_INT_EBE | SDMMC_INT_RXDR | SDMMC_INT_SBE)
#define SDCARD_SEND_MASK (SDMMC_INT_DTO | SDMMC_INT_DCRC | SDMMC_INT_DRTO | \
SDMMC_INT_EBE | SDMMC_INT_TXDR | SDMMC_INT_SBE)
#define SDCARD_DMARECV_MASK (SDMMC_INT_DTO | SDMMC_INT_DCRC | SDMMC_INT_DRTO | \
SDMMC_INT_SBE | SDMMC_INT_EBE)
#define SDCARD_DMASEND_MASK (SDMMC_INT_DTO | SDMMC_INT_DCRC | SDMMC_INT_DRTO | \
#define SDCARD_DMARECV_MASK (SDMMC_INT_DTO | SDMMC_INT_DCRC | SDMMC_INT_DRTO | \
SDMMC_INT_SBE | SDMMC_INT_EBE)
#define SDCARD_DMASEND_MASK (SDMMC_INT_DTO | SDMMC_INT_DCRC | SDMMC_INT_DRTO | \
SDMMC_INT_EBE)
#define SDCARD_DMAERROR_MASK (SDMMC_IDINTEN_FBE | SDMMC_IDINTEN_DU | \
SDMMC_IDINTEN_AIS)
#define SDCARD_TRANSFER_ALL (SDMMC_INT_DTO | SDMMC_INT_DCRC | SDMMC_INT_DRTO | \
SDMMC_INT_EBE | SDMMC_INT_TXDR | SDMMC_INT_RXDR | \
SDMMC_INT_SBE)
/* Event waiting interrupt mask bits */
#define SDCARD_INT_ERROR (SDMMC_INT_RE | SDMMC_INT_RCRC | SDMMC_INT_DCRC | \
SDMMC_INT_RTO | SDMMC_INT_DRTO | SDMMC_INT_HTO | \
SDMMC_INT_FRUN | SDMMC_INT_HLE | SDMMC_INT_SBE | \
SDMMC_INT_EBE)
#define SDCARD_INT_RESPERR (SDMMC_INT_RE | SDMMC_INT_RCRC | SDMMC_INT_RTO)
#ifdef CONFIG_MMCSD_HAVE_CARDDETECT
# define SDCARD_INT_CDET SDMMC_INT_CDET
@ -170,17 +169,16 @@
#define SDCARD_RESPDONE_STA (0)
#define SDCARD_CMDDONE_MASK (SDMMC_INT_CDONE)
#define SDCARD_RESPDONE_MASK (SDMMC_INT_RTO | SDMMC_INT_RCRC | SDMMC_INT_CDONE)
#define SDCARD_XFRDONE_MASK (SDMMC_INT_DTO)
#define SDCARD_RESPDONE_MASK (SDMMC_INT_CDONE | SDCARD_INT_RESPERR)
#define SDCARD_XFRDONE_MASK (0) /* Handled by transfer masks */
#define SDCARD_CMDDONE_ICR (SDMMC_INT_CDONE)
#define SDCARD_RESPDONE_ICR (SDMMC_INT_RTO | SDMMC_INT_RCRC | SDMMC_INT_CDONE)
#define SDCARD_CMDDONE_CLEAR (SDMMC_INT_CDONE)
#define SDCARD_RESPDONE_CLEAR (SDMMC_INT_CDONE | SDCARD_INT_RESPERR)
#define SDCARD_XFRDONE_ICR (SDMMC_INT_DTO | SDMMC_INT_DCRC | SDMMC_INT_DRTO | \
SDMMC_INT_FRUN | SDMMC_INT_SBE)
#define SDCARD_XFRDONE_CLEAR (SDCARD_TRANSFER_ALL)
#define SDCARD_WAITALL_ICR (SDCARD_CMDDONE_ICR | SDCARD_RESPDONE_ICR | \
SDCARD_XFRDONE_ICR)
#define SDCARD_WAITALL_CLEAR (SDCARD_CMDDONE_CLEAR | SDCARD_RESPDONE_CLEAR | \
SDCARD_XFRDONE_CLEAR)
/* Let's wait until we have both SD card transfer complete and DMA complete. */
@ -270,11 +268,14 @@ static void lpc43_takesem(struct lpc43_dev_s *priv);
static inline void lpc43_setclock(uint32_t clkdiv);
static inline void lpc43_sdcard_clock(bool enable);
static int lpc43_ciu_sendcmd(uint32_t cmd, uint32_t arg);
static void lpc43_configwaitints(struct lpc43_dev_s *priv, uint32_t waitmask,
static void lpc43_enable_ints(struct lpc43_dev_s *priv);
static void lpc43_disable_allints(struct lpc43_dev_s *priv);
static void lpc43_config_waitints(struct lpc43_dev_s *priv, uint32_t waitmask,
sdio_eventset_t waitevents, sdio_eventset_t wkupevents);
static void lpc43_configxfrints(struct lpc43_dev_s *priv, uint32_t xfrmask);
static void lpc43_config_xfrints(struct lpc43_dev_s *priv, uint32_t xfrmask);
#ifdef CONFIG_LPC43_SDMMC_DMA
static void lpc43_configdmaints(struct lpc43_dev_s *priv, uint32_t dmamask);
static void lpc43_config_dmaints(struct lpc43_dev_s *priv, uint32_t xfrmask,
uint32_t dmamask);
#endif
/* Data Transfer Helpers ****************************************************/
@ -632,7 +633,7 @@ static int lpc43_ciu_sendcmd(uint32_t cmd, uint32_t arg)
}
/****************************************************************************
* Name: lpc43_setupints
* Name: lpc43_enable_ints
*
* Description:
* Enable/disable SD card interrupts per functional settings.
@ -645,22 +646,24 @@ static int lpc43_ciu_sendcmd(uint32_t cmd, uint32_t arg)
*
****************************************************************************/
static void lpc43_setupints(struct lpc43_dev_s *priv)
static void lpc43_enable_ints(struct lpc43_dev_s *priv)
{
uint32_t regval;
#ifdef CONFIG_LPC43_SDMMC_DMA
mcinfo("waitmask=%04lx xfrmask=%04lx dmamask=%04lx\n",
mcinfo("waitmask=%04lx xfrmask=%04lx dmamask=%04lx RINTSTS=%08lx\n",
(unsigned long)priv->waitmask, (unsigned long)priv->xfrmask,
(unsigned long)priv->dmamask);
(unsigned long)priv->dmamask,
(unsigned long)lpc43_getreg(LPC43_SDMMC_RINTSTS));
/* Enable DMA-related interrupts */
lpc43_putreg(priv->dmamask, LPC43_SDMMC_IDINTEN);
#else
mcinfo("waitmask=%04lx xfrmask=%04lx\n",
(unsigned long)priv->waitmask, (unsigned long)priv->xfrmask);
mcinfo("waitmask=%04lx xfrmask=%04lx RINTSTS=%08lx\n",
(unsigned long)priv->waitmask, (unsigned long)priv->xfrmask,
(unsigned long)lpc43_getreg(LPC43_SDMMC_RINTSTS));
#endif
/* Enable SDMMC interrupts */
@ -670,14 +673,44 @@ static void lpc43_setupints(struct lpc43_dev_s *priv)
}
/****************************************************************************
* Name: lpc43_configwaitints
* Name: lpc43_disable_allints
*
* Description:
* Disable all SD card interrupts.
*
* Input Parameters:
* priv - A reference to the SD card device state structure
*
* Returned Value:
* None
*
****************************************************************************/
static void lpc43_disable_allints(struct lpc43_dev_s *priv)
{
#ifdef CONFIG_LPC43_SDMMC_DMA
/* Disable DMA-related interrupts */
lpc43_putreg(0, LPC43_SDMMC_IDINTEN);
priv->dmamask = 0;
#endif
/* Disable all SDMMC interrupts (except card detect) */
lpc43_putreg(SDCARD_INT_CDET, LPC43_SDMMC_INTMASK);
priv->waitmask = 0;
priv->xfrmask = 0;
}
/****************************************************************************
* Name: lpc43_config_waitints
*
* Description:
* Enable/disable SD card interrupts needed to suport the wait function
*
* Input Parameters:
* priv - A reference to the SD card device state structure
* waitmask - The set of bits in the SD card MASK register to set
* waitmask - The set of bits in the SD card INTMASK register to set
* waitevents - Waited for events
* wkupevent - Wake-up events
*
@ -686,9 +719,9 @@ static void lpc43_setupints(struct lpc43_dev_s *priv)
*
****************************************************************************/
static void lpc43_configwaitints(struct lpc43_dev_s *priv, uint32_t waitmask,
sdio_eventset_t waitevents,
sdio_eventset_t wkupevent)
static void lpc43_config_waitints(struct lpc43_dev_s *priv, uint32_t waitmask,
sdio_eventset_t waitevents,
sdio_eventset_t wkupevent)
{
irqstate_t flags;
@ -704,12 +737,12 @@ static void lpc43_configwaitints(struct lpc43_dev_s *priv, uint32_t waitmask,
priv->wkupevent = wkupevent;
priv->waitmask = waitmask;
lpc43_setupints(priv);
lpc43_enable_ints(priv);
leave_critical_section(flags);
}
/****************************************************************************
* Name: lpc43_configxfrints
* Name: lpc43_config_xfrints
*
* Description:
* Enable SD card interrupts needed to support the data transfer event
@ -723,22 +756,22 @@ static void lpc43_configwaitints(struct lpc43_dev_s *priv, uint32_t waitmask,
*
****************************************************************************/
static void lpc43_configxfrints(struct lpc43_dev_s *priv, uint32_t xfrmask)
static void lpc43_config_xfrints(struct lpc43_dev_s *priv, uint32_t xfrmask)
{
irqstate_t flags;
flags = enter_critical_section();
priv->xfrmask = xfrmask;
lpc43_setupints(priv);
lpc43_enable_ints(priv);
leave_critical_section(flags);
}
/****************************************************************************
* Name: lpc43_configdmaints
* Name: lpc43_config_dmaints
*
* Description:
* Enable DMA interrupts
* Enable DMA transfer interrupts
*
* Input Parameters:
* priv - A reference to the SD card device state structure
@ -750,13 +783,15 @@ static void lpc43_configxfrints(struct lpc43_dev_s *priv, uint32_t xfrmask)
****************************************************************************/
#ifdef CONFIG_LPC43_SDMMC_DMA
static void lpc43_configdmaints(struct lpc43_dev_s *priv, uint32_t dmamask)
static void lpc43_config_dmaints(struct lpc43_dev_s *priv, uint32_t xfrmask,
uint32_t dmamask)
{
irqstate_t flags;
flags = enter_critical_section();
priv->xfrmask = xfrmask;
priv->dmamask = dmamask;
lpc43_setupints(priv);
lpc43_enable_ints(priv);
leave_critical_section(flags);
}
@ -830,7 +865,7 @@ static void lpc43_endwait(struct lpc43_dev_s *priv, sdio_eventset_t wkupevent)
/* Disable event-related interrupts */
lpc43_configwaitints(priv, 0, 0, wkupevent);
lpc43_config_waitints(priv, 0, 0, wkupevent);
/* Wake up the waiting thread */
@ -863,7 +898,7 @@ static void lpc43_endtransfer(struct lpc43_dev_s *priv, sdio_eventset_t wkupeven
/* Disable all transfer related interrupts */
lpc43_configxfrints(priv, 0);
lpc43_config_xfrints(priv, 0);
/* Clearing pending interrupt status on all transfer related interrupts */
@ -970,7 +1005,7 @@ static int lpc43_sdmmc_interrupt(int irq, void *context, FAR void *arg)
}
#endif
/* Handle in progress, interrupt driven data transfers ****************/
/* Handle idata transfer events ***************************************/
pending = enabled & priv->xfrmask;
if (pending != 0)
@ -1042,13 +1077,15 @@ static int lpc43_sdmmc_interrupt(int irq, void *context, FAR void *arg)
}
}
/* Check for transfer errors */
/* Handle data block send/receive CRC failure */
if ((pending & SDMMC_INT_DCRC) != 0)
{
/* Terminate the transfer with an error */
mcerr("ERROR: Data block CRC failure, remaining: %d\n", priv->remaining);
mcerr("ERROR: Data CRC failure, pending=%08x remaining: %d\n",
pending, priv->remaining);
lpc43_putreg(SDMMC_INT_DCRC, LPC43_SDMMC_RINTSTS);
lpc43_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR);
}
@ -1059,7 +1096,8 @@ static int lpc43_sdmmc_interrupt(int irq, void *context, FAR void *arg)
{
/* Terminate the transfer with an error */
mcerr("ERROR: Data timeout, remaining: %d\n", priv->remaining);
mcerr("ERROR: Data timeout, pending=%08x remaining: %d\n",
pending, priv->remaining);
lpc43_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_TIMEOUT);
}
@ -1069,7 +1107,8 @@ static int lpc43_sdmmc_interrupt(int irq, void *context, FAR void *arg)
{
/* Terminate the transfer with an error */
mcerr("ERROR: RX FIFO overrun, remaining: %d\n", priv->remaining);
mcerr("ERROR: RX FIFO overrun, pending=%08x remaining: %d\n",
pending, priv->remaining);
lpc43_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR);
}
@ -1079,7 +1118,8 @@ static int lpc43_sdmmc_interrupt(int irq, void *context, FAR void *arg)
{
/* Terminate the transfer with an error */
mcerr("ERROR: TX FIFO underrun, remaining: %d\n", priv->remaining);
mcerr("ERROR: TX FIFO underrun, pending=%08x remaining: %d\n",
pending, priv->remaining);
lpc43_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR);
}
@ -1089,7 +1129,8 @@ static int lpc43_sdmmc_interrupt(int irq, void *context, FAR void *arg)
{
/* Terminate the transfer with an error */
mcerr("ERROR: Start bit, remaining: %d\n", priv->remaining);
mcerr("ERROR: Start bit, pending=%08x remaining: %d\n",
pending, priv->remaining);
lpc43_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR);
}
@ -1103,9 +1144,9 @@ static int lpc43_sdmmc_interrupt(int irq, void *context, FAR void *arg)
{
/* Finish the transfer */
lpc43_putreg(SDCARD_XFRDONE_CLEAR, LPC43_SDMMC_RINTSTS);
lpc43_endtransfer(priv, SDIOWAIT_TRANSFERDONE);
}
}
/* Handle wait events *************************************************/
@ -1113,9 +1154,9 @@ static int lpc43_sdmmc_interrupt(int irq, void *context, FAR void *arg)
pending = enabled & priv->waitmask;
if (pending != 0)
{
/* Is this a response completion event? */
/* Is this a command (plus response) completion event? */
if ((pending & SDMMC_INT_DTO) != 0)
if ((pending & SDMMC_INT_CDONE) != 0)
{
/* Yes.. Is their a thread waiting for response done? */
@ -1123,23 +1164,18 @@ static int lpc43_sdmmc_interrupt(int irq, void *context, FAR void *arg)
{
/* Yes.. wake the thread up */
lpc43_putreg(SDCARD_RESPDONE_ICR | SDCARD_CMDDONE_ICR,
lpc43_putreg(SDCARD_RESPDONE_CLEAR | SDCARD_CMDDONE_CLEAR,
LPC43_SDMMC_RINTSTS);
lpc43_endwait(priv, SDIOWAIT_RESPONSEDONE);
}
}
/* Is this a command completion event? */
/* NO.. Is their a thread waiting for command done? */
if ((pending & SDMMC_INT_CDONE) != 0)
{
/* Yes.. Is their a thread waiting for command done? */
if ((priv->waitevents & SDIOWAIT_RESPONSEDONE) != 0)
else if ((priv->waitevents & SDIOWAIT_CMDDONE) != 0)
{
/* Yes.. wake the thread up */
lpc43_putreg(SDCARD_CMDDONE_ICR, LPC43_SDMMC_RINTSTS);
lpc43_putreg(SDCARD_CMDDONE_CLEAR, LPC43_SDMMC_RINTSTS);
lpc43_endwait(priv, SDIOWAIT_CMDDONE);
}
}
@ -1223,10 +1259,6 @@ static void lpc43_reset(FAR struct sdio_dev_s *dev)
lpc43_putreg(SDMMC_BMOD_SWR, LPC43_SDMMC_BMOD);
/* Software Reset */
lpc43_putreg(SDMMC_BMOD_SWR, LPC43_SDMMC_BMOD);
/* Reset all blocks */
lpc43_putreg(SDMMC_CTRL_CNTLRRESET | SDMMC_CTRL_FIFORESET |
@ -1378,8 +1410,6 @@ static sdio_statset_t lpc43_status(FAR struct sdio_dev_s *dev)
static void lpc43_widebus(FAR struct sdio_dev_s *dev, bool wide)
{
struct lpc43_dev_s *priv = (struct lpc43_dev_s *)dev;
mcinfo("wide=%d\n", wide);
}
@ -1602,7 +1632,7 @@ static int lpc43_sendcmd(FAR struct sdio_dev_s *dev, uint32_t cmd,
/* Write the SD card CMD */
lpc43_putreg(SDCARD_RESPDONE_ICR | SDCARD_CMDDONE_ICR,
lpc43_putreg(SDCARD_RESPDONE_CLEAR | SDCARD_CMDDONE_CLEAR,
LPC43_SDMMC_RINTSTS);
lpc43_ciu_sendcmd(regval, arg);
@ -1689,7 +1719,7 @@ static int lpc43_recvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer,
/* Configure the transfer interrupts */
lpc43_configxfrints(priv, SDCARD_RECV_MASK);
lpc43_config_xfrints(priv, SDCARD_RECV_MASK);
return OK;
}
@ -1753,7 +1783,7 @@ static int lpc43_sendsetup(FAR struct sdio_dev_s *dev, FAR const uint8_t *buffer
/* Configure the transfer interrupts */
lpc43_configxfrints(priv, SDCARD_SEND_MASK);
lpc43_config_xfrints(priv, SDCARD_SEND_MASK);
return OK;
}
@ -1782,17 +1812,13 @@ static int lpc43_cancel(FAR struct sdio_dev_s *dev)
/* Disable all transfer- and event- related interrupts */
lpc43_configxfrints(priv, 0);
lpc43_configwaitints(priv, 0, 0, 0);
#ifdef CONFIG_LPC43_SDMMC_DMA
lpc43_configdmaints(priv, 0);
#endif
lpc43_disable_allints(priv);
/* Clearing pending interrupt status on all transfer- and event- related
* interrupts
*/
lpc43_putreg(SDCARD_WAITALL_ICR, LPC43_SDMMC_RINTSTS);
lpc43_putreg(SDCARD_WAITALL_CLEAR, LPC43_SDMMC_RINTSTS);
/* Cancel any watchdog timeout */
@ -1837,7 +1863,7 @@ static int lpc43_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd)
case MMCSD_R1B_RESPONSE:
case MMCSD_R2_RESPONSE:
case MMCSD_R6_RESPONSE:
events = SDCARD_RESPDONE_STA;
events = (SDCARD_CMDDONE_STA | SDCARD_RESPDONE_STA);
timeout = SDCARD_LONGTIMEOUT;
break;
@ -1847,7 +1873,7 @@ static int lpc43_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd)
case MMCSD_R3_RESPONSE:
case MMCSD_R7_RESPONSE:
events = SDCARD_RESPDONE_STA;
events = (SDCARD_CMDDONE_STA | SDCARD_RESPDONE_STA);
timeout = SDCARD_CMDTIMEOUT;
break;
@ -1855,8 +1881,6 @@ static int lpc43_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd)
return -EINVAL;
}
events |= SDCARD_CMDDONE_STA;
mcinfo("cmd: %04x events: %04x STATUS: %08x RINTSTS: %08x\n",
cmd, events, lpc43_getreg(LPC43_SDMMC_STATUS),
lpc43_getreg(LPC43_SDMMC_RINTSTS));
@ -1872,7 +1896,7 @@ static int lpc43_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd)
lpc43_getreg(LPC43_SDMMC_RINTSTS));
return -ETIMEDOUT;
}
else if ((lpc43_getreg(LPC43_SDMMC_RINTSTS) & SDCARD_INT_ERROR) != 0)
else if ((lpc43_getreg(LPC43_SDMMC_RINTSTS) & SDCARD_INT_RESPERR) != 0)
{
mcerr("ERROR: SDMMC failure cmd: %04x events: %04x STA: %08x RINTSTS: %08x\n",
cmd, events, lpc43_getreg(LPC43_SDMMC_STATUS),
@ -1881,7 +1905,7 @@ static int lpc43_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd)
}
}
lpc43_putreg(SDCARD_CMDDONE_ICR, LPC43_SDMMC_RINTSTS);
lpc43_putreg(SDCARD_CMDDONE_CLEAR, LPC43_SDMMC_RINTSTS);
return OK;
}
@ -1973,16 +1997,20 @@ static int lpc43_recvshortcrc(FAR struct sdio_dev_s *dev, uint32_t cmd,
}
}
/* Clear all pending message completion events and return the R1/R6 response */
/* Clear all pending message completion events and return the R1/R6
* response.
*/
lpc43_putreg(SDCARD_RESPDONE_ICR | SDCARD_CMDDONE_ICR, LPC43_SDMMC_RINTSTS);
lpc43_putreg(SDCARD_RESPDONE_CLEAR | SDCARD_CMDDONE_CLEAR,
LPC43_SDMMC_RINTSTS);
*rshort = lpc43_getreg(LPC43_SDMMC_RESP0);
mcinfo("CRC=%04x\n", *rshort);
return ret;
}
static int lpc43_recvlong(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t rlong[4])
static int lpc43_recvlong(FAR struct sdio_dev_s *dev, uint32_t cmd,
uint32_t rlong[4])
{
uint32_t regval;
int ret = OK;
@ -2026,7 +2054,8 @@ static int lpc43_recvlong(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t rlo
/* Return the long response */
lpc43_putreg(SDCARD_RESPDONE_ICR | SDCARD_CMDDONE_ICR, LPC43_SDMMC_RINTSTS);
lpc43_putreg(SDCARD_RESPDONE_CLEAR | SDCARD_CMDDONE_CLEAR,
LPC43_SDMMC_RINTSTS);
if (rlong)
{
rlong[0] = lpc43_getreg(LPC43_SDMMC_RESP3);
@ -2078,7 +2107,8 @@ static int lpc43_recvshort(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t *r
}
}
lpc43_putreg(SDCARD_RESPDONE_ICR | SDCARD_CMDDONE_ICR, LPC43_SDMMC_RINTSTS);
lpc43_putreg(SDCARD_RESPDONE_CLEAR | SDCARD_CMDDONE_CLEAR,
LPC43_SDMMC_RINTSTS);
if (rshort)
{
*rshort = lpc43_getreg(LPC43_SDMMC_RESP0);
@ -2094,7 +2124,8 @@ static int lpc43_recvnotimpl(FAR struct sdio_dev_s *dev, uint32_t cmd,
{
mcinfo("cmd=%04x\n", cmd);
lpc43_putreg(SDCARD_RESPDONE_ICR | SDCARD_CMDDONE_ICR, LPC43_SDMMC_RINTSTS);
lpc43_putreg(SDCARD_RESPDONE_CLEAR | SDCARD_CMDDONE_CLEAR,
LPC43_SDMMC_RINTSTS);
return -ENOSYS;
}
@ -2133,7 +2164,7 @@ static void lpc43_waitenable(FAR struct sdio_dev_s *dev,
/* Disable event-related interrupts */
lpc43_configwaitints(priv, 0, 0, 0);
lpc43_config_waitints(priv, 0, 0, 0);
/* Select the interrupt mask that will give us the appropriate wakeup
* interrupts.
@ -2157,7 +2188,7 @@ static void lpc43_waitenable(FAR struct sdio_dev_s *dev,
/* Enable event-related interrupts */
lpc43_configwaitints(priv, waitmask, eventset, 0);
lpc43_config_waitints(priv, waitmask, eventset, 0);
}
/****************************************************************************
@ -2256,12 +2287,13 @@ static sdio_eventset_t lpc43_eventwait(FAR struct sdio_dev_s *dev,
}
}
/* Disable event-related interrupts */
/* Disable all transfer- and event- related interrupts */
lpc43_configwaitints(priv, 0, 0, 0);
lpc43_disable_allints(priv);
errout:
leave_critical_section(flags);
mcinfo("wkupevent=%04x\n", wkupevent);
return wkupevent;
}
@ -2477,11 +2509,7 @@ static int lpc43_dmarecvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer,
/* Setup DMA error interrupts */
lpc43_putreg(SDMMC_INT_ALL, LPC43_SDMMC_RINTSTS);
lpc43_putreg(SDMMC_IDINTEN_ALL, LPC43_SDMMC_IDSTS);
lpc43_configxfrints(priv, SDCARD_DMARECV_MASK);
lpc43_configdmaints(priv, SDCARD_DMAERROR_MASK);
lpc43_config_dmaints(priv, SDCARD_DMARECV_MASK, SDCARD_DMAERROR_MASK);
return OK;
}
#endif
@ -2579,11 +2607,7 @@ static int lpc43_dmasendsetup(FAR struct sdio_dev_s *dev,
/* Setup DMA error interrupts */
lpc43_putreg(SDMMC_INT_ALL, LPC43_SDMMC_RINTSTS);
lpc43_putreg(SDMMC_IDINTEN_ALL, LPC43_SDMMC_IDSTS);
lpc43_configxfrints(priv, SDCARD_DMASEND_MASK);
lpc43_configdmaints(priv, SDCARD_DMAERROR_MASK);
lpc43_config_dmaints(priv, SDCARD_DMASEND_MASK, SDCARD_DMAERROR_MASK);
return OK;
}
#endif

View File

@ -142,27 +142,26 @@
/* Data transfer interrupt mask bits */
#define SDCARD_RECV_MASK (SDMMC_INT_DCRC | SDMMC_INT_RCRC | SDMMC_INT_DRTO | \
SDMMC_INT_RTO | SDMMC_INT_EBE | SDMMC_INT_RXDR | \
SDMMC_INT_SBE)
#define SDCARD_SEND_MASK (SDMMC_INT_DCRC | SDMMC_INT_RCRC | SDMMC_INT_DRTO | \
SDMMC_INT_RTO | SDMMC_INT_EBE | SDMMC_INT_TXDR | \
SDMMC_INT_DTO | SDMMC_INT_SBE)
#define SDCARD_RECV_MASK (SDMMC_INT_DTO | SDMMC_INT_DCRC | SDMMC_INT_DRTO | \
SDMMC_INT_EBE | SDMMC_INT_RXDR | SDMMC_INT_SBE)
#define SDCARD_SEND_MASK (SDMMC_INT_DTO | SDMMC_INT_DCRC | SDMMC_INT_DRTO | \
SDMMC_INT_EBE | SDMMC_INT_TXDR | SDMMC_INT_SBE)
#define SDCARD_DMARECV_MASK (SDMMC_INT_DTO | SDMMC_INT_DCRC | SDMMC_INT_DRTO | \
SDMMC_INT_SBE | SDMMC_INT_EBE)
#define SDCARD_DMASEND_MASK (SDMMC_INT_DTO | SDMMC_INT_DCRC | SDMMC_INT_DRTO | \
#define SDCARD_DMARECV_MASK (SDMMC_INT_DTO | SDMMC_INT_DCRC | SDMMC_INT_DRTO | \
SDMMC_INT_SBE | SDMMC_INT_EBE)
#define SDCARD_DMASEND_MASK (SDMMC_INT_DTO | SDMMC_INT_DCRC | SDMMC_INT_DRTO | \
SDMMC_INT_EBE)
#define SDCARD_DMAERROR_MASK (SDMMC_IDINTEN_FBE | SDMMC_IDINTEN_DU | \
SDMMC_IDINTEN_AIS)
#define SDCARD_TRANSFER_ALL (SDMMC_INT_DTO | SDMMC_INT_DCRC | SDMMC_INT_DRTO | \
SDMMC_INT_EBE | SDMMC_INT_TXDR | SDMMC_INT_RXDR | \
SDMMC_INT_SBE)
/* Event waiting interrupt mask bits */
#define SDCARD_INT_ERROR (SDMMC_INT_RE | SDMMC_INT_RCRC | SDMMC_INT_DCRC | \
SDMMC_INT_RTO | SDMMC_INT_DRTO | SDMMC_INT_HTO | \
SDMMC_INT_FRUN | SDMMC_INT_HLE | SDMMC_INT_SBE | \
SDMMC_INT_EBE)
#define SDCARD_INT_RESPERR (SDMMC_INT_RE | SDMMC_INT_RCRC | SDMMC_INT_RTO)
#ifdef CONFIG_MMCSD_HAVE_CARDDETECT
# define SDCARD_INT_CDET SDMMC_INT_CDET
@ -174,17 +173,16 @@
#define SDCARD_RESPDONE_STA (0)
#define SDCARD_CMDDONE_MASK (SDMMC_INT_CDONE)
#define SDCARD_RESPDONE_MASK (SDMMC_INT_RTO | SDMMC_INT_RCRC | SDMMC_INT_CDONE)
#define SDCARD_XFRDONE_MASK (SDMMC_INT_DTO)
#define SDCARD_RESPDONE_MASK (SDMMC_INT_CDONE | SDCARD_INT_RESPERR)
#define SDCARD_XFRDONE_MASK (0) /* Handled by transfer masks */
#define SDCARD_CMDDONE_ICR (SDMMC_INT_CDONE)
#define SDCARD_RESPDONE_ICR (SDMMC_INT_RTO | SDMMC_INT_RCRC | SDMMC_INT_CDONE)
#define SDCARD_CMDDONE_CLEAR (SDMMC_INT_CDONE)
#define SDCARD_RESPDONE_CLEAR (SDMMC_INT_CDONE | SDCARD_INT_RESPERR)
#define SDCARD_XFRDONE_ICR (SDMMC_INT_DTO | SDMMC_INT_DCRC | SDMMC_INT_DRTO | \
SDMMC_INT_FRUN | SDMMC_INT_SBE)
#define SDCARD_XFRDONE_CLEAR (SDCARD_TRANSFER_ALL)
#define SDCARD_WAITALL_ICR (SDCARD_CMDDONE_ICR | SDCARD_RESPDONE_ICR | \
SDCARD_XFRDONE_ICR)
#define SDCARD_WAITALL_CLEAR (SDCARD_CMDDONE_CLEAR | SDCARD_RESPDONE_CLEAR | \
SDCARD_XFRDONE_CLEAR)
/* Let's wait until we have both SD card transfer complete and DMA complete. */
@ -274,11 +272,14 @@ static void lpc54_takesem(struct lpc54_dev_s *priv);
static inline void lpc54_setclock(uint32_t clkdiv);
static inline void lpc54_sdcard_clock(bool enable);
static int lpc54_ciu_sendcmd(uint32_t cmd, uint32_t arg);
static void lpc54_configwaitints(struct lpc54_dev_s *priv, uint32_t waitmask,
static void lpc54_enable_ints(struct lpc54_dev_s *priv);
static void lpc54_disable_allints(struct lpc54_dev_s *priv);
static void lpc54_config_waitints(struct lpc54_dev_s *priv, uint32_t waitmask,
sdio_eventset_t waitevents, sdio_eventset_t wkupevents);
static void lpc54_configxfrints(struct lpc54_dev_s *priv, uint32_t xfrmask);
static void lpc54_config_xfrints(struct lpc54_dev_s *priv, uint32_t xfrmask);
#ifdef CONFIG_LPC54_SDMMC_DMA
static void lpc54_configdmaints(struct lpc54_dev_s *priv, uint32_t dmamask);
static void lpc54_config_dmaints(struct lpc54_dev_s *priv, uint32_t xfrmask,
uint32_t dmamask);
#endif
/* Data Transfer Helpers ****************************************************/
@ -632,7 +633,7 @@ static int lpc54_ciu_sendcmd(uint32_t cmd, uint32_t arg)
}
/****************************************************************************
* Name: lpc54_setupints
* Name: lpc54_enable_ints
*
* Description:
* Enable/disable SD card interrupts per functional settings.
@ -645,22 +646,24 @@ static int lpc54_ciu_sendcmd(uint32_t cmd, uint32_t arg)
*
****************************************************************************/
static void lpc54_setupints(struct lpc54_dev_s *priv)
static void lpc54_enable_ints(struct lpc54_dev_s *priv)
{
uint32_t regval;
#ifdef CONFIG_LPC54_SDMMC_DMA
mcinfo("waitmask=%04lx xfrmask=%04lx dmamask=%04lx\n",
mcinfo("waitmask=%04lx xfrmask=%04lx dmamask=%04lx RINTSTS=%08lx\n",
(unsigned long)priv->waitmask, (unsigned long)priv->xfrmask,
(unsigned long)priv->dmamask);
(unsigned long)priv->dmamask,
(unsigned long)lpc54_getreg(LPC54_SDMMC_RINTSTS));
/* Enable DMA-related interrupts */
lpc54_putreg(priv->dmamask, LPC54_SDMMC_IDINTEN);
#else
mcinfo("waitmask=%04lx xfrmask=%04lx\n",
(unsigned long)priv->waitmask, (unsigned long)priv->xfrmask);
mcinfo("waitmask=%04lx xfrmask=%04lx RINTSTS=%08lx\n",
(unsigned long)priv->waitmask, (unsigned long)priv->xfrmask,
(unsigned long)lpc54_getreg(LPC54_SDMMC_RINTSTS));
#endif
/* Enable SDMMC interrupts */
@ -670,14 +673,44 @@ static void lpc54_setupints(struct lpc54_dev_s *priv)
}
/****************************************************************************
* Name: lpc54_configwaitints
* Name: lpc54_disable_allints
*
* Description:
* Disable all SD card interrupts.
*
* Input Parameters:
* priv - A reference to the SD card device state structure
*
* Returned Value:
* None
*
****************************************************************************/
static void lpc54_disable_allints(struct lpc54_dev_s *priv)
{
#ifdef CONFIG_LPC54_SDMMC_DMA
/* Disable DMA-related interrupts */
lpc54_putreg(0, LPC54_SDMMC_IDINTEN);
priv->dmamask = 0;
#endif
/* Disable all SDMMC interrupts (except card detect) */
lpc54_putreg(SDCARD_INT_CDET, LPC54_SDMMC_INTMASK);
priv->waitmask = 0;
priv->xfrmask = 0;
}
/****************************************************************************
* Name: lpc54_config_waitints
*
* Description:
* Enable/disable SD card interrupts needed to suport the wait function
*
* Input Parameters:
* priv - A reference to the SD card device state structure
* waitmask - The set of bits in the SD card MASK register to set
* waitmask - The set of bits in the SD card INTMASK register to set
* waitevents - Waited for events
* wkupevent - Wake-up events
*
@ -686,9 +719,9 @@ static void lpc54_setupints(struct lpc54_dev_s *priv)
*
****************************************************************************/
static void lpc54_configwaitints(struct lpc54_dev_s *priv, uint32_t waitmask,
sdio_eventset_t waitevents,
sdio_eventset_t wkupevent)
static void lpc54_config_waitints(struct lpc54_dev_s *priv, uint32_t waitmask,
sdio_eventset_t waitevents,
sdio_eventset_t wkupevent)
{
irqstate_t flags;
@ -704,12 +737,12 @@ static void lpc54_configwaitints(struct lpc54_dev_s *priv, uint32_t waitmask,
priv->wkupevent = wkupevent;
priv->waitmask = waitmask;
lpc54_setupints(priv);
lpc54_enable_ints(priv);
leave_critical_section(flags);
}
/****************************************************************************
* Name: lpc54_configxfrints
* Name: lpc54_config_xfrints
*
* Description:
* Enable SD card interrupts needed to support the data transfer event
@ -723,22 +756,22 @@ static void lpc54_configwaitints(struct lpc54_dev_s *priv, uint32_t waitmask,
*
****************************************************************************/
static void lpc54_configxfrints(struct lpc54_dev_s *priv, uint32_t xfrmask)
static void lpc54_config_xfrints(struct lpc54_dev_s *priv, uint32_t xfrmask)
{
irqstate_t flags;
flags = enter_critical_section();
priv->xfrmask = xfrmask;
lpc54_setupints(priv);
lpc54_enable_ints(priv);
leave_critical_section(flags);
}
/****************************************************************************
* Name: lpc54_configdmaints
* Name: lpc54_config_dmaints
*
* Description:
* Enable DMA interrupts
* Enable DMA transfer interrupts
*
* Input Parameters:
* priv - A reference to the SD card device state structure
@ -750,13 +783,15 @@ static void lpc54_configxfrints(struct lpc54_dev_s *priv, uint32_t xfrmask)
****************************************************************************/
#ifdef CONFIG_LPC54_SDMMC_DMA
static void lpc54_configdmaints(struct lpc54_dev_s *priv, uint32_t dmamask)
static void lpc54_config_dmaints(struct lpc54_dev_s *priv, uint32_t xfrmask,
uint32_t dmamask)
{
irqstate_t flags;
flags = enter_critical_section();
priv->xfrmask = xfrmask;
priv->dmamask = dmamask;
lpc54_setupints(priv);
lpc54_enable_ints(priv);
leave_critical_section(flags);
}
@ -830,7 +865,7 @@ static void lpc54_endwait(struct lpc54_dev_s *priv, sdio_eventset_t wkupevent)
/* Disable event-related interrupts */
lpc54_configwaitints(priv, 0, 0, wkupevent);
lpc54_config_waitints(priv, 0, 0, wkupevent);
/* Wake up the waiting thread */
@ -863,7 +898,7 @@ static void lpc54_endtransfer(struct lpc54_dev_s *priv, sdio_eventset_t wkupeven
/* Disable all transfer related interrupts */
lpc54_configxfrints(priv, 0);
lpc54_config_xfrints(priv, 0);
/* Clearing pending interrupt status on all transfer related interrupts */
@ -970,7 +1005,7 @@ static int lpc54_sdmmc_interrupt(int irq, void *context, FAR void *arg)
}
#endif
/* Handle in progress, interrupt driven data transfers ****************/
/* Handle idata transfer events ***************************************/
pending = enabled & priv->xfrmask;
if (pending != 0)
@ -1042,13 +1077,15 @@ static int lpc54_sdmmc_interrupt(int irq, void *context, FAR void *arg)
}
}
/* Check for transfer errors */
/* Handle data block send/receive CRC failure */
if ((pending & SDMMC_INT_DCRC) != 0)
{
/* Terminate the transfer with an error */
mcerr("ERROR: Data block CRC failure, remaining: %d\n", priv->remaining);
mcerr("ERROR: Data CRC failure, pending=%08x remaining: %d\n",
pending, priv->remaining);
lpc54_putreg(SDMMC_INT_DCRC, LPC54_SDMMC_RINTSTS);
lpc54_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR);
}
@ -1059,7 +1096,8 @@ static int lpc54_sdmmc_interrupt(int irq, void *context, FAR void *arg)
{
/* Terminate the transfer with an error */
mcerr("ERROR: Data timeout, remaining: %d\n", priv->remaining);
mcerr("ERROR: Data timeout, pending=%08x remaining: %d\n",
pending, priv->remaining);
lpc54_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_TIMEOUT);
}
@ -1069,7 +1107,8 @@ static int lpc54_sdmmc_interrupt(int irq, void *context, FAR void *arg)
{
/* Terminate the transfer with an error */
mcerr("ERROR: RX FIFO overrun, remaining: %d\n", priv->remaining);
mcerr("ERROR: RX FIFO overrun, pending=%08x remaining: %d\n",
pending, priv->remaining);
lpc54_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR);
}
@ -1079,7 +1118,8 @@ static int lpc54_sdmmc_interrupt(int irq, void *context, FAR void *arg)
{
/* Terminate the transfer with an error */
mcerr("ERROR: TX FIFO underrun, remaining: %d\n", priv->remaining);
mcerr("ERROR: TX FIFO underrun, pending=%08x remaining: %d\n",
pending, priv->remaining);
lpc54_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR);
}
@ -1089,7 +1129,8 @@ static int lpc54_sdmmc_interrupt(int irq, void *context, FAR void *arg)
{
/* Terminate the transfer with an error */
mcerr("ERROR: Start bit, remaining: %d\n", priv->remaining);
mcerr("ERROR: Start bit, pending=%08x remaining: %d\n",
pending, priv->remaining);
lpc54_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR);
}
@ -1103,9 +1144,9 @@ static int lpc54_sdmmc_interrupt(int irq, void *context, FAR void *arg)
{
/* Finish the transfer */
lpc54_putreg(SDCARD_XFRDONE_CLEAR, LPC54_SDMMC_RINTSTS);
lpc54_endtransfer(priv, SDIOWAIT_TRANSFERDONE);
}
}
/* Handle wait events *************************************************/
@ -1113,9 +1154,9 @@ static int lpc54_sdmmc_interrupt(int irq, void *context, FAR void *arg)
pending = enabled & priv->waitmask;
if (pending != 0)
{
/* Is this a response completion event? */
/* Is this a command (plus response) completion event? */
if ((pending & SDMMC_INT_DTO) != 0)
if ((pending & SDMMC_INT_CDONE) != 0)
{
/* Yes.. Is their a thread waiting for response done? */
@ -1123,23 +1164,18 @@ static int lpc54_sdmmc_interrupt(int irq, void *context, FAR void *arg)
{
/* Yes.. wake the thread up */
lpc54_putreg(SDCARD_RESPDONE_ICR | SDCARD_CMDDONE_ICR,
lpc54_putreg(SDCARD_RESPDONE_CLEAR | SDCARD_CMDDONE_CLEAR,
LPC54_SDMMC_RINTSTS);
lpc54_endwait(priv, SDIOWAIT_RESPONSEDONE);
}
}
/* Is this a command completion event? */
/* NO.. Is their a thread waiting for command done? */
if ((pending & SDMMC_INT_CDONE) != 0)
{
/* Yes.. Is their a thread waiting for command done? */
if ((priv->waitevents & SDIOWAIT_RESPONSEDONE) != 0)
else if ((priv->waitevents & SDIOWAIT_CMDDONE) != 0)
{
/* Yes.. wake the thread up */
lpc54_putreg(SDCARD_CMDDONE_ICR, LPC54_SDMMC_RINTSTS);
lpc54_putreg(SDCARD_CMDDONE_CLEAR, LPC54_SDMMC_RINTSTS);
lpc54_endwait(priv, SDIOWAIT_CMDDONE);
}
}
@ -1223,10 +1259,6 @@ static void lpc54_reset(FAR struct sdio_dev_s *dev)
lpc54_putreg(SDMMC_BMOD_SWR, LPC54_SDMMC_BMOD);
/* Software Reset */
lpc54_putreg(SDMMC_BMOD_SWR, LPC54_SDMMC_BMOD);
/* Reset all blocks */
lpc54_putreg(SDMMC_CTRL_CNTLRRESET | SDMMC_CTRL_FIFORESET |
@ -1378,8 +1410,6 @@ static sdio_statset_t lpc54_status(FAR struct sdio_dev_s *dev)
static void lpc54_widebus(FAR struct sdio_dev_s *dev, bool wide)
{
struct lpc54_dev_s *priv = (struct lpc54_dev_s *)dev;
mcinfo("wide=%d\n", wide);
}
@ -1602,7 +1632,7 @@ static int lpc54_sendcmd(FAR struct sdio_dev_s *dev, uint32_t cmd,
/* Write the SD card CMD */
lpc54_putreg(SDCARD_RESPDONE_ICR | SDCARD_CMDDONE_ICR,
lpc54_putreg(SDCARD_RESPDONE_CLEAR | SDCARD_CMDDONE_CLEAR,
LPC54_SDMMC_RINTSTS);
lpc54_ciu_sendcmd(regval, arg);
@ -1689,7 +1719,7 @@ static int lpc54_recvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer,
/* Configure the transfer interrupts */
lpc54_configxfrints(priv, SDCARD_RECV_MASK);
lpc54_config_xfrints(priv, SDCARD_RECV_MASK);
return OK;
}
@ -1753,7 +1783,7 @@ static int lpc54_sendsetup(FAR struct sdio_dev_s *dev, FAR const uint8_t *buffer
/* Configure the transfer interrupts */
lpc54_configxfrints(priv, SDCARD_SEND_MASK);
lpc54_config_xfrints(priv, SDCARD_SEND_MASK);
return OK;
}
@ -1782,17 +1812,13 @@ static int lpc54_cancel(FAR struct sdio_dev_s *dev)
/* Disable all transfer- and event- related interrupts */
lpc54_configxfrints(priv, 0);
lpc54_configwaitints(priv, 0, 0, 0);
#ifdef CONFIG_LPC54_SDMMC_DMA
lpc54_configdmaints(priv, 0);
#endif
lpc54_disable_allints(priv);
/* Clearing pending interrupt status on all transfer- and event- related
* interrupts
*/
lpc54_putreg(SDCARD_WAITALL_ICR, LPC54_SDMMC_RINTSTS);
lpc54_putreg(SDCARD_WAITALL_CLEAR, LPC54_SDMMC_RINTSTS);
/* Cancel any watchdog timeout */
@ -1837,7 +1863,7 @@ static int lpc54_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd)
case MMCSD_R1B_RESPONSE:
case MMCSD_R2_RESPONSE:
case MMCSD_R6_RESPONSE:
events = SDCARD_RESPDONE_STA;
events = (SDCARD_CMDDONE_STA | SDCARD_RESPDONE_STA);
timeout = SDCARD_LONGTIMEOUT;
break;
@ -1847,7 +1873,7 @@ static int lpc54_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd)
case MMCSD_R3_RESPONSE:
case MMCSD_R7_RESPONSE:
events = SDCARD_RESPDONE_STA;
events = (SDCARD_CMDDONE_STA | SDCARD_RESPDONE_STA);
timeout = SDCARD_CMDTIMEOUT;
break;
@ -1855,8 +1881,6 @@ static int lpc54_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd)
return -EINVAL;
}
events |= SDCARD_CMDDONE_STA;
mcinfo("cmd: %04x events: %04x STATUS: %08x RINTSTS: %08x\n",
cmd, events, lpc54_getreg(LPC54_SDMMC_STATUS),
lpc54_getreg(LPC54_SDMMC_RINTSTS));
@ -1872,7 +1896,7 @@ static int lpc54_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd)
lpc54_getreg(LPC54_SDMMC_RINTSTS));
return -ETIMEDOUT;
}
else if ((lpc54_getreg(LPC54_SDMMC_RINTSTS) & SDCARD_INT_ERROR) != 0)
else if ((lpc54_getreg(LPC54_SDMMC_RINTSTS) & SDCARD_INT_RESPERR) != 0)
{
mcerr("ERROR: SDMMC failure cmd: %04x events: %04x STA: %08x RINTSTS: %08x\n",
cmd, events, lpc54_getreg(LPC54_SDMMC_STATUS),
@ -1881,7 +1905,7 @@ static int lpc54_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd)
}
}
lpc54_putreg(SDCARD_CMDDONE_ICR, LPC54_SDMMC_RINTSTS);
lpc54_putreg(SDCARD_CMDDONE_CLEAR, LPC54_SDMMC_RINTSTS);
return OK;
}
@ -1973,16 +1997,20 @@ static int lpc54_recvshortcrc(FAR struct sdio_dev_s *dev, uint32_t cmd,
}
}
/* Clear all pending message completion events and return the R1/R6 response */
/* Clear all pending message completion events and return the R1/R6
* response.
*/
lpc54_putreg(SDCARD_RESPDONE_ICR | SDCARD_CMDDONE_ICR, LPC54_SDMMC_RINTSTS);
lpc54_putreg(SDCARD_RESPDONE_CLEAR | SDCARD_CMDDONE_CLEAR,
LPC54_SDMMC_RINTSTS);
*rshort = lpc54_getreg(LPC54_SDMMC_RESP0);
mcinfo("CRC=%04x\n", *rshort);
return ret;
}
static int lpc54_recvlong(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t rlong[4])
static int lpc54_recvlong(FAR struct sdio_dev_s *dev, uint32_t cmd,
uint32_t rlong[4])
{
uint32_t regval;
int ret = OK;
@ -2026,7 +2054,8 @@ static int lpc54_recvlong(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t rlo
/* Return the long response */
lpc54_putreg(SDCARD_RESPDONE_ICR | SDCARD_CMDDONE_ICR, LPC54_SDMMC_RINTSTS);
lpc54_putreg(SDCARD_RESPDONE_CLEAR | SDCARD_CMDDONE_CLEAR,
LPC54_SDMMC_RINTSTS);
if (rlong)
{
rlong[0] = lpc54_getreg(LPC54_SDMMC_RESP3);
@ -2078,7 +2107,8 @@ static int lpc54_recvshort(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t *r
}
}
lpc54_putreg(SDCARD_RESPDONE_ICR | SDCARD_CMDDONE_ICR, LPC54_SDMMC_RINTSTS);
lpc54_putreg(SDCARD_RESPDONE_CLEAR | SDCARD_CMDDONE_CLEAR,
LPC54_SDMMC_RINTSTS);
if (rshort)
{
*rshort = lpc54_getreg(LPC54_SDMMC_RESP0);
@ -2094,7 +2124,8 @@ static int lpc54_recvnotimpl(FAR struct sdio_dev_s *dev, uint32_t cmd,
{
mcinfo("cmd=%04x\n", cmd);
lpc54_putreg(SDCARD_RESPDONE_ICR | SDCARD_CMDDONE_ICR, LPC54_SDMMC_RINTSTS);
lpc54_putreg(SDCARD_RESPDONE_CLEAR | SDCARD_CMDDONE_CLEAR,
LPC54_SDMMC_RINTSTS);
return -ENOSYS;
}
@ -2133,7 +2164,7 @@ static void lpc54_waitenable(FAR struct sdio_dev_s *dev,
/* Disable event-related interrupts */
lpc54_configwaitints(priv, 0, 0, 0);
lpc54_config_waitints(priv, 0, 0, 0);
/* Select the interrupt mask that will give us the appropriate wakeup
* interrupts.
@ -2157,7 +2188,7 @@ static void lpc54_waitenable(FAR struct sdio_dev_s *dev,
/* Enable event-related interrupts */
lpc54_configwaitints(priv, waitmask, eventset, 0);
lpc54_config_waitints(priv, waitmask, eventset, 0);
}
/****************************************************************************
@ -2256,12 +2287,13 @@ static sdio_eventset_t lpc54_eventwait(FAR struct sdio_dev_s *dev,
}
}
/* Disable event-related interrupts */
/* Disable all transfer- and event- related interrupts */
lpc54_configwaitints(priv, 0, 0, 0);
lpc54_disable_allints(priv);
errout:
leave_critical_section(flags);
mcinfo("wkupevent=%04x\n", wkupevent);
return wkupevent;
}
@ -2477,11 +2509,7 @@ static int lpc54_dmarecvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer,
/* Setup DMA error interrupts */
lpc54_putreg(SDMMC_INT_ALL, LPC54_SDMMC_RINTSTS);
lpc54_putreg(SDMMC_IDINTEN_ALL, LPC54_SDMMC_IDSTS);
lpc54_configxfrints(priv, SDCARD_DMARECV_MASK);
lpc54_configdmaints(priv, SDCARD_DMAERROR_MASK);
lpc54_config_dmaints(priv, SDCARD_DMARECV_MASK, SDCARD_DMAERROR_MASK);
return OK;
}
#endif
@ -2579,11 +2607,7 @@ static int lpc54_dmasendsetup(FAR struct sdio_dev_s *dev,
/* Setup DMA error interrupts */
lpc54_putreg(SDMMC_INT_ALL, LPC54_SDMMC_RINTSTS);
lpc54_putreg(SDMMC_IDINTEN_ALL, LPC54_SDMMC_IDSTS);
lpc54_configxfrints(priv, SDCARD_DMASEND_MASK);
lpc54_configdmaints(priv, SDCARD_DMAERROR_MASK);
lpc54_config_dmaints(priv, SDCARD_DMASEND_MASK, SDCARD_DMAERROR_MASK);
return OK;
}
#endif