Finish event wait logic
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2265 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
7ef8423ad0
commit
29395f7fd1
@ -115,8 +115,44 @@
|
||||
/* FIFO sizes */
|
||||
|
||||
#define SDIO_HALFFIFO_WORDS (8)
|
||||
#define SDIO_HALFFIFO_BYTES (8*4)
|
||||
#define SDIO_HALFFIFO_BYTES (8*4)
|
||||
|
||||
/* Data transfer interrupt mask bits */
|
||||
|
||||
#define SDIO_RECV_MASK (SDIO_MASK_DCRCFAILIE|SDIO_MASK_DTIMEOUTIE|\
|
||||
SDIO_MASK_DATAENDIE|SDIO_MASK_RXOVERRIE|\
|
||||
SDIO_MASK_RXFIFOHFIE|SDIO_MASK_STBITERRIE)
|
||||
#define SDIO_SEND_MASK (SDIO_MASK_DCRCFAILIE|SDIO_MASK_DTIMEOUTIE|\
|
||||
SDIO_MASK_DATAENDIE|SDIO_MASK_TXUNDERRIE|\
|
||||
SDIO_MASK_TXFIFOHEIE|SDIO_MASK_STBITERRIE)
|
||||
#define SDIO_DMARECV_MASK (SDIO_MASK_DCRCFAILIE|SDIO_MASK_DTIMEOUTIE|\
|
||||
SDIO_MASK_DATAENDIE|SDIO_MASK_RXOVERRIE|\
|
||||
SDIO_MASK_STBITERRIE)
|
||||
#define SDIO_DMASEND_MASK (SDIO_MASK_DCRCFAILIE|SDIO_MASK_DTIMEOUTIE|\
|
||||
SDIO_MASK_DATAENDIE|SDIO_MASK_TXUNDERRIE|\
|
||||
SDIO_MASK_STBITERRIE)
|
||||
|
||||
/* Event waiting interrupt mask bits */
|
||||
|
||||
#define SDIO_CMDDONE_STA (SDIO_STA_CMDSENT)
|
||||
#define SDIO_CRCRESP_STA (SDIO_STA_CTIMEOUT|SDIO_STA_CCRCFAIL|SDIO_STA_CMDREND)
|
||||
#define SDIO_RESPDONE_STA (SDIO_STA_CTIMEOUT|SDIO_STA_CMDREND)
|
||||
#define SDIO_XFRDONE_STA (0)
|
||||
|
||||
#define SDIO_CMDDONE_MASK (SDIO_MASK_CMDSENTIE)
|
||||
#define SDIO_CRCRESP_MASK (SDIO_MASK_CCRCFAILIE|SDIO_MASK_CTIMEOUTIE|\
|
||||
SDIO_MASK_CMDRENDIE)
|
||||
#define SDIO_RESPDONE_MASK (SDIO_MASK_CTIMEOUTIE|SDIO_MASK_CMDRENDIE)
|
||||
#define SDIO_XFRDONE_MASK (0)
|
||||
|
||||
#define SDIO_CMDDONE_ICR (SDIO_ICR_CMDSENTC)
|
||||
#define SDIO_CRCRESP_ICR (SDIO_ICR_CTIMEOUTC|SDIO_ICR_CCRCFAILC|SDIO_ICR_CMDRENDC)
|
||||
#define SDIO_RESPDONE_ICR (SDIO_ICR_CTIMEOUTC|SDIO_ICR_CMDRENDC)
|
||||
#define SDIO_XFRDONE_ICR (0)
|
||||
|
||||
#define SDIO_WAITALL_ICR (SDIO_ICR_CMDSENTC|SDIO_ICR_CTIMEOUTC|\
|
||||
SDIO_ICR_CCRCFAILC|SDIO_ICR_CMDRENDC)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
@ -131,6 +167,7 @@ struct stm32_dev_s
|
||||
|
||||
sem_t waitsem; /* Implements event waiting */
|
||||
sdio_eventset_t waitevents; /* Set of events to be waited for */
|
||||
uint32 waitmask; /* Interrupt enables for event waiting */
|
||||
volatile sdio_eventset_t wkupevent; /* The event that caused the wakeup */
|
||||
sdio_eventset_t cbevents; /* Set of events to be cause callbacks */
|
||||
sdio_mediachange_t callback; /* Registered callback function */
|
||||
@ -141,6 +178,7 @@ struct stm32_dev_s
|
||||
uint32 *buffer; /* Address of current R/W buffer */
|
||||
size_t remaining; /* Number of bytes remaining in the transfer */
|
||||
int result; /* Result of the transfer */
|
||||
uint32 xfrmask; /* Interrupt enables for data transfer */
|
||||
|
||||
/* DMA data transfer support */
|
||||
|
||||
@ -160,8 +198,9 @@ struct stm32_dev_s
|
||||
static void stm32_takesem(struct stm32_dev_s *priv);
|
||||
#define stm32_givesem(priv) (sem_post(&priv->waitsem))
|
||||
static inline void stm32_setclkcr(uint32 clkcr);
|
||||
static inline void stm32_enableint(uint32 bitset);
|
||||
static inline void stm32_disableint(uint32 bitset);
|
||||
static void stm32_configwaitints(struct stm32_dev_s *priv, uint32 waitmask,
|
||||
ubyte waitevents, ubyte wkupevents);
|
||||
static void stm32_configxfrints(struct stm32_dev_s *priv, uint32 xfrmask);
|
||||
static void stm32_setpwrctrl(uint32 pwrctrl);
|
||||
static inline uint32 stm32_getpwrctrl(void);
|
||||
static inline void stm32_clkenable(void);
|
||||
@ -180,6 +219,7 @@ static void stm32_dataconfig(uint32 timeout, uint32 dlen, uint32 dctrl);
|
||||
static void stm32_datadisable(void);
|
||||
static void stm32_sendfifo(struct stm32_dev_s *priv);
|
||||
static void stm32_recvfifo(struct stm32_dev_s *priv);
|
||||
static void stm32_endwait(struct stm32_dev_s *priv, uint32 eventset);
|
||||
static void stm32_endtransfer(struct stm32_dev_s *priv, int result);
|
||||
|
||||
/* Interrupt Handling *******************************************************/
|
||||
@ -351,49 +391,58 @@ static inline void stm32_setclkcr(uint32 clkcr)
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_enableint
|
||||
* Name: stm32_configwaitints
|
||||
*
|
||||
* Description:
|
||||
* Enable SDIO interrupts
|
||||
* Enable/disable SDIO interrupts needed to suport the wait function
|
||||
*
|
||||
* Input Parameters:
|
||||
* bitset - The set of bits in the SDIO MASK register to set
|
||||
* priv - A reference to the SDIO device state structure
|
||||
* waitmask - The set of bits in the SDIO MASK register to set
|
||||
* waitevent - Waited for events
|
||||
* wkupevent - Wake-up events
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void stm32_enableint(uint32 bitset)
|
||||
{
|
||||
uint32 regval;
|
||||
regval = getreg32(STM32_SDIO_MASK);
|
||||
regval |= bitset;
|
||||
putreg32(regval, STM32_SDIO_MASK);
|
||||
}
|
||||
|
||||
|
||||
static void stm32_configwaitints(struct stm32_dev_s *priv, uint32 waitmask,
|
||||
ubyte waitevents, ubyte wkupevent)
|
||||
{
|
||||
irqstate_t flags;
|
||||
flags = irqsave();
|
||||
priv->waitevents = waitevents;
|
||||
priv->wkupevent = wkupevent;
|
||||
priv->waitmask = waitmask;
|
||||
putreg32(priv->xfrmask | priv->waitmask, STM32_SDIO_MASK);
|
||||
irqrestore(flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_disableint
|
||||
* Name: stm32_configxfrints
|
||||
*
|
||||
* Description:
|
||||
* Disable SDIO interrupts
|
||||
* Enable SDIO interrupts needed to support the data transfer event
|
||||
*
|
||||
* Input Parameters:
|
||||
* bitset - The set of bits in the SDIO MASK register to clear
|
||||
* Input Parameters:
|
||||
* priv - A reference to the SDIO device state structure
|
||||
* xfrmask - The set of bits in the SDIO MASK register to set
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void stm32_disableint(uint32 bitset)
|
||||
{
|
||||
uint32 regval;
|
||||
regval = getreg32(STM32_SDIO_MASK);
|
||||
regval &= ~bitset;
|
||||
putreg32(regval, STM32_SDIO_MASK);
|
||||
}
|
||||
|
||||
static void stm32_configxfrints(struct stm32_dev_s *priv, uint32 xfrmask)
|
||||
{
|
||||
irqstate_t flags;
|
||||
flags = irqsave();
|
||||
priv->xfrmask = xfrmask;
|
||||
putreg32(priv->xfrmask | priv->waitmask, STM32_SDIO_MASK);
|
||||
irqrestore(flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_setpwrctrl
|
||||
*
|
||||
@ -681,6 +730,32 @@ static void stm32_recvfifo(struct stm32_dev_s *priv)
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_endwait
|
||||
*
|
||||
* Description:
|
||||
* Wake up a waiting thread if the waited-for event has occurred.
|
||||
*
|
||||
* Input Parameters:
|
||||
* priv - An instance of the SDIO device interface
|
||||
* result - The result status of the transfer
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void stm32_endwait(struct stm32_dev_s *priv, uint32 eventset)
|
||||
{
|
||||
/* Yes.. Disable event-related interrupts */
|
||||
|
||||
stm32_configwaitints(priv, 0, 0, eventset);
|
||||
|
||||
/* Wake up the waiting thread */
|
||||
|
||||
stm32_givesem(priv);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_endtransfer
|
||||
*
|
||||
@ -688,7 +763,7 @@ static void stm32_recvfifo(struct stm32_dev_s *priv)
|
||||
* Terminate a transfer with the provided status
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - An instance of the SDIO device interface
|
||||
* priv - An instance of the SDIO device interface
|
||||
* result - The result status of the transfer
|
||||
*
|
||||
* Returned Value:
|
||||
@ -698,12 +773,9 @@ static void stm32_recvfifo(struct stm32_dev_s *priv)
|
||||
|
||||
static void stm32_endtransfer(struct stm32_dev_s *priv, int result)
|
||||
{
|
||||
/* Disable interrupts */
|
||||
/* Disable all transfer related interrupts */
|
||||
|
||||
stm32_disableint(SDIO_MASK_DCRCFAILIE|SDIO_MASK_DTIMEOUTIE|
|
||||
SDIO_MASK_DATAENDIE|SDIO_MASK_TXFIFOHEIE|
|
||||
SDIO_MASK_RXFIFOHFIE|SDIO_MASK_TXUNDERRIE|
|
||||
SDIO_MASK_RXOVERRIE|SDIO_MASK_STBITERRIE);
|
||||
stm32_configxfrints(priv, 0);
|
||||
|
||||
/* Mark the transfer finished with the provided status */
|
||||
|
||||
@ -714,10 +786,9 @@ static void stm32_endtransfer(struct stm32_dev_s *priv, int result)
|
||||
|
||||
if ((priv->waitevents & SDIOWAIT_TRANSFERDONE) != 0)
|
||||
{
|
||||
/* Yes, wake up the waiting thread */
|
||||
/* Yes.. wake up any waiting threads */
|
||||
|
||||
priv->wkupevent = SDIOWAIT_TRANSFERDONE;
|
||||
stm32_givesem(priv);
|
||||
stm32_endwait(priv, SDIOWAIT_TRANSFERDONE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -742,7 +813,8 @@ static void stm32_endtransfer(struct stm32_dev_s *priv, int result)
|
||||
static int stm32_interrupt(int irq, void *context)
|
||||
{
|
||||
struct stm32_dev_s *priv = &g_sdiodev;
|
||||
uint32 sta;
|
||||
uint32 enabled;
|
||||
uint32 pending;
|
||||
|
||||
/* Loop while there are pending interrupts. Check the SDIO status
|
||||
* register. Mask out all bits that don't correspond to enabled
|
||||
@ -751,111 +823,151 @@ static int stm32_interrupt(int irq, void *context)
|
||||
* bits remaining, then we have work to do here.
|
||||
*/
|
||||
|
||||
while ((sta = getreg32(STM32_SDIO_STA) & getreg32(STM32_SDIO_MASK)) != 0)
|
||||
while ((enabled = getreg32(STM32_SDIO_STA) & getreg32(STM32_SDIO_MASK)) != 0)
|
||||
{
|
||||
/* Handle in progress, interrupt driven data transfers */
|
||||
/* Handle in progress, interrupt driven data transfers ****************/
|
||||
|
||||
#ifdef CONFIG_SDIO_DMA
|
||||
if (!priv->dmamode)
|
||||
#endif
|
||||
{
|
||||
/* Is the RX FIFO half full or more? Is so then we must be
|
||||
* processing a receive transaction.
|
||||
*/
|
||||
|
||||
if ((sta & SDIO_STA_RXFIFOHF) != 0)
|
||||
{
|
||||
/* Receive data from the RX FIFO */
|
||||
|
||||
stm32_recvfifo(priv);
|
||||
}
|
||||
|
||||
/* Otherwise, Is the transmit FIFO half empty or less? If so we must
|
||||
* be processing a send transaction. NOTE: We can't be processing
|
||||
* both!
|
||||
*/
|
||||
|
||||
else if ((sta & SDIO_STA_TXFIFOHE) != 0)
|
||||
{
|
||||
/* Send data via the TX FIFO */
|
||||
|
||||
stm32_sendfifo(priv);
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle data end events */
|
||||
|
||||
if ((sta & SDIO_STA_DATAEND) != 0)
|
||||
pending = enabled & priv->xfrmask;
|
||||
if (pending != 0)
|
||||
{
|
||||
/* Handle any data remaining the RX FIFO. If the RX FIFO is
|
||||
* less than half full at the end of the transfer, then no
|
||||
* half-full interrupt will be received.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_SDIO_DMA
|
||||
if (!priv->dmamode)
|
||||
#endif
|
||||
{
|
||||
/* Is the RX FIFO half full or more? Is so then we must be
|
||||
* processing a receive transaction.
|
||||
*/
|
||||
|
||||
if ((pending & SDIO_STA_RXFIFOHF) != 0)
|
||||
{
|
||||
/* Receive data from the RX FIFO */
|
||||
|
||||
stm32_recvfifo(priv);
|
||||
}
|
||||
|
||||
/* Otherwise, Is the transmit FIFO half empty or less? If so we must
|
||||
* be processing a send transaction. NOTE: We can't be processing
|
||||
* both!
|
||||
*/
|
||||
|
||||
else if ((pending & SDIO_STA_TXFIFOHE) != 0)
|
||||
{
|
||||
/* Send data via the TX FIFO */
|
||||
|
||||
stm32_sendfifo(priv);
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle data end events */
|
||||
|
||||
if ((pending & SDIO_STA_DATAEND) != 0)
|
||||
{
|
||||
/* Handle any data remaining the RX FIFO. If the RX FIFO is
|
||||
* less than half full at the end of the transfer, then no
|
||||
* half-full interrupt will be received.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_SDIO_DMA
|
||||
if (!priv->dmamode)
|
||||
#endif
|
||||
{
|
||||
/* Receive data from the RX FIFO */
|
||||
|
||||
stm32_recvfifo(priv);
|
||||
}
|
||||
|
||||
/* Then terminate the transfer */
|
||||
|
||||
putreg32(SDIO_ICR_DATAENDC, STM32_SDIO_ICR);
|
||||
stm32_endtransfer(priv, OK);
|
||||
}
|
||||
|
||||
/* Handler data block send/receive CRC failure */
|
||||
|
||||
else if ((pending & SDIO_STA_DCRCFAIL) != 0)
|
||||
{
|
||||
/* Terminate the transfer with an error */
|
||||
|
||||
putreg32(SDIO_ICR_DCRCFAILC, STM32_SDIO_ICR);
|
||||
stm32_endtransfer(priv, -EIO);
|
||||
}
|
||||
|
||||
/* Handle data timeout error */
|
||||
|
||||
else if ((pending & SDIO_STA_DTIMEOUT) != 0)
|
||||
{
|
||||
/* Receive data from the RX FIFO */
|
||||
/* Terminate the transfer with an error */
|
||||
|
||||
putreg32(SDIO_ICR_DTIMEOUTC, STM32_SDIO_ICR);
|
||||
stm32_endtransfer(priv, -ETIMEDOUT);
|
||||
}
|
||||
|
||||
stm32_recvfifo(priv);
|
||||
/* Handle RX FIFO overrun error */
|
||||
|
||||
else if ((pending & SDIO_STA_RXOVERR) != 0)
|
||||
{
|
||||
/* Terminate the transfer with an error */
|
||||
|
||||
putreg32(SDIO_ICR_RXOVERRC, STM32_SDIO_ICR);
|
||||
stm32_endtransfer(priv, -EOVERFLOW);
|
||||
}
|
||||
|
||||
/* Handle TX FIFO underrun error */
|
||||
|
||||
else if ((pending & SDIO_STA_TXUNDERR) != 0)
|
||||
{
|
||||
/* Terminate the transfer with an error */
|
||||
|
||||
putreg32(SDIO_ICR_TXUNDERRC, STM32_SDIO_ICR);
|
||||
stm32_endtransfer(priv, -EOVERFLOW);
|
||||
}
|
||||
|
||||
/* Handle start bit error */
|
||||
|
||||
else if ((pending & SDIO_STA_STBITERR) != 0)
|
||||
{
|
||||
/* Terminate the transfer with an error */
|
||||
|
||||
putreg32(SDIO_ICR_STBITERRC, STM32_SDIO_ICR);
|
||||
stm32_endtransfer(priv, -EIO);
|
||||
}
|
||||
|
||||
/* Then terminate the transfer */
|
||||
|
||||
putreg32(SDIO_ICR_DATAENDC, STM32_SDIO_ICR);
|
||||
stm32_endtransfer(priv, OK);
|
||||
}
|
||||
|
||||
/* Handler data block send/receive CRC failure */
|
||||
|
||||
else if ((sta & SDIO_STA_DCRCFAIL) != 0)
|
||||
/* Handle wait events *************************************************/
|
||||
|
||||
pending = enabled & priv->waitmask;
|
||||
if (pending != 0)
|
||||
{
|
||||
/* Terminate the transfer with an error */
|
||||
|
||||
putreg32(SDIO_ICR_DCRCFAILC, STM32_SDIO_ICR);
|
||||
stm32_endtransfer(priv, -EIO);
|
||||
}
|
||||
/* Is this a response completion event? */
|
||||
|
||||
/* Handle data timeout error */
|
||||
|
||||
else if ((sta & SDIO_STA_DTIMEOUT) != 0)
|
||||
{
|
||||
/* Terminate the transfer with an error */
|
||||
|
||||
putreg32(SDIO_ICR_DTIMEOUTC, STM32_SDIO_ICR);
|
||||
stm32_endtransfer(priv, -ETIMEDOUT);
|
||||
}
|
||||
if ((pending & SDIO_CRCRESP_STA) != 0)
|
||||
{
|
||||
/* Yes.. Is their a thread waiting for response done? */
|
||||
|
||||
/* Handle RX FIFO overrun error */
|
||||
|
||||
else if ((sta & SDIO_STA_RXOVERR) != 0)
|
||||
{
|
||||
/* Terminate the transfer with an error */
|
||||
|
||||
putreg32(SDIO_ICR_RXOVERRC, STM32_SDIO_ICR);
|
||||
stm32_endtransfer(priv, -EOVERFLOW);
|
||||
}
|
||||
if ((priv->waitevents & SDIOWAIT_RESPONSEDONE) != 0)
|
||||
{
|
||||
/* Yes.. wake the thread up */
|
||||
|
||||
/* Handle TX FIFO underrun error */
|
||||
|
||||
else if ((sta & SDIO_STA_TXUNDERR) != 0)
|
||||
{
|
||||
/* Terminate the transfer with an error */
|
||||
|
||||
putreg32(SDIO_ICR_TXUNDERRC, STM32_SDIO_ICR);
|
||||
stm32_endtransfer(priv, -EOVERFLOW);
|
||||
}
|
||||
putreg32(SDIO_CRCRESP_ICR, STM32_SDIO_ICR);
|
||||
stm32_endwait(priv, SDIOWAIT_RESPONSEDONE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle start bit error */
|
||||
|
||||
else if ((sta & SDIO_STA_STBITERR) != 0)
|
||||
{
|
||||
/* Terminate the transfer with an error */
|
||||
|
||||
putreg32(SDIO_ICR_STBITERRC, STM32_SDIO_ICR);
|
||||
stm32_endtransfer(priv, -EIO);
|
||||
}
|
||||
/* Is this a command completion event? */
|
||||
|
||||
if ((pending & SDIO_CMDDONE_STA) != 0)
|
||||
{
|
||||
/* Yes.. Is their a thread waiting for command done? */
|
||||
|
||||
if ((priv->waitevents & SDIOWAIT_RESPONSEDONE) != 0)
|
||||
{
|
||||
/* Yes.. wake the thread up */
|
||||
|
||||
putreg32(SDIO_CMDDONE_ICR, STM32_SDIO_ICR);
|
||||
stm32_endwait(priv, SDIOWAIT_CMDDONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
@ -1102,9 +1214,7 @@ static int stm32_recvsetup(FAR struct sdio_dev_s *dev, FAR ubyte *buffer,
|
||||
|
||||
/* And enable interrupts */
|
||||
|
||||
stm32_enableint(SDIO_MASK_DCRCFAILIE|SDIO_MASK_DTIMEOUTIE|
|
||||
SDIO_MASK_DATAENDIE|SDIO_MASK_RXOVERRIE|
|
||||
SDIO_MASK_RXFIFOHFIE|SDIO_MASK_STBITERRIE);
|
||||
stm32_configxfrints(priv, SDIO_RECV_MASK);
|
||||
return OK;
|
||||
}
|
||||
|
||||
@ -1156,9 +1266,7 @@ static int stm32_sendsetup(FAR struct sdio_dev_s *dev, FAR const ubyte *buffer,
|
||||
|
||||
/* Enable TX interrrupts */
|
||||
|
||||
stm32_enableint(SDIO_MASK_DCRCFAILIE|SDIO_MASK_DTIMEOUTIE|
|
||||
SDIO_MASK_DATAENDIE|SDIO_MASK_TXUNDERRIE|
|
||||
SDIO_MASK_TXFIFOHEIE|SDIO_MASK_STBITERRIE);
|
||||
stm32_configxfrints(priv, SDIO_SEND_MASK);
|
||||
return OK;
|
||||
}
|
||||
|
||||
@ -1179,21 +1287,22 @@ static int stm32_sendsetup(FAR struct sdio_dev_s *dev, FAR const ubyte *buffer,
|
||||
|
||||
static int stm32_waitresponse(FAR struct sdio_dev_s *dev, uint32 cmd)
|
||||
{
|
||||
sint32 timeout = SDIO_LONGTIMEOUT;
|
||||
sint32 timeout;
|
||||
uint32 events;
|
||||
|
||||
switch (cmd & MMCSD_RESPONSE_MASK)
|
||||
{
|
||||
case MMCSD_NO_RESPONSE:
|
||||
events = SDIO_CMDDONE_STA;
|
||||
timeout = SDIO_CMDTIMEOUT;
|
||||
events = SDIO_STA_CMDSENT;
|
||||
break;
|
||||
|
||||
case MMCSD_R1_RESPONSE:
|
||||
case MMCSD_R1B_RESPONSE:
|
||||
case MMCSD_R2_RESPONSE:
|
||||
case MMCSD_R6_RESPONSE:
|
||||
events = SDIO_STA_CTIMEOUT|SDIO_STA_CCRCFAIL|SDIO_STA_CMDREND;
|
||||
events = SDIO_CRCRESP_STA;
|
||||
timeout = SDIO_LONGTIMEOUT;
|
||||
break;
|
||||
|
||||
case MMCSD_R4_RESPONSE:
|
||||
@ -1202,7 +1311,7 @@ static int stm32_waitresponse(FAR struct sdio_dev_s *dev, uint32 cmd)
|
||||
|
||||
case MMCSD_R3_RESPONSE:
|
||||
case MMCSD_R7_RESPONSE:
|
||||
events = SDIO_STA_CTIMEOUT|SDIO_STA_CMDREND;
|
||||
events = SDIO_RESPDONE_STA;
|
||||
timeout = SDIO_CMDTIMEOUT;
|
||||
break;
|
||||
|
||||
@ -1472,13 +1581,38 @@ static void stm32_waitenable(FAR struct sdio_dev_s *dev,
|
||||
sdio_eventset_t eventset)
|
||||
{
|
||||
struct stm32_dev_s *priv = (struct stm32_dev_s*)dev;
|
||||
|
||||
/* This odd sequence avoids race conditions */
|
||||
|
||||
uint32 waitmask;
|
||||
|
||||
DEBUGASSERT(priv != NULL);
|
||||
priv->waitevents = 0;
|
||||
priv->wkupevent = 0;
|
||||
priv->waitevents = eventset;
|
||||
|
||||
/* Disable event-related interrupts */
|
||||
|
||||
stm32_configwaitints(priv, 0, 0, 0);
|
||||
|
||||
/* Select the interrupt mask that will give us the appropriate wakeup
|
||||
* interrupts.
|
||||
*/
|
||||
|
||||
waitmask = 0;
|
||||
if ((eventset & SDIOWAIT_CMDDONE) != 0)
|
||||
{
|
||||
waitmask |= SDIO_CMDDONE_MASK;
|
||||
}
|
||||
|
||||
if ((eventset & SDIOWAIT_RESPONSEDONE) != 0)
|
||||
{
|
||||
waitmask |= SDIO_CRCRESP_MASK;
|
||||
}
|
||||
|
||||
if ((eventset & SDIOWAIT_TRANSFERDONE) != 0)
|
||||
{
|
||||
waitmask |= SDIO_XFRDONE_MASK;
|
||||
}
|
||||
|
||||
/* Enable event-related interrupts */
|
||||
|
||||
putreg32(SDIO_WAITALL_ICR, STM32_SDIO_ICR);
|
||||
stm32_configwaitints(priv, waitmask, eventset, 0);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -1534,10 +1668,9 @@ static ubyte stm32_eventwait(FAR struct sdio_dev_s *dev, uint32 timeout)
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear all enabled wait events before returning */
|
||||
/* Disable event-related interrupts */
|
||||
|
||||
priv->waitevents = 0;
|
||||
priv->wkupevent = 0;
|
||||
stm32_configwaitints(priv, 0, 0, 0);
|
||||
return wkupevent;
|
||||
}
|
||||
|
||||
@ -1702,9 +1835,7 @@ static int stm32_dmarecvsetup(FAR struct sdio_dev_s *dev, FAR ubyte *buffer,
|
||||
|
||||
/* Configure the RX DMA */
|
||||
|
||||
stm32_enableint(SDIO_MASK_DCRCFAILIE|SDIO_MASK_DTIMEOUTIE|
|
||||
SDIO_MASK_DATAENDIE|SDIO_MASK_RXOVERRIE|
|
||||
SDIO_MASK_STBITERRIE);
|
||||
stm32_configxfrints(priv, SDIO_DMARECV_MASK);
|
||||
|
||||
putreg32(1, SDIO_DCTRL_DMAEN_BB);
|
||||
stm32_dmasetup(priv->dma, STM32_SDIO_FIFO, (uint32)buffer,
|
||||
@ -1771,9 +1902,7 @@ static int stm32_dmasendsetup(FAR struct sdio_dev_s *dev,
|
||||
|
||||
/* Enable TX interrrupts */
|
||||
|
||||
stm32_enableint(SDIO_MASK_DCRCFAILIE|SDIO_MASK_DTIMEOUTIE|
|
||||
SDIO_MASK_DATAENDIE|SDIO_MASK_TXUNDERRIE|
|
||||
SDIO_MASK_STBITERRIE);
|
||||
stm32_configxfrints(priv, SDIO_DMASEND_MASK);
|
||||
|
||||
/* Configure the TX DMA */
|
||||
|
||||
|
@ -425,13 +425,11 @@ static int mmcsd_getSCR(FAR struct mmcsd_state_s *priv, uint32 scr[2])
|
||||
int ret;
|
||||
|
||||
/* Set Block Size To 8 Bytes */
|
||||
/* Send CMD55 APP_CMD with argument as card's RCA */
|
||||
|
||||
mmcsd_sendcmdpoll(priv, MMCSD_CMD16, 8);
|
||||
ret = mmcsd_recvR1(priv, MMCSD_CMD16);
|
||||
ret = mmcsd_setblocklen(priv, 8);
|
||||
if (ret != OK)
|
||||
{
|
||||
fdbg("ERROR: RECVR1 for CMD16 failed: %d\n", ret);
|
||||
fdbg("ERROR: mmcsd_setblocklen failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -52,11 +52,11 @@
|
||||
* Wait events are used for event-waiting by SDIO_WAITENABLE and SDIO_EVENTWAIT
|
||||
*/
|
||||
|
||||
#define SDIOWAIT_CMDDONE (1 << 0) /* Bit 0: Command+response complete */
|
||||
#define SDIOWAIT_CMDBUSYDONE (1 << 1) /* Bit 1: Command with transition to not busy */
|
||||
#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_ALLEVENTS 0x03
|
||||
#define SDIOWAIT_ALLEVENTS 0x07
|
||||
|
||||
/* Media events are used for enable/disable registered event callbacks */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user