SDIO: Make interface field names conform to standard.

The SDIO interface structure includes fields with names like recvR1 and others.  These cause "Mixed case identifier" errors from nxstyle in all places they are uses.
This change performs a mass substition of recvR with recv_r to correct this coding standard violation.
This commit is contained in:
Gregory Nutt
2020-04-03 20:02:25 -06:00
committed by Ouss4
parent de188fbe85
commit a6e69a82ad
16 changed files with 1480 additions and 1333 deletions
+8 -8
View File
@@ -240,7 +240,7 @@
<h1><big><font color="#3c34ec">
<i>NuttX RTOS Porting Guide</i>
</font></big></h1>
<p>Last Updated: August 8, 2019</p>
<p>Last Updated: April 2, 2020</p>
</td>
</tr>
</table>
@@ -6220,13 +6220,13 @@ int kbd_decode(FAR struct lib_instream_s *stream, FAR struct kbd_getstate_s *sta
<code>int (*sendsetup)(FAR struct sdio_dev_s *dev, FAR const uint8_t *buffer, size_t nbytes);</code><br>
<code>int (*cancel)(FAR struct sdio_dev_s *dev);</code><br>
<code>int (*waitresponse)(FAR struct sdio_dev_s *dev, uint32_t cmd);</code><br>
<code>int (*recvR1)(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t *R1);</code><br>
<code>int (*recvR2)(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t R2[4]);</code><br>
<code>int (*recvR3)(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t *R3);</code><br>
<code>int (*recvR4)(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t *R4);</code><br>
<code>int (*recvR5)(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t *R5);</code><br>
<code>int (*recvR6)(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t *R6);</code><br>
<code>int (*recvR7)(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t *R7);</code></p>
<code>int (*recv_r1)(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t *R1);</code><br>
<code>int (*recv_r2)(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t R2[4]);</code><br>
<code>int (*recv_r3)(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t *R3);</code><br>
<code>int (*recv_r4)(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t *R4);</code><br>
<code>int (*recv_r5)(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t *R5);</code><br>
<code>int (*recv_r6)(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t *R6);</code><br>
<code>int (*recv_r7)(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t *R7);</code></p>
</ul>
<p>
Event/Callback support:
+77 -73
View File
@@ -244,10 +244,15 @@
struct sdio_softc_s
{
int func_num; /* number of I/O functions (SDIO) */
FAR struct sdio_function_s *fn[SDIO_FUNC_NUM_MAX + 1]; /* selected card */
/* Selected card */
FAR struct sdio_function_s *fn[SDIO_FUNC_NUM_MAX + 1];
bool full_speed; /* high speed mode */
uint8_t dma; /* true: hardware supports DMA */
sem_t sem; /* Assures mutually exclusive access to the sdio */
sem_t sem; /* Assures mutually exclusive access to the
* sdio */
};
/* Structure describing either an SDIO device I/O function. */
@@ -256,10 +261,11 @@ struct sdio_function_s
{
/* common members */
FAR struct sdio_softc_s *sc; /* card slot softc */
sdio_irqhandler_t *irq_callback; /* function callback */
int number; /* I/O function number or -1, 0 for func0,1 for func1... */
struct sdio_cis_s cis; /* decoded CIS */
FAR struct sdio_softc_s *sc; /* Dard slot softc */
sdio_irqhandler_t *irq_callback; /* function callback */
int number; /* I/O function number or -1, 0 for
* func0,1 for func1... */
struct sdio_cis_s cis; /* Decoded CIS */
};
#endif /* CONFIG_CXD56_SDIO_ENABLE_MULTIFUNCTION */
@@ -267,41 +273,43 @@ struct sdio_function_s
struct cxd56_sdiodev_s
{
struct sdio_dev_s dev; /* Standard, base SDIO interface */
struct sdio_dev_s dev; /* Standard, base SDIO interface */
/* CXD56xx-specific extensions */
/* Event support */
sem_t waitsem; /* Implements event waiting */
sdio_eventset_t waitevents; /* Set of events to be waited for */
uint32_t waitints; /* Interrupt enables for event waiting */
sem_t waitsem; /* Implements event waiting */
sdio_eventset_t waitevents; /* Set of events to be waited for */
uint32_t waitints; /* Interrupt enables for event waiting */
volatile sdio_eventset_t wkupevent; /* The event that caused the wakeup */
WDOG_ID waitwdog; /* Watchdog that handles event timeouts */
WDOG_ID waitwdog; /* Watchdog that handles event timeouts */
/* Callback support */
sdio_statset_t cdstatus; /* Card status */
sdio_eventset_t cbevents; /* Set of events to be cause callbacks */
worker_t callback; /* Registered callback function */
void *cbarg; /* Registered callback argument */
struct work_s cbwork; /* Callback work queue structure */
sdio_statset_t cdstatus; /* Card status */
sdio_eventset_t cbevents; /* Set of events to be cause callbacks */
worker_t callback; /* Registered callback function */
void *cbarg; /* Registered callback argument */
struct work_s cbwork; /* Callback work queue structure */
/* Interrupt mode data transfer support */
uint32_t *buffer; /* Address of current R/W buffer */
size_t remaining; /* Number of bytes remaining in the transfer */
uint32_t xfrints; /* Interrupt enables for data transfer */
uint32_t *buffer; /* Address of current R/W buffer */
size_t remaining; /* Number of bytes remaining in the
* transfer */
uint32_t xfrints; /* Interrupt enables for data transfer */
/* DMA data transfer support */
#ifdef CONFIG_SDIO_DMA
volatile uint8_t xfrflags; /* Used to synchronize SDIO and DMA completion events */
volatile uint8_t xfrflags; /* Used to synchronize SDIO and DMA
* completion events */
bool usedma;
bool dmasend_prepare;
size_t receive_size;
uint8_t *aligned_buffer; /* Used to buffer alignment */
uint8_t *receive_buffer; /* Used to keep receive buffer address */
uint8_t *aligned_buffer; /* Used to buffer alignment */
uint8_t *receive_buffer; /* Used to keep receive buffer address */
uint32_t dma_cmd;
uint32_t dmasend_cmd;
uint32_t dmasend_regcmd;
@@ -311,7 +319,8 @@ struct cxd56_sdiodev_s
uint16_t blocksize;
#ifdef CONFIG_CXD56_SDIO_ENABLE_MULTIFUNCTION
struct sdio_softc_s sc; /* Structure describing a single SDIO card slot. */
struct sdio_softc_s sc; /* Structure describing a single SDIO
* card slot. */
#endif /* CONFIG_CXD56_SDIO_ENABLE_MULTIFUNCTION */
};
@@ -424,7 +433,8 @@ static int cxd56_sdio_sendsetup(FAR struct sdio_dev_s *dev,
FAR const uint8_t *buffer, uint32_t nbytes);
static int cxd56_sdio_cancel(FAR struct sdio_dev_s *dev);
static int cxd56_sdio_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd);
static int cxd56_sdio_waitresponse(FAR struct sdio_dev_s *dev,
uint32_t cmd);
static int cxd56_sdio_recvshortcrc(FAR struct sdio_dev_s *dev, uint32_t cmd,
uint32_t *rshort);
static int cxd56_sdio_recvlong(FAR struct sdio_dev_s *dev, uint32_t cmd,
@@ -501,13 +511,13 @@ struct cxd56_sdiodev_s g_sdhcdev =
.sendsetup = cxd56_sdio_sendsetup,
.cancel = cxd56_sdio_cancel,
.waitresponse = cxd56_sdio_waitresponse,
.recvR1 = cxd56_sdio_recvshortcrc,
.recvR2 = cxd56_sdio_recvlong,
.recvR3 = cxd56_sdio_recvshort,
.recvR4 = cxd56_sdio_recvshort,
.recvR5 = cxd56_sdio_recvshort,
.recvR6 = cxd56_sdio_recvshortcrc,
.recvR7 = cxd56_sdio_recvshort,
.recv_r1 = cxd56_sdio_recvshortcrc,
.recv_r2 = cxd56_sdio_recvlong,
.recv_r3 = cxd56_sdio_recvshort,
.recv_r4 = cxd56_sdio_recvshort,
.recv_r5 = cxd56_sdio_recvshort,
.recv_r6 = cxd56_sdio_recvshortcrc,
.recv_r7 = cxd56_sdio_recvshort,
.waitenable = cxd56_sdio_waitenable,
.eventwait = cxd56_sdio_eventwait,
.callbackenable = cxd56_sdio_callbackenable,
@@ -545,10 +555,6 @@ static FAR uint32_t cxd56_sdhci_adma_dscr[CXD56_SDIO_MAX_LEN_ADMA_DSCR * 2];
* Private Functions
****************************************************************************/
/****************************************************************************
* Low-level Helpers
****************************************************************************/
/****************************************************************************
* Name: cxd56_takesem
*
@@ -635,10 +641,6 @@ static void cxd56_configxfrints(struct cxd56_sdiodev_s *priv,
leave_critical_section(flags);
}
/****************************************************************************
* DMA Helpers
****************************************************************************/
/****************************************************************************
* Name: cxd56_sampleinit
*
@@ -713,7 +715,8 @@ static void cxd56_sample(struct cxd56_sdiodev_s *priv, int index)
#ifdef CONFIG_SDIO_XFRDEBUG
static void cxd56_dumpsample(struct cxd56_sdiodev_s *priv,
struct cxd56_sdhcregs_s *regs, const char *msg)
struct cxd56_sdhcregs_s *regs,
const char *msg)
{
mcinfo("SDHC Registers: %s\n", msg);
mcinfo(" DSADDR[%08x]: %08x\n", CXD56_SDHCI_DSADDR, regs->dsaddr);
@@ -776,10 +779,6 @@ static void cxd56_showregs(struct cxd56_sdiodev_s *priv, const char *msg)
}
#endif
/****************************************************************************
* Data Transfer Helpers
****************************************************************************/
/****************************************************************************
* Name: cxd56_dataconfig
*
@@ -1155,10 +1154,6 @@ static void cxd56_endtransfer(struct cxd56_sdiodev_s *priv,
}
}
/****************************************************************************
* Interrupt Handling
****************************************************************************/
/****************************************************************************
* Name: cxd56_interrupt
*
@@ -1316,10 +1311,6 @@ static int cxd56_interrupt(int irq, FAR void *context, FAR void *arg)
return OK;
}
/****************************************************************************
* SDIO Interface Methods
****************************************************************************/
/****************************************************************************
* Name: cxd56_sdio_lock
*
@@ -1988,12 +1979,13 @@ static void cxd56_blocksetup(FAR struct sdio_dev_s *dev,
* Name: cxd56_sdio_recvsetup
*
* Description:
* Setup hardware in preparation for data transfer from the card in non-DMA
* (interrupt driven mode). This method will do whatever controller setup
* is necessary. This would be called for SD memory just BEFORE sending
* CMD13 (SEND_STATUS), CMD17 (READ_SINGLE_BLOCK), CMD18
* (READ_MULTIPLE_BLOCKS), ACMD51 (SEND_SCR), etc. Normally, SDIO_WAITEVENT
* will be called to receive the indication that the transfer is complete.
* Setup hardware in preparation for data transfer from the card in non-
* DMA (interrupt driven mode). This method will do whatever controller
* setup is necessary. This would be called for SD memory just BEFORE
* sending CMD13 (SEND_STATUS), CMD17 (READ_SINGLE_BLOCK), CMD18
* (READ_MULTIPLE_BLOCKS), ACMD51 (SEND_SCR), etc. Normally,
* SDIO_WAITEVENT will be called to receive the indication that the
* transfer is complete.
*
* Input Parameters:
* dev - An instance of the SDIO device interface
@@ -2280,7 +2272,7 @@ static int cxd56_sdio_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd)
}
/****************************************************************************
* Name: cxd56_sdio_recvRx
* Name: cxd56_sdio_recv*
*
* Description:
* Receive response to SDIO command. Only the critical payload is
@@ -2658,10 +2650,10 @@ static sdio_eventset_t cxd56_sdio_eventwait(FAR struct sdio_dev_s *dev,
}
}
/* Loop until the event (or the timeout occurs). Race conditions are avoided
* by calling cxd56_waitenable prior to triggering the logic that will cause
* the wait to terminate. Under certain race conditions, the waited-for
* may have already occurred before this function was called!
/* Loop until the event (or the timeout occurs). Race conditions are
* avoided by calling cxd56_waitenable prior to triggering the logic that
* will cause the wait to terminate. Under certain race conditions, the
* waited-for may have already occurred before this function was called!
*/
for (; ; )
@@ -2909,7 +2901,8 @@ static int cxd56_sdio_dmarecvsetup(FAR struct sdio_dev_s *dev,
/* Allocate aligned buffer */
priv->aligned_buffer = (uint8_t *) kmm_malloc(sizeof(uint8_t) * buflen);
priv->aligned_buffer = (uint8_t *)
kmm_malloc(sizeof(uint8_t) * buflen);
/* Keep receive buffer address */
@@ -3024,7 +3017,8 @@ static int cxd56_sdio_dmasendsetup(FAR struct sdio_dev_s *dev,
/* Allocate aligned buffer */
priv->aligned_buffer = (uint8_t *) kmm_malloc(sizeof(uint8_t) * buflen);
priv->aligned_buffer = (uint8_t *)
kmm_malloc(sizeof(uint8_t) * buflen);
/* Copy buffer to aligned address */
@@ -3208,9 +3202,9 @@ static void cxd56_sdio_callback(void *arg)
priv->cbevents = 0;
leave_critical_section(flags);
/* Callbacks cannot be performed in the context of an interrupt handler.
* If we are in an interrupt handler, then queue the callback to be
* performed later on the work thread.
/* Callbacks cannot be performed in the context of an interrupt
* handler. If we are in an interrupt handler, then queue the
* callback to be performed later on the work thread.
*/
if (up_interrupt_context())/* (1) */
@@ -3218,7 +3212,10 @@ static void cxd56_sdio_callback(void *arg)
/* Yes.. queue it */
work_cancel(HPWORK, &priv->cbwork);
mcinfo("Queuing callback to %p(%p)\n", priv->callback, priv->cbarg);
mcinfo("Queuing callback to %p(%p)\n",
priv->callback, priv->cbarg);
work_queue(HPWORK, &priv->cbwork, (worker_t)priv->callback,
priv->cbarg, delay);
}
@@ -3227,7 +3224,9 @@ static void cxd56_sdio_callback(void *arg)
/* No.. then just call the callback here */
up_mdelay(delay);
mcinfo("Callback to %p(%p)\n", priv->callback, priv->cbarg);
priv->callback(priv->cbarg);
}
}
@@ -3480,7 +3479,9 @@ static FAR struct sdio_function_s *
FAR struct sdio_function_s *sf;
DEBUGASSERT(sc);
sf = (FAR struct sdio_function_s *)kmm_malloc(sizeof(struct sdio_function_s));
sf = (FAR struct sdio_function_s *)
kmm_malloc(sizeof(struct sdio_function_s));
if (!sf)
{
mcerr("ERROR: Failed\n");
@@ -3984,7 +3985,8 @@ static int cxd56_sdio_readb(FAR struct sdio_dev_s *dev, int func_num,
****************************************************************************/
static int cxd56_sdio_writeb(FAR struct sdio_dev_s *dev, int func_num,
uint32_t addr, uint8_t data, FAR uint8_t * rdata)
uint32_t addr, uint8_t data,
FAR uint8_t * rdata)
{
struct cxd56_sdiodev_s *priv = (struct cxd56_sdiodev_s *)dev;
int ret;
@@ -4500,7 +4502,8 @@ SDIO_INIT_CIS_ERR:
* slotno - Not used.
*
* Returned Values:
* A reference to an SDIO interface structure. NULL is returned on failures.
* A reference to an SDIO interface structure. NULL is returned on
* failures.
*
****************************************************************************/
@@ -4612,7 +4615,8 @@ FAR struct sdio_dev_s *cxd56_sdhci_initialize(int slotno)
* slotno - Not used.
*
* Returned Values:
* A reference to an SDIO interface structure. NULL is returned on failures.
* A reference to an SDIO interface structure. NULL is returned on
* failures.
*
****************************************************************************/
+88 -69
View File
@@ -161,48 +161,52 @@
struct imxrt_dev_s
{
struct sdio_dev_s dev; /* Standard, base SDIO interface */
struct sdio_dev_s dev; /* Standard, base SDIO interface */
/* Imxrt-specific extensions */
/* Event support */
sem_t waitsem; /* Implements event waiting */
sdio_eventset_t waitevents; /* Set of events to be waited for */
uint32_t waitints; /* Interrupt enables for event waiting */
sem_t waitsem; /* Implements event waiting */
sdio_eventset_t waitevents; /* Set of events to be waited for */
uint32_t waitints; /* Interrupt enables for event waiting */
volatile sdio_eventset_t wkupevent; /* The event that caused the wakeup */
WDOG_ID waitwdog; /* Watchdog that handles event timeouts */
WDOG_ID waitwdog; /* Watchdog that handles event timeouts */
/* Callback support */
sdio_statset_t cdstatus; /* Card status */
sdio_eventset_t cbevents; /* Set of events to be cause callbacks */
worker_t callback; /* Registered callback function */
void *cbarg; /* Registered callback argument */
struct work_s cbwork; /* Callback work queue structure */
sdio_statset_t cdstatus; /* Card status */
sdio_eventset_t cbevents; /* Set of events to be cause callbacks */
worker_t callback; /* Registered callback function */
void *cbarg; /* Registered callback argument */
struct work_s cbwork; /* Callback work queue structure */
/* Interrupt mode data transfer support */
uint32_t *buffer; /* Address of current R/W buffer */
size_t remaining; /* Number of bytes remaining in the transfer */
uint32_t xfrints; /* Interrupt enables for data transfer */
uint32_t *buffer; /* Address of current R/W buffer */
size_t remaining; /* Number of bytes remaining in the
* transfer */
uint32_t xfrints; /* Interrupt enables for data transfer */
#ifdef CONFIG_IMXRT_USDHC_DMA
/* DMA data transfer support */
volatile uint8_t xfrflags; /* Used to synchronize SDIO and DMA completion */
uint32_t *bufferend; /* Far end of R/W buffer for cache invalidation */
volatile uint8_t xfrflags; /* Used to synchronize SDIO and DMA
* completion */
uint32_t *bufferend; /* Far end of R/W buffer for cache
* invalidation */
#endif
/* Card interrupt support for SDIO */
uint32_t cintints; /* Interrupt enables for card ints */
int (*do_sdio_card)(void *); /* SDIO card ISR */
void *do_sdio_arg; /* arg for SDIO card ISR */
uint32_t cintints; /* Interrupt enables for card ints */
int (*do_sdio_card)(void *); /* SDIO card ISR */
void *do_sdio_arg; /* arg for SDIO card ISR */
uint32_t addr; /* Base address of this instances */
uint32_t sw_cd_gpio; /* If a non USDHCx CD pin is used, this is its GPIO */
uint32_t cd_invert; /* If true invert the CD pin */
uint32_t addr; /* Base address of this instances */
uint32_t sw_cd_gpio; /* If a non USDHCx CD pin is used,
* this is its GPIO */
uint32_t cd_invert; /* If true invert the CD pin */
};
/* Register logging support */
@@ -406,13 +410,13 @@ struct imxrt_dev_s g_sdhcdev[IMXRT_MAX_SDHC_DEV_SLOTS] =
#endif
.cancel = imxrt_cancel,
.waitresponse = imxrt_waitresponse,
.recvR1 = imxrt_recvshortcrc,
.recvR2 = imxrt_recvlong,
.recvR3 = imxrt_recvshort,
.recvR4 = imxrt_recvshort,
.recvR5 = imxrt_recvshortcrc,
.recvR6 = imxrt_recvshortcrc,
.recvR7 = imxrt_recvshort,
.recv_r1 = imxrt_recvshortcrc,
.recv_r2 = imxrt_recvlong,
.recv_r3 = imxrt_recvshort,
.recv_r4 = imxrt_recvshort,
.recv_r5 = imxrt_recvshortcrc,
.recv_r6 = imxrt_recvshortcrc,
.recv_r7 = imxrt_recvshort,
.waitenable = imxrt_waitenable,
.eventwait = imxrt_eventwait,
.callbackenable = imxrt_callbackenable,
@@ -464,13 +468,13 @@ struct imxrt_dev_s g_sdhcdev[IMXRT_MAX_SDHC_DEV_SLOTS] =
#endif
.cancel = imxrt_cancel,
.waitresponse = imxrt_waitresponse,
.recvR1 = imxrt_recvshortcrc,
.recvR2 = imxrt_recvlong,
.recvR3 = imxrt_recvshort,
.recvR4 = imxrt_recvshort,
.recvR5 = imxrt_recvshortcrc,
.recvR6 = imxrt_recvshortcrc,
.recvR7 = imxrt_recvshort,
.recv_r1 = imxrt_recvshortcrc,
.recv_r2 = imxrt_recvlong,
.recv_r3 = imxrt_recvshort,
.recv_r4 = imxrt_recvshort,
.recv_r5 = imxrt_recvshortcrc,
.recv_r6 = imxrt_recvshortcrc,
.recv_r7 = imxrt_recvshort,
.waitenable = imxrt_waitenable,
.eventwait = imxrt_eventwait,
.callbackenable = imxrt_callbackenable,
@@ -791,16 +795,17 @@ static void imxrt_dataconfig(struct imxrt_dev_s *priv, bool bwrite,
}
/* When the watermark level requirement is met in data transfer, and the
* internal DMA is enabled, the data buffer block sends a DMA request to the
* crossbar switch interface.
* internal DMA is enabled, the data buffer block sends a DMA request to
* the crossbar switch interface.
*/
if (bwrite)
{
/* The USDHC will not start data transmission until the number of words
* set in the WML register can be held in the buffer. If the buffer is
* empty and the host system does not write data in time, the USDHC will
* stop the SD_CLK to avoid the data buffer under-run situation.
/* The USDHC will not start data transmission until the number of
* words set in the WML register can be held in the buffer. If the
* buffer is empty and the host system does not write data in time,
* the USDHC will stop the SD_CLK to avoid the data buffer under-run
* situation.
*/
putreg32(watermark << USDHC_WML_WR_SHIFT,
@@ -1051,7 +1056,8 @@ static void imxrt_eventtimeout(int argc, uint32_t arg)
*
****************************************************************************/
static void imxrt_endwait(struct imxrt_dev_s *priv, sdio_eventset_t wkupevent)
static void imxrt_endwait(struct imxrt_dev_s *priv,
sdio_eventset_t wkupevent)
{
/* Cancel the watchdog timeout */
@@ -1105,7 +1111,8 @@ static void imxrt_endtransfer(struct imxrt_dev_s *priv,
#ifdef CONFIG_IMXRT_USDHC_DMA
/* DMA modified the buffer, so we need to flush its cache lines. */
up_invalidate_dcache((uintptr_t) priv->buffer, (uintptr_t) priv->bufferend);
up_invalidate_dcache((uintptr_t) priv->buffer,
(uintptr_t) priv->bufferend);
#endif
/* Debug instrumentation */
@@ -1219,7 +1226,7 @@ static int imxrt_interrupt(int irq, void *context, FAR void *arg)
}
}
/* Handle Card interrupt events *****************************************/
/* Handle Card interrupt events *******************************************/
pending = enabled & priv->cintints;
if ((pending & USDHC_INT_CINT) != 0)
@@ -1242,7 +1249,9 @@ static int imxrt_interrupt(int irq, void *context, FAR void *arg)
{
/* Yes.. queue it */
mcinfo("Queuing callback to %p(%p)\n", priv->callback, priv->cbarg);
mcinfo("Queuing callback to %p(%p)\n",
priv->callback, priv->cbarg);
(void)work_queue(HPWORK, &priv->cbwork, (worker_t)priv->callback,
priv->cbarg, 0);
}
@@ -1251,6 +1260,7 @@ static int imxrt_interrupt(int irq, void *context, FAR void *arg)
/* No.. then just call the callback here */
mcinfo("Callback to %p(%p)\n", priv->callback, priv->cbarg);
priv->callback(priv->cbarg);
}
}
@@ -1340,8 +1350,10 @@ static void imxrt_reset(FAR struct sdio_dev_s *dev)
* Initiate the reset by setting the RSTA bit in the SYSCTL register.
*/
modifyreg32(priv->addr + IMXRT_USDHC_VENDOR2_OFFSET, 0, USDHC_VS2_BUSRESET);
modifyreg32(priv->addr + IMXRT_USDHC_SYSCTL_OFFSET, 0, USDHC_SYSCTL_RSTA);
modifyreg32(priv->addr + IMXRT_USDHC_VENDOR2_OFFSET,
0, USDHC_VS2_BUSRESET);
modifyreg32(priv->addr + IMXRT_USDHC_SYSCTL_OFFSET,
0, USDHC_SYSCTL_RSTA);
modifyreg32(priv->addr + IMXRT_USDHC_VENDOR2_OFFSET,
USDHC_VS2_BUSRESET | USDHC_VS2_ACMD23ARGU2, 0);
@@ -1571,9 +1583,9 @@ static void imxrt_frequency(FAR struct sdio_dev_s *dev, uint32_t frequency)
*
* The prescaler is available only for the values: 2, 4, 8, 16, 32,
* 64, 128, and 256. Pick the smallest value of SDCLKFS that would
* result in an in-range frequency. For example, if the base clock frequency
* is 96 MHz, and the target frequency is 25 MHz, the following logic
* will select prescaler:
* result in an in-range frequency. For example, if the base clock
* frequency is 96 MHz, and the target frequency is 25 MHz, the
* following logic will select prescaler:
*
* 96MHz / 2 <= 25MHz <= 96MHz / 2 /16 -- YES, prescaler == 2
*
@@ -1666,7 +1678,9 @@ static void imxrt_frequency(FAR struct sdio_dev_s *dev, uint32_t frequency)
USDHC_SYSCTL_HCKEN | USDHC_SYSCTL_IPGEN);
putreg32(regval, priv->addr + IMXRT_USDHC_SYSCTL_OFFSET);
mcinfo("SYSCTRL: %08x\n", getreg32(priv->addr + IMXRT_USDHC_SYSCTL_OFFSET));
mcinfo("SYSCTRL: %08x\n",
getreg32(priv->addr + IMXRT_USDHC_SYSCTL_OFFSET));
}
#endif
@@ -2127,12 +2141,13 @@ static void imxrt_blocksetup(FAR struct sdio_dev_s *dev,
* Name: imxrt_recvsetup
*
* Description:
* Setup hardware in preparation for data transfer from the card in non-DMA
* (interrupt driven mode). This method will do whatever controller setup
* is necessary. This would be called for SD memory just BEFORE sending
* CMD13 (SEND_STATUS), CMD17 (READ_SINGLE_BLOCK), CMD18
* (READ_MULTIPLE_BLOCKS), ACMD51 (SEND_SCR), etc. Normally, SDIO_WAITEVENT
* will be called to receive the indication that the transfer is complete.
* Setup hardware in preparation for data transfer from the card in non-
* DMA (interrupt driven mode). This method will do whatever controller
* setup is necessary. This would be called for SD memory just BEFORE
* sending CMD13 (SEND_STATUS), CMD17 (READ_SINGLE_BLOCK), CMD18
* (READ_MULTIPLE_BLOCKS), ACMD51 (SEND_SCR), etc. Normally,
* SDIO_WAITEVENT will be called to receive the indication that the
* transfer is complete.
*
* Input Parameters:
* dev - An instance of the SDIO device interface
@@ -2372,7 +2387,7 @@ static int imxrt_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd)
}
/****************************************************************************
* Name: imxrt_recvRx
* Name: imxrt_recv*
*
* Description:
* Receive response to SDIO command. Only the critical payload is
@@ -2456,9 +2471,9 @@ static int imxrt_recvshortcrc(FAR struct sdio_dev_s *dev, uint32_t cmd,
}
}
/* Return the R1/R1b/R6 response. These responses are returned in CDMRSP0.
* NOTE: This is not true for R1b (Auto CMD12 response) which is returned in
* CMDRSP3.
/* Return the R1/R1b/R6 response. These responses are returned in
* CDMRSP0. NOTE: This is not true for R1b (Auto CMD12 response) which is
* returned in CMDRSP3.
*/
*rshort = getreg32(priv->addr + IMXRT_USDHC_CMDRSP0_OFFSET);
@@ -2975,16 +2990,18 @@ static void imxrt_callback(void *arg)
priv->cbevents = 0;
/* Callbacks cannot be performed in the context of an interrupt handler.
* If we are in an interrupt handler, then queue the callback to be
* performed later on the work thread.
/* Callbacks cannot be performed in the context of an interrupt
* handler. If we are in an interrupt handler, then queue the
* callback to be performed later on the work thread.
*/
if (up_interrupt_context())
{
/* Yes.. queue it */
mcinfo("Queuing callback to %p(%p)\n", priv->callback, priv->cbarg);
mcinfo("Queuing callback to %p(%p)\n",
priv->callback, priv->cbarg);
work_queue(HPWORK, &priv->cbwork, (worker_t)priv->callback,
priv->cbarg, 0);
}
@@ -2992,7 +3009,9 @@ static void imxrt_callback(void *arg)
{
/* No.. then just call the callback here */
mcinfo("Callback to %p(%p)\n", priv->callback, priv->cbarg);
mcinfo("Callback to %p(%p)\n",
priv->callback, priv->cbarg);
priv->callback(priv->cbarg);
}
}
@@ -3092,9 +3111,9 @@ FAR struct sdio_dev_s *imxrt_usdhc_initialize(int slotno)
{
case IMXRT_USDHC1_BASE:
/* Configure pins for 1 or 4-bit, wide-bus operation (the chip is
* capable of 8-bit wide bus operation but D4-D7 are not configured). If
* bus is multiplexed then there is a custom bus configuration utility
* in the scope of the board support package.
* capable of 8-bit wide bus operation but D4-D7 are not configured).
* If bus is multiplexed then there is a custom bus configuration
* utility in the scope of the board support package.
*/
#ifndef CONFIG_SDIO_MUXBUS
+119 -83
View File
@@ -89,8 +89,8 @@
* the board.h file
*
* NOTE: These settings are not currently used. Since there are only four
* frequencies, it makes more sense to just "can" the fixed frequency prescaler
* and divider values.
* frequencies, it makes more sense to just "can" the fixed frequency
* prescaler and divider values.
*/
#ifdef CONFIG_KINETIS_SDHC_ABSFREQ
@@ -156,36 +156,38 @@
struct kinetis_dev_s
{
struct sdio_dev_s dev; /* Standard, base SDIO interface */
struct sdio_dev_s dev; /* Standard, base SDIO interface */
/* Kinetis-specific extensions */
/* Event support */
sem_t waitsem; /* Implements event waiting */
sdio_eventset_t waitevents; /* Set of events to be waited for */
uint32_t waitints; /* Interrupt enables for event waiting */
sem_t waitsem; /* Implements event waiting */
sdio_eventset_t waitevents; /* Set of events to be waited for */
uint32_t waitints; /* Interrupt enables for event waiting */
volatile sdio_eventset_t wkupevent; /* The event that caused the wakeup */
WDOG_ID waitwdog; /* Watchdog that handles event timeouts */
WDOG_ID waitwdog; /* Watchdog that handles event timeouts */
/* Callback support */
sdio_statset_t cdstatus; /* Card status */
sdio_eventset_t cbevents; /* Set of events to be cause callbacks */
worker_t callback; /* Registered callback function */
void *cbarg; /* Registered callback argument */
struct work_s cbwork; /* Callback work queue structure */
sdio_statset_t cdstatus; /* Card status */
sdio_eventset_t cbevents; /* Set of events to be cause callbacks */
worker_t callback; /* Registered callback function */
void *cbarg; /* Registered callback argument */
struct work_s cbwork; /* Callback work queue structure */
/* Interrupt mode data transfer support */
uint32_t *buffer; /* Address of current R/W buffer */
size_t remaining; /* Number of bytes remaining in the transfer */
uint32_t xfrints; /* Interrupt enables for data transfer */
uint32_t *buffer; /* Address of current R/W buffer */
size_t remaining; /* Number of bytes remaining in the
* transfer */
uint32_t xfrints; /* Interrupt enables for data transfer */
/* DMA data transfer support */
#ifdef CONFIG_KINETIS_SDHC_DMA
volatile uint8_t xfrflags; /* Used to synchronize SDIO and DMA completion events */
volatile uint8_t xfrflags; /* Used to synchronize SDIO and DMA
* completion events */
#endif
};
@@ -229,9 +231,11 @@ struct kinetis_sdhcregs_s
static void kinetis_takesem(struct kinetis_dev_s *priv);
#define kinetis_givesem(priv) (nxsem_post(&priv->waitsem))
static void kinetis_configwaitints(struct kinetis_dev_s *priv, uint32_t waitints,
sdio_eventset_t waitevents, sdio_eventset_t wkupevents);
static void kinetis_configxfrints(struct kinetis_dev_s *priv, uint32_t xfrints);
static void kinetis_configwaitints(struct kinetis_dev_s *priv,
uint32_t waitints, sdio_eventset_t waitevents,
sdio_eventset_t wkupevents);
static void kinetis_configxfrints(struct kinetis_dev_s *priv,
uint32_t xfrints);
/* DMA Helpers **************************************************************/
@@ -285,7 +289,8 @@ static sdio_capset_t kinetis_capabilities(FAR struct sdio_dev_s *dev);
static sdio_statset_t kinetis_status(FAR struct sdio_dev_s *dev);
static void kinetis_widebus(FAR struct sdio_dev_s *dev, bool enable);
#ifdef CONFIG_KINETIS_SDHC_ABSFREQ
static void kinetis_frequency(FAR struct sdio_dev_s *dev, uint32_t frequency);
static void kinetis_frequency(FAR struct sdio_dev_s *dev,
uint32_t frequency);
#endif
static void kinetis_clock(FAR struct sdio_dev_s *dev,
enum sdio_clock_e rate);
@@ -302,8 +307,8 @@ static void kinetis_blocksetup(FAR struct sdio_dev_s *dev,
#endif
#ifndef CONFIG_KINETIS_SDHC_DMA
static int kinetis_recvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer,
size_t nbytes);
static int kinetis_recvsetup(FAR struct sdio_dev_s *dev,
FAR uint8_t *buffer, size_t nbytes);
static int kinetis_sendsetup(FAR struct sdio_dev_s *dev,
FAR const uint8_t *buffer, uint32_t nbytes);
#endif
@@ -374,13 +379,13 @@ struct kinetis_dev_s g_sdhcdev =
#endif
.cancel = kinetis_cancel,
.waitresponse = kinetis_waitresponse,
.recvR1 = kinetis_recvshortcrc,
.recvR2 = kinetis_recvlong,
.recvR3 = kinetis_recvshort,
.recvR4 = kinetis_recvnotimpl,
.recvR5 = kinetis_recvnotimpl,
.recvR6 = kinetis_recvshortcrc,
.recvR7 = kinetis_recvshort,
.recv_r1 = kinetis_recvshortcrc,
.recv_r2 = kinetis_recvlong,
.recv_r3 = kinetis_recvshort,
.recv_r4 = kinetis_recvnotimpl,
.recv_r5 = kinetis_recvnotimpl,
.recv_r6 = kinetis_recvshortcrc,
.recv_r7 = kinetis_recvshort,
.waitenable = kinetis_waitenable,
.eventwait = kinetis_eventwait,
.callbackenable = kinetis_callbackenable,
@@ -444,9 +449,10 @@ static void kinetis_takesem(struct kinetis_dev_s *priv)
*
****************************************************************************/
static void kinetis_configwaitints(struct kinetis_dev_s *priv, uint32_t waitints,
sdio_eventset_t waitevents,
sdio_eventset_t wkupevent)
static void kinetis_configwaitints(struct kinetis_dev_s *priv,
uint32_t waitints,
sdio_eventset_t waitevents,
sdio_eventset_t wkupevent)
{
irqstate_t flags;
@@ -481,7 +487,8 @@ static void kinetis_configwaitints(struct kinetis_dev_s *priv, uint32_t waitints
*
****************************************************************************/
static void kinetis_configxfrints(struct kinetis_dev_s *priv, uint32_t xfrints)
static void kinetis_configxfrints(struct kinetis_dev_s *priv,
uint32_t xfrints)
{
irqstate_t flags;
flags = enter_critical_section();
@@ -502,7 +509,8 @@ static void kinetis_configxfrints(struct kinetis_dev_s *priv, uint32_t xfrints)
#ifdef CONFIG_SDIO_XFRDEBUG
static void kinetis_sampleinit(void)
{
memset(g_sampleregs, 0xff, DEBUG_NSAMPLES * sizeof(struct kinetis_sdhcregs_s));
memset(g_sampleregs, 0xff,
DEBUG_NSAMPLES * sizeof(struct kinetis_sdhcregs_s));
}
#endif
@@ -567,7 +575,8 @@ static void kinetis_sample(struct kinetis_dev_s *priv, int index)
#ifdef CONFIG_SDIO_XFRDEBUG
static void kinetis_dumpsample(struct kinetis_dev_s *priv,
struct kinetis_sdhcregs_s *regs, const char *msg)
struct kinetis_sdhcregs_s *regs,
const char *msg)
{
mcinfo("SDHC Registers: %s\n", msg);
mcinfo(" DSADDR[%08x]: %08x\n", KINETIS_SDHC_DSADDR, regs->dsaddr);
@@ -1074,6 +1083,7 @@ static int kinetis_interrupt(int irq, void *context, FAR void *arg)
regval = getreg32(KINETIS_SDHC_IRQSIGEN);
enabled = getreg32(KINETIS_SDHC_IRQSTAT) & regval;
mcinfo("IRQSTAT: %08x IRQSIGEN %08x enabled: %08x\n",
getreg32(KINETIS_SDHC_IRQSTAT), regval, enabled);
@@ -1133,7 +1143,9 @@ static int kinetis_interrupt(int irq, void *context, FAR void *arg)
mcerr("ERROR: Data block CRC failure, remaining: %d\n",
priv->remaining);
kinetis_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR);
kinetis_endtransfer(priv,
SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR);
}
/* Handle data timeout error */
@@ -1143,7 +1155,9 @@ static int kinetis_interrupt(int irq, void *context, FAR void *arg)
/* Terminate the transfer with an error */
mcerr("ERROR: Data timeout, remaining: %d\n", priv->remaining);
kinetis_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_TIMEOUT);
kinetis_endtransfer(priv,
SDIOWAIT_TRANSFERDONE | SDIOWAIT_TIMEOUT);
}
}
@@ -1158,7 +1172,8 @@ static int kinetis_interrupt(int irq, void *context, FAR void *arg)
{
/* Yes.. Is their a thread waiting for response done? */
if ((priv->waitevents & (SDIOWAIT_CMDDONE | SDIOWAIT_RESPONSEDONE)) != 0)
if ((priv->waitevents & (SDIOWAIT_CMDDONE |
SDIOWAIT_RESPONSEDONE)) != 0)
{
/* Yes.. mask further interrupts and wake the thread up */
@@ -1392,15 +1407,15 @@ static void kinetis_frequency(FAR struct sdio_dev_s *dev, uint32_t frequency)
unsigned int prescaler;
unsigned int divisor;
/* The SDCLK frequency is determined by (1) the frequency of the base clock
* that was selected as the input clock, and (2) by a prescaler and a
* divisor that are selected here:
/* The SDCLK frequency is determined by (1) the frequency of the base
* clock that was selected as the input clock, and (2) by a prescaler and
* a divisor that are selected here:
*
* SDCLK frequency = (base clock) / (prescaler * divisor)
*
* The prescaler is available only for the values: 2, 4, 8, 16, 32, 64, 128,
* and 256. Pick the smallest value of SDCLKFS that would result in an
* in-range frequency.
* The prescaler is available only for the values: 2, 4, 8, 16, 32, 64,
* 128, and 256. Pick the smallest value of SDCLKFS that would result in
* an in-range frequency.
*
* For example, if the base clock frequency is 96 MHz, and the target
* frequency is 25 MHz, the following logic will select prescaler.
@@ -1545,8 +1560,10 @@ static void kinetis_clock(FAR struct sdio_dev_s *dev, enum sdio_clock_e rate)
* enables as well.
*/
regval &= ~(SDHC_SYSCTL_IPGEN | SDHC_SYSCTL_HCKEN | SDHC_SYSCTL_PEREN |
SDHC_SYSCTL_SDCLKFS_MASK | SDHC_SYSCTL_DVS_MASK);
regval &=
~(SDHC_SYSCTL_IPGEN | SDHC_SYSCTL_HCKEN | SDHC_SYSCTL_PEREN |
SDHC_SYSCTL_SDCLKFS_MASK | SDHC_SYSCTL_DVS_MASK);
putreg32(regval, KINETIS_SDHC_SYSCTL);
mcinfo("SYSCTRL: %08x\n", getreg32(KINETIS_SDHC_SYSCTL));
return;
@@ -1613,37 +1630,51 @@ static void kinetis_clock(FAR struct sdio_dev_s *dev, enum sdio_clock_e rate)
* enables as well.
*/
regval &= ~(SDHC_SYSCTL_IPGEN | SDHC_SYSCTL_HCKEN | SDHC_SYSCTL_PEREN);
regval &=
~(SDHC_SYSCTL_IPGEN | SDHC_SYSCTL_HCKEN | SDHC_SYSCTL_PEREN);
putreg32(regval, KINETIS_SDHC_SYSCTL);
mcinfo("SYSCTRL: %08x\n", getreg32(KINETIS_SDHC_SYSCTL));
return;
}
case CLOCK_IDMODE : /* Initial ID mode clocking (<400KHz) */
regval |= (BOARD_SDHC_IDMODE_PRESCALER | BOARD_SDHC_IDMODE_DIVISOR |
SDHC_SYSCTL_SDCLKEN | SDHC_SYSCTL_PEREN | SDHC_SYSCTL_HCKEN |
regval |= (BOARD_SDHC_IDMODE_PRESCALER |
BOARD_SDHC_IDMODE_DIVISOR |
SDHC_SYSCTL_SDCLKEN |
SDHC_SYSCTL_PEREN |
SDHC_SYSCTL_HCKEN |
SDHC_SYSCTL_IPGEN);
break;
case CLOCK_MMC_TRANSFER : /* MMC normal operation clocking */
regval |= (BOARD_SDHC_MMCMODE_PRESCALER | BOARD_SDHC_MMCMODE_DIVISOR |
SDHC_SYSCTL_SDCLKEN | SDHC_SYSCTL_PEREN | SDHC_SYSCTL_HCKEN |
regval |= (BOARD_SDHC_MMCMODE_PRESCALER |
BOARD_SDHC_MMCMODE_DIVISOR |
SDHC_SYSCTL_SDCLKEN |
SDHC_SYSCTL_PEREN |
SDHC_SYSCTL_HCKEN |
SDHC_SYSCTL_IPGEN);
break;
case CLOCK_SD_TRANSFER_1BIT : /* SD normal operation clocking (narrow
* 1-bit mode) */
#ifndef CONFIG_KINETIS_SDHC_WIDTH_D1_ONLY
regval |= (BOARD_SDHC_SD1MODE_PRESCALER | BOARD_SDHC_SD1MODE_DIVISOR |
SDHC_SYSCTL_SDCLKEN | SDHC_SYSCTL_PEREN | SDHC_SYSCTL_HCKEN |
regval |= (BOARD_SDHC_SD1MODE_PRESCALER |
BOARD_SDHC_SD1MODE_DIVISOR |
SDHC_SYSCTL_SDCLKEN |
SDHC_SYSCTL_PEREN |
SDHC_SYSCTL_HCKEN |
SDHC_SYSCTL_IPGEN);
break;
#endif
case CLOCK_SD_TRANSFER_4BIT : /* SD normal operation clocking (wide
* 4-bit mode) */
regval |= (BOARD_SDHC_SD4MODE_PRESCALER | BOARD_SDHC_SD4MODE_DIVISOR |
SDHC_SYSCTL_SDCLKEN | SDHC_SYSCTL_PEREN | SDHC_SYSCTL_HCKEN |
regval |= (BOARD_SDHC_SD4MODE_PRESCALER |
BOARD_SDHC_SD4MODE_DIVISOR |
SDHC_SYSCTL_SDCLKEN |
SDHC_SYSCTL_PEREN |
SDHC_SYSCTL_HCKEN |
SDHC_SYSCTL_IPGEN);
break;
}
@@ -1893,12 +1924,13 @@ static void kinetis_blocksetup(FAR struct sdio_dev_s *dev,
* Name: kinetis_recvsetup
*
* Description:
* Setup hardware in preparation for data transfer from the card in non-DMA
* (interrupt driven mode). This method will do whatever controller setup
* is necessary. This would be called for SD memory just BEFORE sending
* CMD13 (SEND_STATUS), CMD17 (READ_SINGLE_BLOCK), CMD18
* (READ_MULTIPLE_BLOCKS), ACMD51 (SEND_SCR), etc. Normally, SDIO_WAITEVENT
* will be called to receive the indication that the transfer is complete.
* Setup hardware in preparation for data transfer from the card in non-
* DMA (interrupt driven mode). This method will do whatever controller
* setup is necessary. This would be called for SD memory just BEFORE
* sending CMD13 (SEND_STATUS), CMD17 (READ_SINGLE_BLOCK), CMD18
* (READ_MULTIPLE_BLOCKS), ACMD51 (SEND_SCR), etc. Normally,
* SDIO_WAITEVENT will be called to receive the indication that the
* transfer is complete.
*
* Input Parameters:
* dev - An instance of the SDIO device interface
@@ -1946,9 +1978,9 @@ static int kinetis_recvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer,
* Name: kinetis_sendsetup
*
* Description:
* Setup hardware in preparation for data transfer from the card. This method
* will do whatever controller setup is necessary. This would be called
* for SD memory just AFTER sending CMD24 (WRITE_BLOCK), CMD25
* Setup hardware in preparation for data transfer from the card. This
* method will do whatever controller setup is necessary. This would be
* called for SD memory just AFTER sending CMD24 (WRITE_BLOCK), CMD25
* (WRITE_MULTIPLE_BLOCK), ... and before SDIO_SENDDATA is called.
*
* Input Parameters:
@@ -2140,7 +2172,7 @@ static int kinetis_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd)
}
/****************************************************************************
* Name: kinetis_recvRx
* Name: kinetis_recv*
*
* Description:
* Receive response to SDIO command. Only the critical payload is
@@ -2418,9 +2450,9 @@ static void kinetis_waitenable(FAR struct sdio_dev_s *dev,
*
* Description:
* Wait for one of the enabled events to occur (or a timeout). Note that
* all events enabled by SDIO_WAITEVENTS are disabled when kinetis_eventwait
* returns. SDIO_WAITEVENTS must be called again before kinetis_eventwait
* can be used again.
* all events enabled by SDIO_WAITEVENTS are disabled when
* kinetis_eventwait returns. SDIO_WAITEVENTS must be called again before
* kinetis_eventwait can be used again.
*
* Input Parameters:
* dev - An instance of the SDIO device interface
@@ -2465,7 +2497,8 @@ static sdio_eventset_t kinetis_eventwait(FAR struct sdio_dev_s *dev,
/* Start the watchdog timer */
delay = MSEC2TICK(timeout);
ret = wd_start(priv->waitwdog, delay, (wdentry_t)kinetis_eventtimeout,
ret = wd_start(priv->waitwdog, delay,
(wdentry_t)kinetis_eventtimeout,
1, (uint32_t)priv);
if (ret < 0)
{
@@ -2473,24 +2506,26 @@ static sdio_eventset_t kinetis_eventwait(FAR struct sdio_dev_s *dev,
}
}
/* Loop until the event (or the timeout occurs). Race conditions are avoided
* by calling kinetis_waitenable prior to triggering the logic that will cause
* the wait to terminate. Under certain race conditions, the waited-for
* may have already occurred before this function was called!
/* Loop until the event (or the timeout occurs). Race conditions are
* avoided by calling kinetis_waitenable prior to triggering the logic
* that will cause the wait to terminate. Under certain race conditions,
* the waited-for may have already occurred before this function was
* called!
*/
for (; ; )
{
/* Wait for an event in event set to occur. If this the event has already
* occurred, then the semaphore will already have been incremented and
* there will be no wait.
/* Wait for an event in event set to occur. If this the event has
* already occurred, then the semaphore will already have been
* incremented and there will be no wait.
*/
kinetis_takesem(priv);
wkupevent = priv->wkupevent;
/* Check if the event has occurred. When the event has occurred, then
* evenset will be set to 0 and wkupevent will be set to a non-zero value.
* evenset will be set to 0 and wkupevent will be set to a non-zero
* value.
*/
if (wkupevent != 0)
@@ -2604,8 +2639,8 @@ static int kinetis_registercallback(FAR struct sdio_dev_s *dev,
****************************************************************************/
#ifdef CONFIG_KINETIS_SDHC_DMA
static int kinetis_dmarecvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer,
size_t buflen)
static int kinetis_dmarecvsetup(FAR struct sdio_dev_s *dev,
FAR uint8_t *buffer, size_t buflen)
{
struct kinetis_dev_s *priv = (struct kinetis_dev_s *)dev;
@@ -2759,9 +2794,9 @@ static void kinetis_callback(void *arg)
priv->cbevents = 0;
/* Callbacks cannot be performed in the context of an interrupt handler.
* If we are in an interrupt handler, then queue the callback to be
* performed later on the work thread.
/* Callbacks cannot be performed in the context of an interrupt
* handler. If we are in an interrupt handler, then queue the
* callback to be performed later on the work thread.
*/
if (up_interrupt_context())
@@ -2797,7 +2832,8 @@ static void kinetis_callback(void *arg)
* slotno - Not used.
*
* Returned Value:
* A reference to an SDIO interface structure. NULL is returned on failures.
* A reference to an SDIO interface structure. NULL is returned on
* failures.
*
****************************************************************************/
+9 -9
View File
@@ -310,7 +310,7 @@ static int lpc17_40_takesem(struct lpc17_40_dev_s *priv);
static inline void lpc17_40_setclock(uint32_t clkcr);
static void lpc17_40_configwaitints(struct lpc17_40_dev_s *priv,
uint32_t waitmask, sdio_eventset_t waitevents,
sdio_eventset_t wkupevents);
sdio_eventset_t wkupevents);
static void lpc17_40_configxfrints(struct lpc17_40_dev_s *priv,
uint32_t xfrmask);
static void lpc17_40_setpwrctrl(uint32_t pwrctrl);
@@ -440,13 +440,13 @@ struct lpc17_40_dev_s g_scard_dev =
.sendsetup = lpc17_40_sendsetup,
.cancel = lpc17_40_cancel,
.waitresponse = lpc17_40_waitresponse,
.recvR1 = lpc17_40_recvshortcrc,
.recvR2 = lpc17_40_recvlong,
.recvR3 = lpc17_40_recvshort,
.recvR4 = lpc17_40_recvnotimpl,
.recvR5 = lpc17_40_recvnotimpl,
.recvR6 = lpc17_40_recvshortcrc,
.recvR7 = lpc17_40_recvshort,
.recv_r1 = lpc17_40_recvshortcrc,
.recv_r2 = lpc17_40_recvlong,
.recv_r3 = lpc17_40_recvshort,
.recv_r4 = lpc17_40_recvnotimpl,
.recv_r5 = lpc17_40_recvnotimpl,
.recv_r6 = lpc17_40_recvshortcrc,
.recv_r7 = lpc17_40_recvshort,
.waitenable = lpc17_40_waitenable,
.eventwait = lpc17_40_eventwait,
.callbackenable = lpc17_40_callbackenable,
@@ -1998,7 +1998,7 @@ static int lpc17_40_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd)
}
/****************************************************************************
* Name: lpc17_40_recvRx
* Name: lpc17_40_recv*
*
* Description:
* Receive response to SD card command. Only the critical payload is
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+67 -98
View File
@@ -1,36 +1,20 @@
/****************************************************************************
* arch/arm/src/stm32/stm32_sdio.c
*
* Copyright (C) 2009, 2011-2014, 2016-2019 Gregory Nutt. All rights
* reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* http://www.apache.org/licenses/LICENSE-2.0
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
@@ -86,8 +70,8 @@
* CONFIG_SDIO_MUXBUS - Setting this configuration enables some locking
* APIs to manage concurrent accesses on the SDIO bus. This is not
* needed for the simple case of a single SD card, for example.
* CONFIG_STM32_SDIO_DMA - Enable SDIO. This is a marginally optional. For
* most usages, SDIO will cause data overruns if used without DMA.
* CONFIG_STM32_SDIO_DMA - Enable SDIO. This is a marginally optional.
* For most usages, SDIO will cause data overruns if used without DMA.
* NOTE the above system DMA configuration options.
* CONFIG_STM32_SDIO_WIDTH_D1_ONLY - This may be selected to force the
* driver operate with only a single data line (the default is to use
@@ -313,31 +297,31 @@
struct stm32_dev_s
{
struct sdio_dev_s dev; /* Standard, base SDIO interface */
struct sdio_dev_s dev; /* Standard, base SDIO interface */
/* STM32-specific extensions */
/* Event support */
sem_t waitsem; /* Implements event waiting */
sdio_eventset_t waitevents; /* Set of events to be waited for */
uint32_t waitmask; /* Interrupt enables for event waiting */
sem_t waitsem; /* Implements event waiting */
sdio_eventset_t waitevents; /* Set of events to be waited for */
uint32_t waitmask; /* Interrupt enables for event waiting */
volatile sdio_eventset_t wkupevent; /* The event that caused the wakeup */
WDOG_ID waitwdog; /* Watchdog that handles event timeouts */
WDOG_ID waitwdog; /* Watchdog that handles event timeouts */
/* Callback support */
sdio_statset_t cdstatus; /* Card status */
sdio_eventset_t cbevents; /* Set of events to be cause callbacks */
worker_t callback; /* Registered callback function */
void *cbarg; /* Registered callback argument */
struct work_s cbwork; /* Callback work queue structure */
sdio_statset_t cdstatus; /* Card status */
sdio_eventset_t cbevents; /* Set of events to be cause callbacks */
worker_t callback; /* Registered callback function */
void *cbarg; /* Registered callback argument */
struct work_s cbwork; /* Callback work queue structure */
/* Interrupt mode data transfer support */
uint32_t *buffer; /* Address of current R/W buffer */
size_t remaining; /* Number of bytes remaining in the transfer */
uint32_t xfrmask; /* Interrupt enables for data transfer */
uint32_t *buffer; /* Address of current R/W buffer */
size_t remaining; /* Number of bytes remaining in the transfer */
uint32_t xfrmask; /* Interrupt enables for data transfer */
#ifdef CONFIG_STM32_SDIO_CARD
/* Interrupt at SDIO_D1 pin, only for SDIO cards */
@@ -355,11 +339,12 @@ struct stm32_dev_s
/* DMA data transfer support */
bool widebus; /* Required for DMA support */
bool widebus; /* Required for DMA support */
#ifdef CONFIG_STM32_SDIO_DMA
volatile uint8_t xfrflags; /* Used to synchronize SDIO and DMA completion events */
bool dmamode; /* true: DMA mode transfer */
DMA_HANDLE dma; /* Handle for DMA channel */
volatile uint8_t xfrflags; /* Used to synchronize SDIO and
* DMA completion events */
bool dmamode; /* true: DMA mode transfer */
DMA_HANDLE dma; /* Handle for DMA channel */
#endif
};
@@ -538,13 +523,13 @@ struct stm32_dev_s g_sdiodev =
.sendsetup = stm32_sendsetup,
.cancel = stm32_cancel,
.waitresponse = stm32_waitresponse,
.recvR1 = stm32_recvshortcrc,
.recvR2 = stm32_recvlong,
.recvR3 = stm32_recvshort,
.recvR4 = stm32_recvshort,
.recvR5 = stm32_recvshortcrc,
.recvR6 = stm32_recvshortcrc,
.recvR7 = stm32_recvshort,
.recv_r1 = stm32_recvshortcrc,
.recv_r2 = stm32_recvlong,
.recv_r3 = stm32_recvshort,
.recv_r4 = stm32_recvshort,
.recv_r5 = stm32_recvshortcrc,
.recv_r6 = stm32_recvshortcrc,
.recv_r7 = stm32_recvshort,
.waitenable = stm32_waitenable,
.eventwait = stm32_eventwait,
.callbackenable = stm32_callbackenable,
@@ -577,9 +562,6 @@ static struct stm32_sampleregs_s g_sampleregs[DEBUG_NSAMPLES];
* Private Functions
****************************************************************************/
/****************************************************************************
* Low-level Helpers
****************************************************************************/
/****************************************************************************
* Name: stm32_takesem
*
@@ -672,6 +654,7 @@ static void stm32_configwaitints(struct stm32_dev_s *priv, uint32_t waitmask,
/* Save all of the data and set the new interrupt mask in one, atomic
* operation.
*/
flags = enter_critical_section();
#ifdef CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE
@@ -793,10 +776,6 @@ static inline uint32_t stm32_getpwrctrl(void)
return getreg32(STM32_SDIO_POWER) & SDIO_POWER_PWRCTRL_MASK;
}
/****************************************************************************
* DMA Helpers
****************************************************************************/
/****************************************************************************
* Name: stm32_sampleinit
*
@@ -894,7 +873,8 @@ static void stm32_sdiodump(struct stm32_sdioregs_s *regs, const char *msg)
#ifdef CONFIG_SDIO_XFRDEBUG
static void stm32_dumpsample(struct stm32_dev_s *priv,
struct stm32_sampleregs_s *regs, const char *msg)
struct stm32_sampleregs_s *regs,
const char *msg)
{
#if defined(CONFIG_DEBUG_DMA_INFO) && defined(CONFIG_STM32_SDIO_DMA)
if (priv->dmamode)
@@ -994,10 +974,6 @@ static void stm32_dmacallback(DMA_HANDLE handle, uint8_t status, void *arg)
}
#endif
/****************************************************************************
* Data Transfer Helpers
****************************************************************************/
/****************************************************************************
* Name: stm32_log2
*
@@ -1262,7 +1238,8 @@ static void stm32_eventtimeout(int argc, uint32_t arg)
*
****************************************************************************/
static void stm32_endwait(struct stm32_dev_s *priv, sdio_eventset_t wkupevent)
static void stm32_endwait(struct stm32_dev_s *priv,
sdio_eventset_t wkupevent)
{
/* Cancel the watchdog timeout */
@@ -1318,8 +1295,8 @@ static void stm32_endtransfer(struct stm32_dev_s *priv,
stm32_sample(priv, SAMPLENDX_END_TRANSFER);
/* Make sure that the DMA is stopped (it will be stopped automatically
* on normal transfers, but not necessarily when the transfer terminates
* on an error condition).
* on normal transfers, but not necessarily when the transfer
* terminates on an error condition).
*/
stm32_dmastop(priv->dma);
@@ -1340,10 +1317,6 @@ static void stm32_endtransfer(struct stm32_dev_s *priv,
}
}
/****************************************************************************
* Interrupt Handling
****************************************************************************/
/****************************************************************************
* Name: stm32_rdyinterrupt
*
@@ -1394,7 +1367,8 @@ static int stm32_interrupt(int irq, void *context, FAR void *arg)
* bits remaining, then we have work to do here.
*/
while ((enabled = 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 ****************/
@@ -1594,10 +1568,6 @@ static int stm32_interrupt(int irq, void *context, FAR void *arg)
return OK;
}
/****************************************************************************
* SDIO Interface Methods
****************************************************************************/
/****************************************************************************
* Name: stm32_lock
*
@@ -1969,8 +1939,9 @@ static void stm32_blocksetup(FAR struct sdio_dev_s *dev,
* (interrupt driven mode). This method will do whatever controller setup
* is necessary. This would be called for SD memory just BEFORE sending
* CMD13 (SEND_STATUS), CMD17 (READ_SINGLE_BLOCK), CMD18
* (READ_MULTIPLE_BLOCKS), ACMD51 (SEND_SCR), etc. Normally, SDIO_WAITEVENT
* will be called to receive the indication that the transfer is complete.
* (READ_MULTIPLE_BLOCKS), ACMD51 (SEND_SCR), etc. Normally,
* SDIO_WAITEVENT will be called to receive the indication that the
* transfer is complete.
*
* Input Parameters:
* dev - An instance of the SDIO device interface
@@ -2134,8 +2105,8 @@ static int stm32_cancel(FAR struct sdio_dev_s *dev)
if (priv->dmamode)
{
/* Make sure that the DMA is stopped (it will be stopped automatically
* on normal transfers, but not necessarily when the transfer terminates
* on an error condition.
* on normal transfers, but not necessarily when the transfer
* terminates on an error condition.
*/
stm32_dmastop(priv->dma);
@@ -2213,7 +2184,7 @@ static int stm32_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd)
}
/****************************************************************************
* Name: stm32_recvRx
* Name: stm32_recv*
*
* Description:
* Receive response to SDIO command. Only the critical payload is
@@ -2304,7 +2275,8 @@ static int stm32_recvshortcrc(FAR struct sdio_dev_s *dev, uint32_t cmd,
/* Check response received is of desired command */
respcmd = getreg32(STM32_SDIO_RESPCMD);
if ((uint8_t)(respcmd & SDIO_RESPCMD_MASK) != (cmd & MMCSD_CMDIDX_MASK))
if ((uint8_t)(respcmd & SDIO_RESPCMD_MASK) !=
(cmd & MMCSD_CMDIDX_MASK))
{
mcerr("ERROR: RESCMD=%02x CMD=%08x\n", respcmd, cmd);
ret = -EINVAL;
@@ -2579,8 +2551,8 @@ static sdio_eventset_t stm32_eventwait(FAR struct sdio_dev_s *dev,
#if defined(CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE)
if ((priv->waitevents & SDIOWAIT_WRCOMPLETE) != 0)
{
/* Atomically read pin to see if ready (true) and determine if ISR fired
* If Pin is ready and if ISR did NOT fire end the wait here
/* Atomically read pin to see if ready (true) and determine if ISR
* fired. If Pin is ready and if ISR did NOT fire end the wait here.
*/
if (stm32_gpioread(GPIO_SDIO_D0) &&
@@ -2591,10 +2563,10 @@ static sdio_eventset_t stm32_eventwait(FAR struct sdio_dev_s *dev,
}
#endif
/* Loop until the event (or the timeout occurs). Race conditions are avoided
* by calling stm32_waitenable prior to triggering the logic that will cause
* the wait to terminate. Under certain race conditions, the waited-for
* may have already occurred before this function was called!
/* Loop until the event (or the timeout occurs). Race conditions are
* avoided by calling stm32_waitenable prior to triggering the logic that
* will cause the wait to terminate. Under certain race conditions, the
* waited-for may have already occurred before this function was called!
*/
for (; ; )
@@ -2774,8 +2746,8 @@ static int stm32_dmapreflight(FAR struct sdio_dev_s *dev,
****************************************************************************/
#ifdef CONFIG_STM32_SDIO_DMA
static int stm32_dmarecvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer,
size_t buflen)
static int stm32_dmarecvsetup(FAR struct sdio_dev_s *dev,
FAR uint8_t *buffer, size_t buflen)
{
struct stm32_dev_s *priv = (struct stm32_dev_s *)dev;
uint32_t dblocksize;
@@ -2916,9 +2888,6 @@ static int stm32_dmasendsetup(FAR struct sdio_dev_s *dev,
}
#endif
/****************************************************************************
* Initialization/uninitialization/reset
****************************************************************************/
/****************************************************************************
* Name: stm32_callback
*
@@ -2975,9 +2944,9 @@ static void stm32_callback(void *arg)
priv->cbevents = 0;
/* Callbacks cannot be performed in the context of an interrupt handler.
* If we are in an interrupt handler, then queue the callback to be
* performed later on the work thread.
/* Callbacks cannot be performed in the context of an interrupt
* handler. If we are in an interrupt handler, then queue the
* callback to be performed later on the work thread.
*/
if (up_interrupt_context())
+71 -88
View File
@@ -378,7 +378,7 @@
struct stm32_dev_s
{
struct sdio_dev_s dev; /* Standard, base SDIO interface */
struct sdio_dev_s dev; /* Standard, base SDIO interface */
/* STM32-specific extensions */
@@ -393,34 +393,34 @@ struct stm32_dev_s
/* Event support */
sem_t waitsem; /* Implements event waiting */
sdio_eventset_t waitevents; /* Set of events to be waited for */
uint32_t waitmask; /* Interrupt enables for event waiting */
sem_t waitsem; /* Implements event waiting */
sdio_eventset_t waitevents; /* Set of events to be waited for */
uint32_t waitmask; /* Interrupt enables for event waiting */
volatile sdio_eventset_t wkupevent; /* The event that caused the wakeup */
WDOG_ID waitwdog; /* Watchdog that handles event timeouts */
WDOG_ID waitwdog; /* Watchdog that handles event timeouts */
/* Callback support */
sdio_statset_t cdstatus; /* Card status */
sdio_eventset_t cbevents; /* Set of events to be cause callbacks */
worker_t callback; /* Registered callback function */
void *cbarg; /* Registered callback argument */
struct work_s cbwork; /* Callback work queue structure */
sdio_statset_t cdstatus; /* Card status */
sdio_eventset_t cbevents; /* Set of events to be cause callbacks */
worker_t callback; /* Registered callback function */
void *cbarg; /* Registered callback argument */
struct work_s cbwork; /* Callback work queue structure */
/* Interrupt mode data transfer support */
uint32_t *buffer; /* Address of current R/W buffer */
size_t remaining; /* Number of bytes remaining in the transfer */
uint32_t xfrmask; /* Interrupt enables for data transfer */
uint32_t *buffer; /* Address of current R/W buffer */
size_t remaining; /* Number of bytes remaining in the transfer */
uint32_t xfrmask; /* Interrupt enables for data transfer */
/* DMA data transfer support */
bool widebus; /* Required for DMA support */
bool onebit; /* true: Only 1-bit transfers are supported */
bool widebus; /* Required for DMA support */
bool onebit; /* true: Only 1-bit transfers are supported */
#ifdef CONFIG_STM32F7_SDMMC_DMA
volatile uint8_t xfrflags; /* Used to synchronize SDMMC and DMA completion events */
bool dmamode; /* true: DMA mode transfer */
DMA_HANDLE dma; /* Handle for DMA channel */
volatile uint8_t xfrflags; /* Used to synchronize SDMMC and DMA completion events */
bool dmamode; /* true: DMA mode transfer */
DMA_HANDLE dma; /* Handle for DMA channel */
#endif
#ifdef HAVE_SDMMC_SDIO_MODE
@@ -434,7 +434,7 @@ struct stm32_dev_s
/* Misc */
uint32_t blocksize; /* Current block size */
uint32_t blocksize; /* Current block size */
};
/* Register logging support */
@@ -617,13 +617,13 @@ struct stm32_dev_s g_sdmmcdev1 =
.sendsetup = stm32_sendsetup,
.cancel = stm32_cancel,
.waitresponse = stm32_waitresponse,
.recvR1 = stm32_recvshortcrc,
.recvR2 = stm32_recvlong,
.recvR3 = stm32_recvshort,
.recvR4 = stm32_recvshort,
.recvR5 = stm32_recvshortcrc,
.recvR6 = stm32_recvshortcrc,
.recvR7 = stm32_recvshort,
.recv_r1 = stm32_recvshortcrc,
.recv_r2 = stm32_recvlong,
.recv_r3 = stm32_recvshort,
.recv_r4 = stm32_recvshort,
.recv_r5 = stm32_recvshortcrc,
.recv_r6 = stm32_recvshortcrc,
.recv_r7 = stm32_recvshort,
.waitenable = stm32_waitenable,
.eventwait = stm32_eventwait,
.callbackenable = stm32_callbackenable,
@@ -687,13 +687,13 @@ struct stm32_dev_s g_sdmmcdev2 =
.sendsetup = stm32_sendsetup,
.cancel = stm32_cancel,
.waitresponse = stm32_waitresponse,
.recvR1 = stm32_recvshortcrc,
.recvR2 = stm32_recvlong,
.recvR3 = stm32_recvshort,
.recvR4 = stm32_recvshort,
.recvR5 = stm32_recvshortcrc,
.recvR6 = stm32_recvshortcrc,
.recvR7 = stm32_recvshort,
.recv_r1 = stm32_recvshortcrc,
.recv_r2 = stm32_recvlong,
.recv_r3 = stm32_recvshort,
.recv_r4 = stm32_recvshort,
.recv_r5 = stm32_recvshortcrc,
.recv_r6 = stm32_recvshortcrc,
.recv_r7 = stm32_recvshort,
.waitenable = stm32_waitenable,
.eventwait = stm32_eventwait,
.callbackenable = stm32_callbackenable,
@@ -738,10 +738,6 @@ static struct stm32_sampleregs_s g_sampleregs[DEBUG_NSAMPLES];
* Private Functions
****************************************************************************/
/****************************************************************************
* Low-level Helpers
****************************************************************************/
/****************************************************************************
* Name: sdmmc_putreg32
****************************************************************************/
@@ -913,8 +909,9 @@ static void stm32_configwaitints(struct stm32_dev_s *priv, uint32_t waitmask,
#ifdef HAVE_SDMMC_SDIO_MODE
if (priv->sdiomode == true)
{
sdmmc_putreg32(priv, priv->xfrmask | priv->waitmask | priv->sdiointmask,
STM32_SDMMC_MASK_OFFSET);
sdmmc_putreg32(priv,
priv->xfrmask | priv->waitmask | priv->sdiointmask,
STM32_SDMMC_MASK_OFFSET);
}
else
#endif
@@ -950,7 +947,8 @@ static void stm32_configxfrints(struct stm32_dev_s *priv, uint32_t xfrmask)
#ifdef HAVE_SDMMC_SDIO_MODE
if (priv->sdiomode == true)
{
sdmmc_putreg32(priv, priv->xfrmask | priv->waitmask | priv->sdiointmask,
sdmmc_putreg32(priv,
priv->xfrmask | priv->waitmask | priv->sdiointmask,
STM32_SDMMC_MASK_OFFSET);
}
else
@@ -1011,10 +1009,6 @@ static inline uint32_t stm32_getpwrctrl(struct stm32_dev_s *priv)
STM32_SDMMC_POWER_PWRCTRL_MASK;
}
/****************************************************************************
* DMA Helpers
****************************************************************************/
/****************************************************************************
* Name: stm32_sampleinit
*
@@ -1113,7 +1107,8 @@ static void stm32_sdiodump(struct stm32_sdioregs_s *regs, const char *msg)
#ifdef CONFIG_STM32F7_SDMMC_XFRDEBUG
static void stm32_dumpsample(struct stm32_dev_s *priv,
struct stm32_sampleregs_s *regs, const char *msg)
struct stm32_sampleregs_s *regs,
const char *msg)
{
#if defined(CONFIG_DEBUG_DMA_INFO) && defined(CONFIG_STM32F7_SDMMC_DMA)
if (priv->dmamode)
@@ -1148,7 +1143,8 @@ static void stm32_dumpsamples(struct stm32_dev_s *priv)
}
#endif
stm32_dumpsample(priv, &g_sampleregs[SAMPLENDX_AFTER_SETUP], "After setup");
stm32_dumpsample(priv, &g_sampleregs[SAMPLENDX_AFTER_SETUP],
"After setup");
stm32_dumpsample(priv, &g_sampleregs[SAMPLENDX_END_TRANSFER],
"End of transfer");
@@ -1211,10 +1207,6 @@ static void stm32_dmacallback(DMA_HANDLE handle, uint8_t status, void *arg)
}
#endif
/****************************************************************************
* Data Transfer Helpers
****************************************************************************/
/****************************************************************************
* Name: stm32_log2
*
@@ -1497,7 +1489,8 @@ static void stm32_eventtimeout(int argc, uint32_t arg)
*
****************************************************************************/
static void stm32_endwait(struct stm32_dev_s *priv, sdio_eventset_t wkupevent)
static void stm32_endwait(struct stm32_dev_s *priv,
sdio_eventset_t wkupevent)
{
/* Cancel the watchdog timeout */
@@ -1566,8 +1559,8 @@ static void stm32_endtransfer(struct stm32_dev_s *priv,
stm32_sample(priv, SAMPLENDX_END_TRANSFER);
/* Make sure that the DMA is stopped (it will be stopped automatically
* on normal transfers, but not necessarily when the transfer terminates
* on an error condition).
* on normal transfers, but not necessarily when the transfer
* terminates on an error condition).
*/
stm32_dmastop(priv->dma);
@@ -1588,10 +1581,6 @@ static void stm32_endtransfer(struct stm32_dev_s *priv,
}
}
/****************************************************************************
* Interrupt Handling
****************************************************************************/
/****************************************************************************
* Name: stm32_sdmmc[1|2]_rdyinterrupt
*
@@ -1671,9 +1660,9 @@ static int stm32_sdmmc_interrupt(int irq, void *context, void *arg)
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!
/* 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 & STM32_SDMMC_STA_TXFIFOHE) != 0)
@@ -1862,10 +1851,6 @@ static int stm32_sdmmc_interrupt(int irq, void *context, void *arg)
return OK;
}
/****************************************************************************
* SDIO Interface Methods
****************************************************************************/
/****************************************************************************
* Name: stm32_lock
*
@@ -2395,8 +2380,8 @@ static int stm32_cancel(FAR struct sdio_dev_s *dev)
if (priv->dmamode)
{
/* Make sure that the DMA is stopped (it will be stopped automatically
* on normal transfers, but not necessarily when the transfer terminates
* on an error condition.
* on normal transfers, but not necessarily when the transfer
* terminates on an error condition.
*/
stm32_dmastop(priv->dma);
@@ -2475,7 +2460,7 @@ static int stm32_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd)
}
/****************************************************************************
* Name: stm32_recvRx
* Name: stm32_recv*
*
* Description:
* Receive response to SDIO command. Only the critical payload is
@@ -2848,8 +2833,8 @@ static sdio_eventset_t stm32_eventwait(FAR struct sdio_dev_s *dev,
#if defined(CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE)
if ((priv->waitevents & SDIOWAIT_WRCOMPLETE) != 0)
{
/* Atomically read pin to see if ready (true) and determine if ISR fired
* If Pin is ready and if ISR did NOT fire end the wait here
/* Atomically read pin to see if ready (true) and determine if ISR
* fired. If Pin is ready and if ISR did NOT fire end the wait here.
*/
if (stm32_gpioread(priv->d0_gpio) &&
@@ -2860,10 +2845,10 @@ static sdio_eventset_t stm32_eventwait(FAR struct sdio_dev_s *dev,
}
#endif
/* Loop until the event (or the timeout occurs). Race conditions are avoided
* by calling stm32_waitenable prior to triggering the logic that will cause
* the wait to terminate. Under certain race conditions, the waited-for
* may have already occurred before this function was called!
/* Loop until the event (or the timeout occurs). Race conditions are
* avoided by calling stm32_waitenable prior to triggering the logic that
* will cause the wait to terminate. Under certain race conditions, the
* waited-for may have already occurred before this function was called!
*/
for (; ; )
@@ -3036,8 +3021,8 @@ static int stm32_dmapreflight(FAR struct sdio_dev_s *dev,
****************************************************************************/
#ifdef CONFIG_STM32F7_SDMMC_DMA
static int stm32_dmarecvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer,
size_t buflen)
static int stm32_dmarecvsetup(FAR struct sdio_dev_s *dev,
FAR uint8_t *buffer, size_t buflen)
{
struct stm32_dev_s *priv = (struct stm32_dev_s *)dev;
uint32_t dblksize;
@@ -3097,7 +3082,8 @@ static int stm32_dmarecvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer,
/* Force RAM reread */
if ((uintptr_t)buffer < DTCM_START || (uintptr_t)buffer + buflen > DTCM_END)
if ((uintptr_t)buffer < DTCM_START ||
(uintptr_t)buffer + buflen > DTCM_END)
{
#if !defined(CONFIG_ARCH_HAVE_SDIO_DELAYED_INVLDT)
up_invalidate_dcache((uintptr_t)buffer, (uintptr_t)buffer + buflen);
@@ -3171,7 +3157,8 @@ static int stm32_dmasendsetup(FAR struct sdio_dev_s *dev,
/* Flush cache to physical memory when not in DTCM memory */
if ((uintptr_t)buffer < DTCM_START || (uintptr_t)buffer + buflen > DTCM_END)
if ((uintptr_t)buffer < DTCM_START ||
(uintptr_t)buffer + buflen > DTCM_END)
{
#ifdef CONFIG_ARMV7M_DCACHE_WRITETHROUGH
up_invalidate_dcache((uintptr_t)buffer, (uintptr_t)buffer + buflen);
@@ -3254,10 +3241,6 @@ static int stm32_dmadelydinvldt(FAR struct sdio_dev_s *dev,
}
#endif
/****************************************************************************
* Initialization/uninitialization/reset
****************************************************************************/
/****************************************************************************
* Name: stm32_callback
*
@@ -3314,9 +3297,9 @@ static void stm32_callback(void *arg)
priv->cbevents = 0;
/* Callbacks cannot be performed in the context of an interrupt handler.
* If we are in an interrupt handler, then queue the callback to be
* performed later on the work thread.
/* Callbacks cannot be performed in the context of an interrupt
* handler. If we are in an interrupt handler, then queue the
* callback to be performed later on the work thread.
*/
if (up_interrupt_context())
@@ -3402,8 +3385,8 @@ FAR struct sdio_dev_s *sdio_initialize(int slotno)
priv->onebit = false;
# endif
/* Configure GPIOs for 4-bit, wide-bus operation (the chip is capable of
* 8-bit wide bus operation but D4-D7 are not configured).
/* Configure GPIOs for 4-bit, wide-bus operation (the chip is capable
* of 8-bit wide bus operation but D4-D7 are not configured).
*
* If bus is multiplexed then there is a custom bus configuration
* utility in the scope of the board support package.
@@ -3439,8 +3422,8 @@ FAR struct sdio_dev_s *sdio_initialize(int slotno)
priv->onebit = false;
# endif
/* Configure GPIOs for 4-bit, wide-bus operation (the chip is capable of
* 8-bit wide bus operation but D4-D7 are not configured).
/* Configure GPIOs for 4-bit, wide-bus operation (the chip is capable
* of 8-bit wide bus operation but D4-D7 are not configured).
*
* If bus is multiplexed then there is a custom bus configuration
* utility in the scope of the board support package.
+70 -72
View File
@@ -305,7 +305,7 @@
struct stm32_dev_s
{
struct sdio_dev_s dev; /* Standard, base SDIO interface */
struct sdio_dev_s dev; /* Standard, base SDIO interface */
/* STM32-specific extensions */
@@ -317,30 +317,30 @@ struct stm32_dev_s
/* Event support */
sem_t waitsem; /* Implements event waiting */
sdio_eventset_t waitevents; /* Set of events to be waited for */
uint32_t waitmask; /* Interrupt enables for event waiting */
sem_t waitsem; /* Implements event waiting */
sdio_eventset_t waitevents; /* Set of events to be waited for */
uint32_t waitmask; /* Interrupt enables for event waiting */
volatile sdio_eventset_t wkupevent; /* The event that caused the wakeup */
WDOG_ID waitwdog; /* Watchdog that handles event timeouts */
WDOG_ID waitwdog; /* Watchdog that handles event timeouts */
/* Callback support */
sdio_statset_t cdstatus; /* Card status */
sdio_eventset_t cbevents; /* Set of events to be cause callbacks */
worker_t callback; /* Registered callback function */
void *cbarg; /* Registered callback argument */
struct work_s cbwork; /* Callback work queue structure */
sdio_statset_t cdstatus; /* Card status */
sdio_eventset_t cbevents; /* Set of events to be cause callbacks */
worker_t callback; /* Registered callback function */
void *cbarg; /* Registered callback argument */
struct work_s cbwork; /* Callback work queue structure */
/* Interrupt mode data transfer support */
uint32_t *buffer; /* Address of current R/W buffer */
size_t remaining; /* Number of bytes remaining in the transfer */
uint32_t xfrmask; /* Interrupt enables for data transfer */
uint32_t *buffer; /* Address of current R/W buffer */
size_t remaining; /* Number of bytes remaining in the transfer */
uint32_t xfrmask; /* Interrupt enables for data transfer */
/* DMA data transfer support */
bool widebus; /* Required for DMA support */
bool onebit; /* true: Only 1-bit transfers are supported */
bool widebus; /* Required for DMA support */
bool onebit; /* true: Only 1-bit transfers are supported */
#if defined(HAVE_SDMMC_SDIO_MODE)
/* Interrupt at SDIO_D1 pin, only for SDIO cards */
@@ -353,10 +353,10 @@ struct stm32_dev_s
/* Misc */
uint32_t blocksize; /* Current block size */
uint32_t receivecnt; /* Real count to receive */
uint32_t blocksize; /* Current block size */
uint32_t receivecnt; /* Real count to receive */
#if !defined(CONFIG_STM32H7_SDMMC_IDMA)
struct work_s cbfifo; /* Monitor for Lame FIFO */
struct work_s cbfifo; /* Monitor for Lame FIFO */
#endif
uint8_t rxfifo[FIFO_SIZE_IN_BYTES] /* To offload with IDMA */
__attribute__((aligned(ARMV7M_DCACHE_LINESIZE)));
@@ -402,7 +402,7 @@ static void stm32_configxfrints(struct stm32_dev_s *priv, uint32_t xfrmask);
static void stm32_setpwrctrl(struct stm32_dev_s *priv, uint32_t pwrctrl);
static inline uint32_t stm32_getpwrctrl(struct stm32_dev_s *priv);
/* Debug Helpers **************************************************************/
/* Debug Helpers ************************************************************/
#if defined(CONFIG_STM32H7_SDMMC_XFRDEBUG)
static void stm32_sampleinit(void);
@@ -537,13 +537,13 @@ struct stm32_dev_s g_sdmmcdev1 =
.sendsetup = stm32_sendsetup,
.cancel = stm32_cancel,
.waitresponse = stm32_waitresponse,
.recvR1 = stm32_recvshortcrc,
.recvR2 = stm32_recvlong,
.recvR3 = stm32_recvshort,
.recvR4 = stm32_recvshort,
.recvR5 = stm32_recvshortcrc,
.recvR6 = stm32_recvshortcrc,
.recvR7 = stm32_recvshort,
.recv_r1 = stm32_recvshortcrc,
.recv_r2 = stm32_recvlong,
.recv_r3 = stm32_recvshort,
.recv_r4 = stm32_recvshort,
.recv_r5 = stm32_recvshortcrc,
.recv_r6 = stm32_recvshortcrc,
.recv_r7 = stm32_recvshort,
.waitenable = stm32_waitenable,
.eventwait = stm32_eventwait,
.callbackenable = stm32_callbackenable,
@@ -589,13 +589,13 @@ struct stm32_dev_s g_sdmmcdev2 =
.sendsetup = stm32_sendsetup,
.cancel = stm32_cancel,
.waitresponse = stm32_waitresponse,
.recvR1 = stm32_recvshortcrc,
.recvR2 = stm32_recvlong,
.recvR3 = stm32_recvshort,
.recvR4 = stm32_recvshort,
.recvR5 = stm32_recvshortcrc,
.recvR6 = stm32_recvshortcrc,
.recvR7 = stm32_recvshort,
.recv_r1 = stm32_recvshortcrc,
.recv_r2 = stm32_recvlong,
.recv_r3 = stm32_recvshort,
.recv_r4 = stm32_recvshort,
.recv_r5 = stm32_recvshortcrc,
.recv_r6 = stm32_recvshortcrc,
.recv_r7 = stm32_recvshort,
.waitenable = stm32_waitenable,
.eventwait = stm32_eventwait,
.callbackenable = stm32_callbackenable,
@@ -802,7 +802,8 @@ static void stm32_configwaitints(struct stm32_dev_s *priv, uint32_t waitmask,
#if defined(HAVE_SDMMC_SDIO_MODE)
if (priv->sdiomode == true)
{
sdmmc_putreg32(priv, priv->xfrmask | priv->waitmask | priv->sdiointmask,
sdmmc_putreg32(priv,
priv->xfrmask | priv->waitmask | priv->sdiointmask,
STM32_SDMMC_MASK_OFFSET);
}
else
@@ -840,7 +841,8 @@ static void stm32_configxfrints(struct stm32_dev_s *priv, uint32_t xfrmask)
#if defined(HAVE_SDMMC_SDIO_MODE)
if (priv->sdiomode == true)
{
sdmmc_putreg32(priv, priv->xfrmask | priv->waitmask | priv->sdiointmask,
sdmmc_putreg32(priv,
priv->xfrmask | priv->waitmask | priv->sdiointmask,
STM32_SDMMC_MASK_OFFSET);
}
else
@@ -901,10 +903,6 @@ static inline uint32_t stm32_getpwrctrl(struct stm32_dev_s *priv)
STM32_SDMMC_POWER_PWRCTRL_MASK;
}
/****************************************************************************
* Debug Helpers
****************************************************************************/
/****************************************************************************
* Name: stm32_sampleinit
*
@@ -1318,7 +1316,8 @@ static void stm32_eventtimeout(int argc, uint32_t arg)
*
****************************************************************************/
static void stm32_endwait(struct stm32_dev_s *priv, sdio_eventset_t wkupevent)
static void stm32_endwait(struct stm32_dev_s *priv,
sdio_eventset_t wkupevent)
{
/* Cancel the watchdog timeout */
@@ -1433,7 +1432,8 @@ static void stm32_sdmmc_fifo_monitor(FAR void *arg)
/* Check for the lame FIFO condition */
if (sdmmc_getreg32(priv, STM32_SDMMC_DCOUNT_OFFSET) != 0 &&
sdmmc_getreg32(priv, STM32_SDMMC_STA_OFFSET) == STM32_SDMMC_STA_DPSMACT)
sdmmc_getreg32(priv, STM32_SDMMC_STA_OFFSET) ==
STM32_SDMMC_STA_DPSMACT)
{
work_queue(HPWORK, &priv->cbfifo,
(worker_t)stm32_sdmmc_fifo_monitor, arg, 1);
@@ -1441,10 +1441,6 @@ static void stm32_sdmmc_fifo_monitor(FAR void *arg)
}
#endif
/****************************************************************************
* Interrupt Handling
****************************************************************************/
/****************************************************************************
* Name: stm32_sdmmc[1|2]_rdyinterrupt
*
@@ -1561,7 +1557,8 @@ static int stm32_sdmmc_interrupt(int irq, void *context, void *arg)
* we used IDMA to manage the lame fifo
*/
if (priv->remaining && priv->remaining < FIFO_SIZE_IN_BYTES / 2)
if (priv->remaining && priv->remaining <
FIFO_SIZE_IN_BYTES / 2)
{
memcpy(priv->buffer, priv->rxfifo, priv->remaining);
}
@@ -1581,7 +1578,9 @@ static int stm32_sdmmc_interrupt(int irq, void *context, void *arg)
mcerr("ERROR: Data block CRC failure, remaining: %d\n",
priv->remaining);
stm32_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR);
stm32_endtransfer(priv,
SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR);
}
/* Handle data timeout error */
@@ -1594,6 +1593,7 @@ static int stm32_sdmmc_interrupt(int irq, void *context, void *arg)
mcerr("ERROR: Data timeout, remaining: %d\n",
priv->remaining);
stm32_endtransfer(priv, SDIOWAIT_TRANSFERDONE |
SDIOWAIT_TIMEOUT);
}
@@ -1608,6 +1608,7 @@ static int stm32_sdmmc_interrupt(int irq, void *context, void *arg)
mcerr("ERROR: RX FIFO overrun, remaining: %d\n",
priv->remaining);
stm32_endtransfer(priv, SDIOWAIT_TRANSFERDONE |
SDIOWAIT_ERROR);
}
@@ -1622,6 +1623,7 @@ static int stm32_sdmmc_interrupt(int irq, void *context, void *arg)
mcerr("ERROR: TX FIFO underrun, remaining: %d\n",
priv->remaining);
stm32_endtransfer(priv, SDIOWAIT_TRANSFERDONE |
SDIOWAIT_ERROR);
}
@@ -1699,10 +1701,6 @@ static int stm32_sdmmc_interrupt(int irq, void *context, void *arg)
return OK;
}
/****************************************************************************
* SDIO Interface Methods
****************************************************************************/
/****************************************************************************
* Name: stm32_lock
*
@@ -2366,7 +2364,7 @@ static int stm32_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd)
}
/****************************************************************************
* Name: stm32_recvRx
* Name: stm32_recv*
*
* Description:
* Receive response to SDIO command. Only the critical payload is
@@ -2739,8 +2737,8 @@ static sdio_eventset_t stm32_eventwait(FAR struct sdio_dev_s *dev,
#if defined(CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE)
if ((priv->waitevents & SDIOWAIT_WRCOMPLETE) != 0)
{
/* Atomically read pin to see if ready (true) and determine if ISR fired
* If Pin is ready and if ISR did NOT fire end the wait here
/* Atomically read pin to see if ready (true) and determine if ISR
* fired. If Pin is ready and if ISR did NOT fire end the wait here
*/
if (stm32_gpioread(priv->d0_gpio) &&
@@ -2751,10 +2749,10 @@ static sdio_eventset_t stm32_eventwait(FAR struct sdio_dev_s *dev,
}
#endif
/* Loop until the event (or the timeout occurs). Race conditions are avoided
* by calling stm32_waitenable prior to triggering the logic that will cause
* the wait to terminate. Under certain race conditions, the waited-for
* may have already occurred before this function was called!
/* Loop until the event (or the timeout occurs). Race conditions are
* avoided by calling stm32_waitenable prior to triggering the logic that
* will cause the wait to terminate. Under certain race conditions, the
* waited-for may have already occurred before this function was called!
*/
for (; ; )
@@ -2891,8 +2889,8 @@ static int stm32_dmapreflight(FAR struct sdio_dev_s *dev,
# if defined(CONFIG_ARMV7M_DCACHE) && !defined(CONFIG_ARMV7M_DCACHE_WRITETHROUGH)
/* buffer alignment is required for DMA transfers with dcache in buffered
* mode (not write-through) because a) arch_invalidate_dcache could lose
* buffered writes and b) arch_flush_dcache could corrupt adjacent memory if
* the maddr and the mend+1, the next next address are not on
* buffered writes and b) arch_flush_dcache could corrupt adjacent memory
* if the maddr and the mend+1, the next next address are not on
* ARMV7M_DCACHE_LINESIZE boundaries.
*/
@@ -2935,8 +2933,8 @@ static int stm32_dmapreflight(FAR struct sdio_dev_s *dev,
****************************************************************************/
#if defined(CONFIG_STM32H7_SDMMC_IDMA)
static int stm32_dmarecvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer,
size_t buflen)
static int stm32_dmarecvsetup(FAR struct sdio_dev_s *dev,
FAR uint8_t *buffer, size_t buflen)
{
struct stm32_dev_s *priv = (struct stm32_dev_s *)dev;
uint32_t dblksize;
@@ -2994,7 +2992,8 @@ static int stm32_dmarecvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer,
/* Force RAM reread */
# if !defined(CONFIG_ARCH_HAVE_SDIO_DELAYED_INVLDT)
if ((uintptr_t)buffer < DTCM_START || (uintptr_t)buffer + buflen > DTCM_END)
if ((uintptr_t)buffer < DTCM_START ||
(uintptr_t)buffer + buflen > DTCM_END)
{
up_invalidate_dcache((uintptr_t)buffer, (uintptr_t)buffer + buflen);
}
@@ -3068,7 +3067,8 @@ static int stm32_dmasendsetup(FAR struct sdio_dev_s *dev,
# if defined(CONFIG_ARMV7M_DCACHE) && \
!defined(CONFIG_ARMV7M_DCACHE_WRITETHROUGH)
if ((uintptr_t)buffer < DTCM_START || (uintptr_t)buffer + buflen > DTCM_END)
if ((uintptr_t)buffer < DTCM_START ||
(uintptr_t)buffer + buflen > DTCM_END)
{
up_clean_dcache((uintptr_t)buffer, (uintptr_t)buffer + buflen);
}
@@ -3140,10 +3140,6 @@ static int stm32_dmadelydinvldt(FAR struct sdio_dev_s *dev,
}
#endif
/****************************************************************************
* Initialization/uninitialization/reset
****************************************************************************/
/****************************************************************************
* Name: stm32_callback
*
@@ -3200,16 +3196,18 @@ static void stm32_callback(void *arg)
priv->cbevents = 0;
/* Callbacks cannot be performed in the context of an interrupt handler.
* If we are in an interrupt handler, then queue the callback to be
* performed later on the work thread.
/* Callbacks cannot be performed in the context of an interrupt
* handler. If we are in an interrupt handler, then queue the
* callback to be performed later on the work thread.
*/
if (up_interrupt_context())
{
/* Yes.. queue it */
mcinfo("Queuing callback to %p(%p)\n", priv->callback, priv->cbarg);
mcinfo("Queuing callback to %p(%p)\n",
priv->callback, priv->cbarg);
work_queue(HPWORK, &priv->cbwork, (worker_t)priv->callback,
priv->cbarg, 0);
}
+59 -57
View File
@@ -328,7 +328,7 @@
struct stm32_dev_s
{
struct sdio_dev_s dev; /* Standard, base SDIO interface */
struct sdio_dev_s dev; /* Standard, base SDIO interface */
/* STM32-specific extensions */
@@ -343,34 +343,34 @@ struct stm32_dev_s
/* Event support */
sem_t waitsem; /* Implements event waiting */
sdio_eventset_t waitevents; /* Set of events to be waited for */
uint32_t waitmask; /* Interrupt enables for event waiting */
sem_t waitsem; /* Implements event waiting */
sdio_eventset_t waitevents; /* Set of events to be waited for */
uint32_t waitmask; /* Interrupt enables for event waiting */
volatile sdio_eventset_t wkupevent; /* The event that caused the wakeup */
WDOG_ID waitwdog; /* Watchdog that handles event timeouts */
WDOG_ID waitwdog; /* Watchdog that handles event timeouts */
/* Callback support */
sdio_statset_t cdstatus; /* Card status */
sdio_eventset_t cbevents; /* Set of events to be cause callbacks */
worker_t callback; /* Registered callback function */
void *cbarg; /* Registered callback argument */
struct work_s cbwork; /* Callback work queue structure */
sdio_statset_t cdstatus; /* Card status */
sdio_eventset_t cbevents; /* Set of events to be cause callbacks */
worker_t callback; /* Registered callback function */
void *cbarg; /* Registered callback argument */
struct work_s cbwork; /* Callback work queue structure */
/* Interrupt mode data transfer support */
uint32_t *buffer; /* Address of current R/W buffer */
size_t remaining; /* Number of bytes remaining in the transfer */
uint32_t xfrmask; /* Interrupt enables for data transfer */
uint32_t *buffer; /* Address of current R/W buffer */
size_t remaining; /* Number of bytes remaining in the transfer */
uint32_t xfrmask; /* Interrupt enables for data transfer */
/* DMA data transfer support */
bool widebus; /* Required for DMA support */
bool onebit; /* true: Only 1-bit transfers are supported */
bool widebus; /* Required for DMA support */
bool onebit; /* true: Only 1-bit transfers are supported */
#ifdef CONFIG_STM32L4_SDMMC_DMA
volatile uint8_t xfrflags; /* Used to synchronize SDMMC and DMA completion events */
bool dmamode; /* true: DMA mode transfer */
DMA_HANDLE dma; /* Handle for DMA channel */
volatile uint8_t xfrflags; /* Used to synchronize SDMMC and DMA completion events */
bool dmamode; /* true: DMA mode transfer */
DMA_HANDLE dma; /* Handle for DMA channel */
#endif
};
@@ -552,13 +552,13 @@ struct stm32_dev_s g_sdmmcdev1 =
.sendsetup = stm32_sendsetup,
.cancel = stm32_cancel,
.waitresponse = stm32_waitresponse,
.recvR1 = stm32_recvshortcrc,
.recvR2 = stm32_recvlong,
.recvR3 = stm32_recvshort,
.recvR4 = stm32_recvnotimpl,
.recvR5 = stm32_recvnotimpl,
.recvR6 = stm32_recvshortcrc,
.recvR7 = stm32_recvshort,
.recv_r1 = stm32_recvshortcrc,
.recv_r2 = stm32_recvlong,
.recv_r3 = stm32_recvshort,
.recv_r4 = stm32_recvnotimpl,
.recv_r5 = stm32_recvnotimpl,
.recv_r6 = stm32_recvshortcrc,
.recv_r7 = stm32_recvshort,
.waitenable = stm32_waitenable,
.eventwait = stm32_eventwait,
.callbackenable = stm32_callbackenable,
@@ -613,13 +613,13 @@ struct stm32_dev_s g_sdmmcdev2 =
.sendsetup = stm32_sendsetup,
.cancel = stm32_cancel,
.waitresponse = stm32_waitresponse,
.recvR1 = stm32_recvshortcrc,
.recvR2 = stm32_recvlong,
.recvR3 = stm32_recvshort,
.recvR4 = stm32_recvnotimpl,
.recvR5 = stm32_recvnotimpl,
.recvR6 = stm32_recvshortcrc,
.recvR7 = stm32_recvshort,
.recv_r1 = stm32_recvshortcrc,
.recv_r2 = stm32_recvlong,
.recv_r3 = stm32_recvshort,
.recv_r4 = stm32_recvnotimpl,
.recv_r5 = stm32_recvnotimpl,
.recv_r6 = stm32_recvshortcrc,
.recv_r7 = stm32_recvshort,
.waitenable = stm32_waitenable,
.eventwait = stm32_eventwait,
.callbackenable = stm32_callbackenable,
@@ -998,7 +998,8 @@ static void stm32_sdiodump(struct stm32_sdioregs_s *regs, const char *msg)
#ifdef CONFIG_STM32L4_SDMMC_XFRDEBUG
static void stm32_dumpsample(struct stm32_dev_s *priv,
struct stm32_sampleregs_s *regs, const char *msg)
struct stm32_sampleregs_s *regs,
const char *msg)
{
#if defined(CONFIG_DEBUG_DMA_INFO) && defined(CONFIG_STM32L4_SDMMC_DMA)
if (priv->dmamode)
@@ -1368,7 +1369,8 @@ static void stm32_eventtimeout(int argc, uint32_t arg)
*
****************************************************************************/
static void stm32_endwait(struct stm32_dev_s *priv, sdio_eventset_t wkupevent)
static void stm32_endwait(struct stm32_dev_s *priv,
sdio_eventset_t wkupevent)
{
/* Cancel the watchdog timeout */
@@ -1424,8 +1426,8 @@ static void stm32_endtransfer(struct stm32_dev_s *priv,
stm32_sample(priv, SAMPLENDX_END_TRANSFER);
/* Make sure that the DMA is stopped (it will be stopped automatically
* on normal transfers, but not necessarily when the transfer terminates
* on an error condition).
* on normal transfers, but not necessarily when the transfer
* terminates on an error condition).
*/
stm32l4_dmastop(priv->dma);
@@ -1523,9 +1525,9 @@ static int stm32_sdmmc_interrupt(int irq, void *context, void *arg)
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!
/* 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 & STM32_SDMMC_STA_TXFIFOHE) != 0)
@@ -2171,8 +2173,8 @@ static int stm32_cancel(FAR struct sdio_dev_s *dev)
if (priv->dmamode)
{
/* Make sure that the DMA is stopped (it will be stopped automatically
* on normal transfers, but not necessarily when the transfer terminates
* on an error condition.
* on normal transfers, but not necessarily when the transfer
* terminates on an error condition.
*/
stm32l4_dmastop(priv->dma);
@@ -2253,7 +2255,7 @@ static int stm32_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd)
}
/****************************************************************************
* Name: stm32_recvRx
* Name: stm32_recv*
*
* Description:
* Receive response to SDIO command. Only the critical payload is
@@ -2637,8 +2639,8 @@ static sdio_eventset_t stm32_eventwait(FAR struct sdio_dev_s *dev,
#if defined(CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE)
if ((priv->waitevents & SDIOWAIT_WRCOMPLETE) != 0)
{
/* Atomically read pin to see if ready (true) and determine if ISR fired
* If Pin is ready and if ISR did NOT fire end the wait here
/* Atomically read pin to see if ready (true) and determine if ISR
* fired. If Pin is ready and if ISR did NOT fire end the wait here
*/
if (stm32_gpioread(priv->d0_gpio) &&
@@ -2649,10 +2651,10 @@ static sdio_eventset_t stm32_eventwait(FAR struct sdio_dev_s *dev,
}
#endif
/* Loop until the event (or the timeout occurs). Race conditions are avoided
* by calling stm32_waitenable prior to triggering the logic that will cause
* the wait to terminate. Under certain race conditions, the waited-for
* may have already occurred before this function was called!
/* Loop until the event (or the timeout occurs). Race conditions are
* avoided by calling stm32_waitenable prior to triggering the logic that
* will cause the wait to terminate. Under certain race conditions, the
* waited-for may have already occurred before this function was called!
*/
for (; ; )
@@ -2820,8 +2822,8 @@ static int stm32_dmapreflight(FAR struct sdio_dev_s *dev,
****************************************************************************/
#ifdef CONFIG_STM32L4_SDMMC_DMA
static int stm32_dmarecvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer,
size_t buflen)
static int stm32_dmarecvsetup(FAR struct sdio_dev_s *dev,
FAR uint8_t *buffer, size_t buflen)
{
struct stm32_dev_s *priv = (struct stm32_dev_s *)dev;
uint32_t dblocksize;
@@ -3000,9 +3002,9 @@ static void stm32_callback(void *arg)
priv->cbevents = 0;
/* Callbacks cannot be performed in the context of an interrupt handler.
* If we are in an interrupt handler, then queue the callback to be
* performed later on the work thread.
/* Callbacks cannot be performed in the context of an interrupt
* handler. If we are in an interrupt handler, then queue the
* callback to be performed later on the work thread.
*/
if (up_interrupt_context())
@@ -3089,8 +3091,8 @@ FAR struct sdio_dev_s *sdio_initialize(int slotno)
priv->onebit = false;
#endif
/* Configure GPIOs for 4-bit, wide-bus operation (the chip is capable of
* 8-bit wide bus operation but D4-D7 are not configured).
/* Configure GPIOs for 4-bit, wide-bus operation (the chip is capable
* of 8-bit wide bus operation but D4-D7 are not configured).
*
* If bus is multiplexed then there is a custom bus configuration
* utility in the scope of the board support package.
@@ -3125,8 +3127,8 @@ FAR struct sdio_dev_s *sdio_initialize(int slotno)
priv->onebit = false;
#endif
/* Configure GPIOs for 4-bit, wide-bus operation (the chip is capable of
* 8-bit wide bus operation but D4-D7 are not configured).
/* Configure GPIOs for 4-bit, wide-bus operation (the chip is capable
* of 8-bit wide bus operation but D4-D7 are not configured).
*
* If bus is multiplexed then there is a custom bus configuration
* utility in the scope of the board support package.
+1 -1
View File
@@ -2946,7 +2946,7 @@ static int mmcsd_sdinitialize(FAR struct mmcsd_state_s *priv)
ret = mmsd_recv_r6(priv, SD_CMD3);
if (ret != OK)
{
ferr("ERROR: mmcsd_recvR2 for SD RCA failed: %d\n", ret);
ferr("ERROR: mmsd_recv_r6 for SD RCA failed: %d\n", ret);
return ret;
}
+45 -58
View File
@@ -1,36 +1,20 @@
/****************************************************************************
* include/nuttx/sdio.h
*
* Copyright (C) 2009, 2011-2013, 2017, 2019 Gregory Nutt. All rights
* reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* http://www.apache.org/licenses/LICENSE-2.0
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
@@ -55,7 +39,8 @@
/* SDIO events needed by the driver
*
* Wait events are used for event-waiting by SDIO_WAITENABLE and SDIO_EVENTWAIT
* Wait events are used for event-waiting by SDIO_WAITENABLE and
* SDIO_EVENTWAIT
*/
#define SDIOWAIT_CMDDONE (1 << 0) /* Bit 0: Command complete */
@@ -65,10 +50,10 @@
#define SDIOWAIT_ERROR (1 << 4) /* Bit 4: Some other error occurred */
/* SDIOWAIT_WRCOMPLETE (optional) : Certain SDIO driver can use D0 busy
* signalling to detect Write Complete. Used of D0 busy signalling will
* signaling to detect Write Complete. Used of D0 busy signaling will
* avoid potentially very long (600Ms+) busy waiting in the MMCSD driver.
*
* To implement D0 Busy signalling, the underlying SDIO driver must be
* To implement D0 Busy signaling, the underlying SDIO driver must be
* capable of switching the D0 GPIO to be a rising edge sensitive
* interrupt pin. It must then, condition that pin to detect the rising
* edge on receipt of SDWAIT_WRCOMPLETE in the SDIO_WAITENABLE call and
@@ -88,8 +73,8 @@
#define SDIOMEDIA_EJECTED (1 << 0) /* Bit 0: Media removed */
#define SDIOMEDIA_INSERTED (1 << 1) /* Bit 1: Media inserted */
/* Commands are bit-encoded to provide as much information to the SDIO driver as
* possible in 32-bits. The encoding is as follows:
/* Commands are bit-encoded to provide as much information to the SDIO
* driver as possible in 32-bits. The encoding is as follows:
*
* ---- ---- ---- ---- ---T TTRR RRCC CCCC
*
@@ -336,7 +321,8 @@
/* SDIO Card Common Control Registers definitions
* see https://www.sdcard.org/developers/overview/sdio/
* sdio_spec/Simplified_SDIO_Card_Spec.pdf */
* sdio_spec/Simplified_SDIO_Card_Spec.pdf
*/
#define SDIO_CCCR_REV 0x00 /* CCCR/SDIO Revision */
#define SDIO_CCCR_SD_SPEC_REV 0x01 /* SD Specification Revision */
@@ -556,8 +542,9 @@
* (interrupt driven mode). This method will do whatever controller setup
* is necessary. This would be called for SD memory just BEFORE sending
* CMD13 (SEND_STATUS), CMD17 (READ_SINGLE_BLOCK), CMD18
* (READ_MULTIPLE_BLOCKS), ACMD51 (SEND_SCR), etc. Normally, SDIO_WAITEVENT
* will be called to receive the indication that the transfer is complete.
* (READ_MULTIPLE_BLOCKS), ACMD51 (SEND_SCR), etc. Normally,
* SDIO_WAITEVENT will be called to receive the indication that the
* transfer is complete.
*
* Input Parameters:
* dev - An instance of the SDIO device interface
@@ -575,9 +562,9 @@
* Name: SDIO_SENDSETUP
*
* Description:
* Setup hardware in preparation for data transfer from the card. This method
* will do whatever controller setup is necessary. This would be called
* for SD memory just AFTER sending CMD24 (WRITE_BLOCK), CMD25
* Setup hardware in preparation for data transfer from the card. This
* method will do whatever controller setup is necessary. This would be
* called for SD memory just AFTER sending CMD24 (WRITE_BLOCK), CMD25
* (WRITE_MULTIPLE_BLOCK), ... and before SDIO_SENDDATA is called.
*
* Input Parameters:
@@ -653,13 +640,13 @@
*
****************************************************************************/
#define SDIO_RECVR1(dev,cmd,R1) ((dev)->recvR1(dev,cmd,R1)) /* 48-bit */
#define SDIO_RECVR2(dev,cmd,R2) ((dev)->recvR2(dev,cmd,R2)) /* 136-bit */
#define SDIO_RECVR3(dev,cmd,R3) ((dev)->recvR3(dev,cmd,R3)) /* 48-bit */
#define SDIO_RECVR4(dev,cmd,R4) ((dev)->recvR4(dev,cmd,R4)) /* 48-bit */
#define SDIO_RECVR5(dev,cmd,R5) ((dev)->recvR5(dev,cmd,R5)) /* 48-bit */
#define SDIO_RECVR6(dev,cmd,R6) ((dev)->recvR6(dev,cmd,R6)) /* 48-bit */
#define SDIO_RECVR7(dev,cmd,R7) ((dev)->recvR7(dev,cmd,R7)) /* 48-bit */
#define SDIO_RECVR1(dev,cmd,R1) ((dev)->recv_r1(dev,cmd,R1)) /* 48-bit */
#define SDIO_RECVR2(dev,cmd,R2) ((dev)->recv_r2(dev,cmd,R2)) /* 136-bit */
#define SDIO_RECVR3(dev,cmd,R3) ((dev)->recv_r3(dev,cmd,R3)) /* 48-bit */
#define SDIO_RECVR4(dev,cmd,R4) ((dev)->recv_r4(dev,cmd,R4)) /* 48-bit */
#define SDIO_RECVR5(dev,cmd,R5) ((dev)->recv_r5(dev,cmd,R5)) /* 48-bit */
#define SDIO_RECVR6(dev,cmd,R6) ((dev)->recv_r6(dev,cmd,R6)) /* 48-bit */
#define SDIO_RECVR7(dev,cmd,R7) ((dev)->recv_r7(dev,cmd,R7)) /* 48-bit */
/****************************************************************************
* Name: SDIO_WAITENABLE
@@ -679,8 +666,8 @@
* SDIO_WAITEVENT: Wait for the event of interest (which might
* already have occurred)
*
* This sequence should eliminate race conditions between the command/transfer
* setup and the subsequent events.
* This sequence should eliminate race conditions between the command/
* transfer setup and the subsequent events.
*
* The enabled events persist until either (1) SDIO_WAITENABLE is called
* again specifying a different set of wait events, or (2) SDIO_EVENTWAIT
@@ -887,8 +874,8 @@ enum sdio_clock_e
CLOCK_SD_TRANSFER_4BIT /* SD normal operation clocking (wide 4-bit mode) */
};
/* Event set. A uint8_t is big enough to hold a set of 8-events. If more are
* needed, change this to a uint16_t.
/* Event set. A uint8_t is big enough to hold a set of 8-events. If more
* are needed, change this to a uint16_t.
*/
typedef uint8_t sdio_eventset_t;
@@ -948,13 +935,13 @@ struct sdio_dev_s
int (*cancel)(FAR struct sdio_dev_s *dev);
int (*waitresponse)(FAR struct sdio_dev_s *dev, uint32_t cmd);
int (*recvR1)(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t *R1);
int (*recvR2)(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t R2[4]);
int (*recvR3)(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t *R3);
int (*recvR4)(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t *R4);
int (*recvR5)(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t *R5);
int (*recvR6)(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t *R6);
int (*recvR7)(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t *R7);
int (*recv_r1)(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t *R1);
int (*recv_r2)(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t R2[4]);
int (*recv_r3)(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t *R3);
int (*recv_r4)(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t *R4);
int (*recv_r5)(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t *R5);
int (*recv_r6)(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t *R6);
int (*recv_r7)(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t *R7);
/* Event/Callback support */
@@ -990,7 +977,7 @@ struct sdio_dev_s
};
/****************************************************************************
* Public Functions
* Public Function Prototypes
****************************************************************************/
#undef EXTERN