diff --git a/Documentation/NuttxPortingGuide.html b/Documentation/NuttxPortingGuide.html index 7282af8f4f9..a015584d263 100644 --- a/Documentation/NuttxPortingGuide.html +++ b/Documentation/NuttxPortingGuide.html @@ -240,7 +240,7 @@

NuttX RTOS Porting Guide

-

Last Updated: August 8, 2019

+

Last Updated: April 2, 2020

@@ -6220,13 +6220,13 @@ int kbd_decode(FAR struct lib_instream_s *stream, FAR struct kbd_getstate_s *sta int (*sendsetup)(FAR struct sdio_dev_s *dev, FAR const uint8_t *buffer, size_t nbytes);
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: diff --git a/arch/arm/src/cxd56xx/cxd56_sdhci.c b/arch/arm/src/cxd56xx/cxd56_sdhci.c index 4b4e6253303..0af13e0aa0b 100644 --- a/arch/arm/src/cxd56xx/cxd56_sdhci.c +++ b/arch/arm/src/cxd56xx/cxd56_sdhci.c @@ -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. * ****************************************************************************/ diff --git a/arch/arm/src/imxrt/imxrt_usdhc.c b/arch/arm/src/imxrt/imxrt_usdhc.c index b70392992e5..e582455c833 100644 --- a/arch/arm/src/imxrt/imxrt_usdhc.c +++ b/arch/arm/src/imxrt/imxrt_usdhc.c @@ -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 diff --git a/arch/arm/src/kinetis/kinetis_sdhc.c b/arch/arm/src/kinetis/kinetis_sdhc.c index 58d912bc0ea..a360cb13947 100644 --- a/arch/arm/src/kinetis/kinetis_sdhc.c +++ b/arch/arm/src/kinetis/kinetis_sdhc.c @@ -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. * ****************************************************************************/ diff --git a/arch/arm/src/lpc17xx_40xx/lpc17_40_sdcard.c b/arch/arm/src/lpc17xx_40xx/lpc17_40_sdcard.c index 6f352c45e91..36b381af15d 100644 --- a/arch/arm/src/lpc17xx_40xx/lpc17_40_sdcard.c +++ b/arch/arm/src/lpc17xx_40xx/lpc17_40_sdcard.c @@ -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 diff --git a/arch/arm/src/lpc43xx/lpc43_sdmmc.c b/arch/arm/src/lpc43xx/lpc43_sdmmc.c index f961335dac2..a41106a8856 100644 --- a/arch/arm/src/lpc43xx/lpc43_sdmmc.c +++ b/arch/arm/src/lpc43xx/lpc43_sdmmc.c @@ -87,6 +87,7 @@ #define MCI_DMADES1_BS1(x) (x) /* Configuration ************************************************************/ + /* Required system configuration options in the sched/Kconfig: * * CONFIG_SCHED_WORKQUEUE -- Callback support requires work queue support. @@ -217,40 +218,42 @@ struct sdmmc_dma_s struct lpc43_dev_s { - struct sdio_dev_s dev; /* Standard, base SD card interface */ + struct sdio_dev_s dev; /* Standard, base SD card interface */ /* LPC43XX-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 */ - uint32_t xfrmask; /* Interrupt enables for data transfer */ + uint32_t *buffer; /* Address of current R/W buffer */ + uint32_t xfrmask; /* Interrupt enables for data transfer */ #ifdef CONFIG_LPC43_SDMMC_DMA - uint32_t dmamask; /* Interrupt enables for DMA transfer */ + uint32_t dmamask; /* Interrupt enables for DMA transfer */ #endif - ssize_t remaining; /* Number of bytes remaining in the transfer */ - bool wrdir; /* True: Writing False: Reading */ + ssize_t remaining; /* Number of bytes remaining in the + * transfer */ + bool wrdir; /* True: Writing False: Reading */ /* DMA data transfer support */ - bool widebus; /* Required for DMA support */ + bool widebus; /* Required for DMA support */ #ifdef CONFIG_LPC43_SDMMC_DMA - bool dmamode; /* true: DMA mode transfer */ + bool dmamode; /* true: DMA mode transfer */ #endif }; @@ -275,19 +278,22 @@ static inline void lpc43_sdcard_clock(bool enable); static int lpc43_ciu_sendcmd(uint32_t cmd, uint32_t arg); static void lpc43_enable_ints(struct lpc43_dev_s *priv); static void lpc43_disable_allints(struct lpc43_dev_s *priv); -static void lpc43_config_waitints(struct lpc43_dev_s *priv, uint32_t waitmask, - sdio_eventset_t waitevents, sdio_eventset_t wkupevents); +static void lpc43_config_waitints(struct lpc43_dev_s *priv, + uint32_t waitmask, sdio_eventset_t waitevents, + sdio_eventset_t wkupevents); static void lpc43_config_xfrints(struct lpc43_dev_s *priv, uint32_t xfrmask); #ifdef CONFIG_LPC43_SDMMC_DMA static void lpc43_config_dmaints(struct lpc43_dev_s *priv, uint32_t xfrmask, - uint32_t dmamask); + uint32_t dmamask); #endif /* Data Transfer Helpers ****************************************************/ static void lpc43_eventtimeout(int argc, uint32_t arg); -static void lpc43_endwait(struct lpc43_dev_s *priv, sdio_eventset_t wkupevent); -static void lpc43_endtransfer(struct lpc43_dev_s *priv, sdio_eventset_t wkupevent); +static void lpc43_endwait(struct lpc43_dev_s *priv, + sdio_eventset_t wkupevent); +static void lpc43_endtransfer(struct lpc43_dev_s *priv, + sdio_eventset_t wkupevent); /* Interrupt Handling *******************************************************/ @@ -381,13 +387,13 @@ struct lpc43_dev_s g_scard_dev = .sendsetup = lpc43_sendsetup, .cancel = lpc43_cancel, .waitresponse = lpc43_waitresponse, - .recvR1 = lpc43_recvshortcrc, - .recvR2 = lpc43_recvlong, - .recvR3 = lpc43_recvshort, - .recvR4 = lpc43_recvnotimpl, - .recvR5 = lpc43_recvnotimpl, - .recvR6 = lpc43_recvshortcrc, - .recvR7 = lpc43_recvshort, + .recv_r1 = lpc43_recvshortcrc, + .recv_r2 = lpc43_recvlong, + .recv_r3 = lpc43_recvshort, + .recv_r4 = lpc43_recvnotimpl, + .recv_r5 = lpc43_recvnotimpl, + .recv_r6 = lpc43_recvshortcrc, + .recv_r7 = lpc43_recvshort, .waitenable = lpc43_waitenable, .eventwait = lpc43_eventwait, .callbackenable = lpc43_callbackenable, @@ -461,7 +467,7 @@ static uint32_t lpc43_getreg(uint32_t addr) { /* Yes.. then show how many times the value repeated */ - mcinfo("[repeats %d more times]\n", count-3); + mcinfo("[repeats %d more times]\n", count - 3); } /* Save the new address, value, and count */ @@ -635,7 +641,8 @@ static int lpc43_ciu_sendcmd(uint32_t cmd, uint32_t arg) { if (watchtime - clock_systimer() > SDCARD_CMDTIMEOUT) { - mcerr("TMO Timed out (%08X)\n",lpc43_getreg(LPC43_SDMMC_CMD)); + mcerr("TMO Timed out (%08X)\n", + lpc43_getreg(LPC43_SDMMC_CMD)); return 1; } } @@ -730,7 +737,8 @@ static void lpc43_disable_allints(struct lpc43_dev_s *priv) * ****************************************************************************/ -static void lpc43_config_waitints(struct lpc43_dev_s *priv, uint32_t waitmask, +static void lpc43_config_waitints(struct lpc43_dev_s *priv, + uint32_t waitmask, sdio_eventset_t waitevents, sdio_eventset_t wkupevent) { @@ -835,7 +843,8 @@ static void lpc43_eventtimeout(int argc, uint32_t arg) /* There is always race conditions with timer expirations. */ - DEBUGASSERT((priv->waitevents & SDIOWAIT_TIMEOUT) != 0 || priv->wkupevent != 0); + DEBUGASSERT((priv->waitevents & SDIOWAIT_TIMEOUT) != 0 || + priv->wkupevent != 0); /* Is a data transfer complete event expected? */ @@ -866,7 +875,8 @@ static void lpc43_eventtimeout(int argc, uint32_t arg) * ****************************************************************************/ -static void lpc43_endwait(struct lpc43_dev_s *priv, sdio_eventset_t wkupevent) +static void lpc43_endwait(struct lpc43_dev_s *priv, + sdio_eventset_t wkupevent) { mcinfo("wkupevent=%04x\n", (unsigned)wkupevent); @@ -903,7 +913,8 @@ static void lpc43_endwait(struct lpc43_dev_s *priv, sdio_eventset_t wkupevent) * ****************************************************************************/ -static void lpc43_endtransfer(struct lpc43_dev_s *priv, sdio_eventset_t wkupevent) +static void lpc43_endtransfer(struct lpc43_dev_s *priv, + sdio_eventset_t wkupevent) { mcinfo("wkupevent=%04x\n", (unsigned)wkupevent); @@ -972,12 +983,14 @@ static int lpc43_sdmmc_interrupt(int irq, void *context, FAR void *arg) /* Update card status */ cdstatus = priv->cdstatus; - if ((lpc43_getreg(LPC43_SDMMC_CDETECT) & SDMMC_CDETECT_NOTPRESENT) == 0) + if ((lpc43_getreg(LPC43_SDMMC_CDETECT) & + SDMMC_CDETECT_NOTPRESENT) == 0) { priv->cdstatus |= SDIO_STATUS_PRESENT; #ifdef CONFIG_MMCSD_HAVE_WRITEPROTECT - if ((lpc43_getreg(LPC43_SDMMC_WRTPRT) & SDMMC_WRTPRT_PROTECTED) != 0) + if ((lpc43_getreg(LPC43_SDMMC_WRTPRT) & + SDMMC_WRTPRT_PROTECTED) != 0) { priv->cdstatus |= SDIO_STATUS_WRPROTECTED; } @@ -992,11 +1005,11 @@ static int lpc43_sdmmc_interrupt(int irq, void *context, FAR void *arg) lpc43_putreg(SDMMC_PWREN, LPC43_SDMMC_PWREN); #endif - } else { - priv->cdstatus &= ~(SDIO_STATUS_PRESENT | SDIO_STATUS_WRPROTECTED); + priv->cdstatus &= + ~(SDIO_STATUS_PRESENT | SDIO_STATUS_WRPROTECTED); #ifdef CONFIG_LPC43_SDMMC_PWRCTRL /* Disable power to the SD card */ @@ -1061,6 +1074,7 @@ static int lpc43_sdmmc_interrupt(int irq, void *context, FAR void *arg) } /* Check for transfer errors */ + /* Handle data block send/receive CRC failure */ if ((pending & SDMMC_INT_DCRC) != 0) @@ -1069,7 +1083,9 @@ static int lpc43_sdmmc_interrupt(int irq, void *context, FAR void *arg) mcerr("ERROR: Data CRC failure, pending=%08x remaining: %d\n", pending, priv->remaining); - lpc43_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR); + + lpc43_endtransfer(priv, + SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR); } /* Handle data timeout error */ @@ -1080,7 +1096,9 @@ static int lpc43_sdmmc_interrupt(int irq, void *context, FAR void *arg) mcerr("ERROR: Data timeout, pending=%08x remaining: %d\n", pending, priv->remaining); - lpc43_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_TIMEOUT); + + lpc43_endtransfer(priv, + SDIOWAIT_TRANSFERDONE | SDIOWAIT_TIMEOUT); } /* Handle RX FIFO overrun error */ @@ -1091,7 +1109,9 @@ static int lpc43_sdmmc_interrupt(int irq, void *context, FAR void *arg) mcerr("ERROR: RX FIFO overrun, pending=%08x remaining: %d\n", pending, priv->remaining); - lpc43_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR); + + lpc43_endtransfer(priv, + SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR); } /* Handle TX FIFO underrun error */ @@ -1102,7 +1122,9 @@ static int lpc43_sdmmc_interrupt(int irq, void *context, FAR void *arg) mcerr("ERROR: TX FIFO underrun, pending=%08x remaining: %d\n", pending, priv->remaining); - lpc43_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR); + + lpc43_endtransfer(priv, + SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR); } /* Handle start bit error */ @@ -1113,7 +1135,9 @@ static int lpc43_sdmmc_interrupt(int irq, void *context, FAR void *arg) mcerr("ERROR: Start bit, pending=%08x remaining: %d\n", pending, priv->remaining); - lpc43_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR); + + lpc43_endtransfer(priv, + SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR); } /* Handle data end events. Note that RXDR may accompany DTO, DTO @@ -1259,7 +1283,8 @@ static void lpc43_reset(FAR struct sdio_dev_s *dev) SDMMC_CTRL_DMARESET, LPC43_SDMMC_CTRL); while ((lpc43_getreg(LPC43_SDMMC_CTRL) & - (SDMMC_CTRL_CNTLRRESET | SDMMC_CTRL_FIFORESET | SDMMC_CTRL_DMARESET)) != 0) + (SDMMC_CTRL_CNTLRRESET | SDMMC_CTRL_FIFORESET | + SDMMC_CTRL_DMARESET)) != 0) { } @@ -1597,7 +1622,8 @@ static int lpc43_sendcmd(FAR struct sdio_dev_s *dev, uint32_t cmd, if ((cmd & MMCSD_WRDATAXFR) == MMCSD_WRDATAXFR) { - regval |= SDMMC_CMD_DATAXFREXPTD | SDMMC_CMD_WRITE | SDMMC_CMD_WAITPREV; + regval |= SDMMC_CMD_DATAXFREXPTD | SDMMC_CMD_WRITE | + SDMMC_CMD_WAITPREV; } else if ((cmd & MMCSD_RDDATAXFR) == MMCSD_RDDATAXFR) { @@ -1678,12 +1704,13 @@ static void lpc43_blocksetup(FAR struct sdio_dev_s *dev, * Name: lpc43_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, SDCARD_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, + * SDCARD_WAITEVENT will be called to receive the indication that the + * transfer is complete. * * Input Parameters: * dev - An instance of the SD card device interface @@ -1762,8 +1789,8 @@ static int lpc43_recvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, * ****************************************************************************/ -static int lpc43_sendsetup(FAR struct sdio_dev_s *dev, FAR const uint8_t *buffer, - size_t nbytes) +static int lpc43_sendsetup(FAR struct sdio_dev_s *dev, + FAR const uint8_t *buffer, size_t nbytes) { struct lpc43_dev_s *priv = (struct lpc43_dev_s *)dev; #ifdef CONFIG_LPC43_SDMMC_DMA @@ -1816,9 +1843,9 @@ static int lpc43_sendsetup(FAR struct sdio_dev_s *dev, FAR const uint8_t *buffer * * Description: * Cancel the data transfer setup of SDCARD_RECVSETUP, SDCARD_SENDSETUP, - * SDCARD_DMARECVSETUP or SDCARD_DMASENDSETUP. This must be called to cancel - * the data transfer setup if, for some reason, you cannot perform the - * transfer. + * SDCARD_DMARECVSETUP or SDCARD_DMASENDSETUP. This must be called to + * cancel the data transfer setup if, for some reason, you cannot perform + * the transfer. * * Input Parameters: * dev - An instance of the SD card device interface @@ -1917,7 +1944,8 @@ static int lpc43_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd) { if (clock_systimer() - watchtime > timeout) { - mcerr("ERROR: Timeout cmd: %04x events: %04x STA: %08x RINTSTS: %08x\n", + mcerr("ERROR: Timeout cmd: %04x events: %04x STA: %08x " + "RINTSTS: %08x\n", cmd, events, lpc43_getreg(LPC43_SDMMC_STATUS), lpc43_getreg(LPC43_SDMMC_RINTSTS)); @@ -1925,7 +1953,8 @@ static int lpc43_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd) } else if ((lpc43_getreg(LPC43_SDMMC_RINTSTS) & SDCARD_INT_RESPERR) != 0) { - mcerr("ERROR: SDMMC failure cmd: %04x events: %04x STA: %08x RINTSTS: %08x\n", + mcerr("ERROR: SDMMC failure cmd: %04x events: %04x STA: %08x " + "RINTSTS: %08x\n", cmd, events, lpc43_getreg(LPC43_SDMMC_STATUS), lpc43_getreg(LPC43_SDMMC_RINTSTS)); @@ -1938,7 +1967,7 @@ static int lpc43_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd) } /**************************************************************************** - * Name: lpc43_recvRx + * Name: lpc43_recv* * * Description: * Receive response to SD card command. Only the critical payload is @@ -1990,7 +2019,6 @@ static int lpc43_recvshortcrc(FAR struct sdio_dev_s *dev, uint32_t cmd, * 0 1 End bit */ - #ifdef CONFIG_DEBUG_FEATURES if (!rshort) { @@ -2095,7 +2123,8 @@ static int lpc43_recvlong(FAR struct sdio_dev_s *dev, uint32_t cmd, return ret; } -static int lpc43_recvshort(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t *rshort) +static int lpc43_recvshort(FAR struct sdio_dev_s *dev, uint32_t cmd, + uint32_t *rshort) { uint32_t regval; int ret = OK; @@ -2224,9 +2253,9 @@ static void lpc43_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 SDCARD_WAITEVENTS are disabled when lpc43_eventwait - * returns. SDCARD_WAITEVENTS must be called again before lpc43_eventwait - * can be used again. + * all events enabled by SDCARD_WAITEVENTS are disabled when + * lpc43_eventwait returns. SDCARD_WAITEVENTS must be called again before + * lpc43_eventwait can be used again. * * Input Parameters: * dev - An instance of the SD card device interface @@ -2287,24 +2316,25 @@ static sdio_eventset_t lpc43_eventwait(FAR struct sdio_dev_s *dev, } } - /* Loop until the event (or the timeout occurs). Race conditions are avoided - * by calling lpc43_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 lpc43_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. */ lpc43_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 nonzero value. + * evenset will be set to 0 and wkupevent will be set to a nonzero + * value. */ if (wkupevent != 0) @@ -2329,9 +2359,9 @@ errout: * Name: lpc43_callbackenable * * Description: - * Enable/disable of a set of SD card callback events. This is part of the - * the SD card callback sequence. The set of events is configured to enabled - * callbacks to the function provided in lpc43_registercallback. + * Enable/disable of a set of SD card callback events. This is part of + * the SD card callback sequence. The set of events is configured to + * enabled callbacks to the function provided in lpc43_registercallback. * * Events are automatically disabled once the callback is performed and no * further callback events will occur until they are again enabled by @@ -2419,8 +2449,8 @@ static int lpc43_registercallback(FAR struct sdio_dev_s *dev, ****************************************************************************/ #ifdef CONFIG_LPC43_SDMMC_DMA -static int lpc43_dmarecvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, - size_t buflen) +static int lpc43_dmarecvsetup(FAR struct sdio_dev_s *dev, + FAR uint8_t *buffer, size_t buflen) { struct lpc43_dev_s *priv = (struct lpc43_dev_s *)dev; uint32_t regval; @@ -2448,7 +2478,9 @@ static int lpc43_dmarecvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, lpc43_putreg(SDMMC_BMOD_SWR, LPC43_SDMMC_BMOD); - /* Save the destination buffer information for use by the interrupt handler */ + /* Save the destination buffer information for use by the interrupt + * handler. + */ priv->buffer = (uint32_t *)buffer; priv->remaining = buflen; @@ -2461,12 +2493,13 @@ static int lpc43_dmarecvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, regval |= SDMMC_CTRL_FIFORESET | SDMMC_CTRL_DMARESET; lpc43_putreg(regval, LPC43_SDMMC_CTRL); - while ((lpc43_getreg(LPC43_SDMMC_CTRL) & (SDMMC_CTRL_FIFORESET | SDMMC_CTRL_DMARESET)) != 0) + while ((lpc43_getreg(LPC43_SDMMC_CTRL) & (SDMMC_CTRL_FIFORESET | + SDMMC_CTRL_DMARESET)) != 0) { } - /* Configure the FIFO so that we will receive the DMA/FIFO requests whenever - * there more than than (FIFO_DEPTH/2) - 1 words in the FIFO. + /* Configure the FIFO so that we will receive the DMA/FIFO requests + * whenever there more than than (FIFO_DEPTH/2) - 1 words in the FIFO. */ regval = SDMMC_FIFOTH_RXWMARK(LPC43_RXFIFO_DEPTH / 2 - 1) | @@ -2495,7 +2528,8 @@ static int lpc43_dmarecvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, /* Setup buffer address (chained) */ - g_sdmmc_dmadd[i].des2 = (uint32_t)priv->buffer + (i * MCI_DMADES1_MAXTR); + g_sdmmc_dmadd[i].des2 = (uint32_t)priv->buffer + + (i * MCI_DMADES1_MAXTR); /* Setup basic control */ @@ -2611,12 +2645,13 @@ static int lpc43_dmasendsetup(FAR struct sdio_dev_s *dev, regval |= SDMMC_CTRL_FIFORESET | SDMMC_CTRL_DMARESET; lpc43_putreg(regval, LPC43_SDMMC_CTRL); - while ((lpc43_getreg(LPC43_SDMMC_CTRL) & (SDMMC_CTRL_FIFORESET | SDMMC_CTRL_DMARESET)) != 0) + while ((lpc43_getreg(LPC43_SDMMC_CTRL) & (SDMMC_CTRL_FIFORESET | + SDMMC_CTRL_DMARESET)) != 0) { } - /* Configure the FIFO so that we will receive the DMA/FIFO requests whenever - * there are FIFO_DEPTH/2 or fewer words in the FIFO. + /* Configure the FIFO so that we will receive the DMA/FIFO requests + * whenever there are FIFO_DEPTH/2 or fewer words in the FIFO. */ regval = SDMMC_FIFOTH_TXWMARK(LPC43_TXFIFO_DEPTH / 2) | @@ -2645,7 +2680,8 @@ static int lpc43_dmasendsetup(FAR struct sdio_dev_s *dev, /* Setup buffer address (chained) */ - g_sdmmc_dmadd[i].des2 = (uint32_t)priv->buffer + (i * MCI_DMADES1_MAXTR); + g_sdmmc_dmadd[i].des2 = (uint32_t)priv->buffer + + (i * MCI_DMADES1_MAXTR); /* Setup basic control */ @@ -2750,17 +2786,19 @@ static void lpc43_callback(struct lpc43_dev_s *priv) 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); - work_queue(HPWORK, &priv->cbwork, (worker_t)priv->callback, priv->cbarg, 0); + mcinfo("Queuing callback to %p(%p)\n", + priv->callback, priv->cbarg); + work_queue(HPWORK, &priv->cbwork, (worker_t)priv->callback, + priv->cbarg, 0); } else { @@ -2786,7 +2824,8 @@ static void lpc43_callback(struct lpc43_dev_s *priv) * slotno - Not used. * * Returned Value: - * A reference to an SD card interface structure. NULL is returned on failures. + * A reference to an SD card interface structure. NULL is returned on + * failures. * ****************************************************************************/ diff --git a/arch/arm/src/lpc54xx/lpc54_sdmmc.c b/arch/arm/src/lpc54xx/lpc54_sdmmc.c index bae4b8d7fd3..be8c0d2a8a5 100644 --- a/arch/arm/src/lpc54xx/lpc54_sdmmc.c +++ b/arch/arm/src/lpc54xx/lpc54_sdmmc.c @@ -91,6 +91,7 @@ #define MCI_DMADES1_BS1(x) (x) /* Configuration ************************************************************/ + /* Required system configuration options in the sched/Kconfig: * * CONFIG_SCHED_WORKQUEUE -- Callback support requires work queue support. @@ -221,40 +222,42 @@ struct sdmmc_dma_s struct lpc54_dev_s { - struct sdio_dev_s dev; /* Standard, base SD card interface */ + struct sdio_dev_s dev; /* Standard, base SD card interface */ /* LPC54XX-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 */ - uint32_t xfrmask; /* Interrupt enables for data transfer */ + uint32_t *buffer; /* Address of current R/W buffer */ + uint32_t xfrmask; /* Interrupt enables for data transfer */ #ifdef CONFIG_LPC54_SDMMC_DMA - uint32_t dmamask; /* Interrupt enables for DMA transfer */ + uint32_t dmamask; /* Interrupt enables for DMA transfer */ #endif - ssize_t remaining; /* Number of bytes remaining in the transfer */ - bool wrdir; /* True: Writing False: Reading */ + ssize_t remaining; /* Number of bytes remaining in the + * transfer */ + bool wrdir; /* True: Writing False: Reading */ /* DMA data transfer support */ - bool widebus; /* Required for DMA support */ + bool widebus; /* Required for DMA support */ #ifdef CONFIG_LPC54_SDMMC_DMA - bool dmamode; /* true: DMA mode transfer */ + bool dmamode; /* true: DMA mode transfer */ #endif }; @@ -279,19 +282,22 @@ static inline void lpc54_sdcard_clock(bool enable); static int lpc54_ciu_sendcmd(uint32_t cmd, uint32_t arg); static void lpc54_enable_ints(struct lpc54_dev_s *priv); static void lpc54_disable_allints(struct lpc54_dev_s *priv); -static void lpc54_config_waitints(struct lpc54_dev_s *priv, uint32_t waitmask, - sdio_eventset_t waitevents, sdio_eventset_t wkupevents); +static void lpc54_config_waitints(struct lpc54_dev_s *priv, + uint32_t waitmask, sdio_eventset_t waitevents, + sdio_eventset_t wkupevents); static void lpc54_config_xfrints(struct lpc54_dev_s *priv, uint32_t xfrmask); #ifdef CONFIG_LPC54_SDMMC_DMA static void lpc54_config_dmaints(struct lpc54_dev_s *priv, uint32_t xfrmask, - uint32_t dmamask); + uint32_t dmamask); #endif /* Data Transfer Helpers ****************************************************/ static void lpc54_eventtimeout(int argc, uint32_t arg); -static void lpc54_endwait(struct lpc54_dev_s *priv, sdio_eventset_t wkupevent); -static void lpc54_endtransfer(struct lpc54_dev_s *priv, sdio_eventset_t wkupevent); +static void lpc54_endwait(struct lpc54_dev_s *priv, + sdio_eventset_t wkupevent); +static void lpc54_endtransfer(struct lpc54_dev_s *priv, + sdio_eventset_t wkupevent); /* Interrupt Handling *******************************************************/ @@ -385,13 +391,13 @@ struct lpc54_dev_s g_scard_dev = .sendsetup = lpc54_sendsetup, .cancel = lpc54_cancel, .waitresponse = lpc54_waitresponse, - .recvR1 = lpc54_recvshortcrc, - .recvR2 = lpc54_recvlong, - .recvR3 = lpc54_recvshort, - .recvR4 = lpc54_recvnotimpl, - .recvR5 = lpc54_recvnotimpl, - .recvR6 = lpc54_recvshortcrc, - .recvR7 = lpc54_recvshort, + .recv_r1 = lpc54_recvshortcrc, + .recv_r2 = lpc54_recvlong, + .recv_r3 = lpc54_recvshort, + .recv_r4 = lpc54_recvnotimpl, + .recv_r5 = lpc54_recvnotimpl, + .recv_r6 = lpc54_recvshortcrc, + .recv_r7 = lpc54_recvshort, .waitenable = lpc54_waitenable, .eventwait = lpc54_eventwait, .callbackenable = lpc54_callbackenable, @@ -465,7 +471,7 @@ static uint32_t lpc54_getreg(uint32_t addr) { /* Yes.. then show how many times the value repeated */ - mcinfo("[repeats %d more times]\n", count-3); + mcinfo("[repeats %d more times]\n", count - 3); } /* Save the new address, value, and count */ @@ -635,7 +641,8 @@ static int lpc54_ciu_sendcmd(uint32_t cmd, uint32_t arg) { if (watchtime - clock_systimer() > SDCARD_CMDTIMEOUT) { - mcerr("TMO Timed out (%08X)\n",lpc54_getreg(LPC54_SDMMC_CMD)); + mcerr("TMO Timed out (%08X)\n", + lpc54_getreg(LPC54_SDMMC_CMD)); return 1; } } @@ -730,7 +737,8 @@ static void lpc54_disable_allints(struct lpc54_dev_s *priv) * ****************************************************************************/ -static void lpc54_config_waitints(struct lpc54_dev_s *priv, uint32_t waitmask, +static void lpc54_config_waitints(struct lpc54_dev_s *priv, + uint32_t waitmask, sdio_eventset_t waitevents, sdio_eventset_t wkupevent) { @@ -835,7 +843,8 @@ static void lpc54_eventtimeout(int argc, uint32_t arg) /* There is always race conditions with timer expirations. */ - DEBUGASSERT((priv->waitevents & SDIOWAIT_TIMEOUT) != 0 || priv->wkupevent != 0); + DEBUGASSERT((priv->waitevents & SDIOWAIT_TIMEOUT) != 0 || + priv->wkupevent != 0); /* Is a data transfer complete event expected? */ @@ -866,7 +875,8 @@ static void lpc54_eventtimeout(int argc, uint32_t arg) * ****************************************************************************/ -static void lpc54_endwait(struct lpc54_dev_s *priv, sdio_eventset_t wkupevent) +static void lpc54_endwait(struct lpc54_dev_s *priv, + sdio_eventset_t wkupevent) { mcinfo("wkupevent=%04x\n", (unsigned)wkupevent); @@ -903,7 +913,8 @@ static void lpc54_endwait(struct lpc54_dev_s *priv, sdio_eventset_t wkupevent) * ****************************************************************************/ -static void lpc54_endtransfer(struct lpc54_dev_s *priv, sdio_eventset_t wkupevent) +static void lpc54_endtransfer(struct lpc54_dev_s *priv, + sdio_eventset_t wkupevent) { mcinfo("wkupevent=%04x\n", (unsigned)wkupevent); @@ -972,12 +983,14 @@ static int lpc54_sdmmc_interrupt(int irq, void *context, FAR void *arg) /* Update card status */ cdstatus = priv->cdstatus; - if ((lpc54_getreg(LPC54_SDMMC_CDETECT) & SDMMC_CDETECT_NOTPRESENT) == 0) + if ((lpc54_getreg(LPC54_SDMMC_CDETECT) & + SDMMC_CDETECT_NOTPRESENT) == 0) { priv->cdstatus |= SDIO_STATUS_PRESENT; #ifdef CONFIG_MMCSD_HAVE_WRITEPROTECT - if ((lpc54_getreg(LPC54_SDMMC_WRTPRT) & SDMMC_WRTPRT_PROTECTED) != 0) + if ((lpc54_getreg(LPC54_SDMMC_WRTPRT) & + SDMMC_WRTPRT_PROTECTED) != 0) { priv->cdstatus |= SDIO_STATUS_WRPROTECTED; } @@ -992,11 +1005,11 @@ static int lpc54_sdmmc_interrupt(int irq, void *context, FAR void *arg) lpc54_putreg(SDMMC_PWREN, LPC54_SDMMC_PWREN); #endif - } else { - priv->cdstatus &= ~(SDIO_STATUS_PRESENT | SDIO_STATUS_WRPROTECTED); + priv->cdstatus &= + ~(SDIO_STATUS_PRESENT | SDIO_STATUS_WRPROTECTED); #ifdef CONFIG_LPC54_SDMMC_PWRCTRL /* Disable power to the SD card */ @@ -1061,6 +1074,7 @@ static int lpc54_sdmmc_interrupt(int irq, void *context, FAR void *arg) } /* Check for transfer errors */ + /* Handle data block send/receive CRC failure */ if ((pending & SDMMC_INT_DCRC) != 0) @@ -1069,7 +1083,9 @@ static int lpc54_sdmmc_interrupt(int irq, void *context, FAR void *arg) mcerr("ERROR: Data CRC failure, pending=%08x remaining: %d\n", pending, priv->remaining); - lpc54_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR); + + lpc54_endtransfer(priv, + SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR); } /* Handle data timeout error */ @@ -1080,7 +1096,9 @@ static int lpc54_sdmmc_interrupt(int irq, void *context, FAR void *arg) mcerr("ERROR: Data timeout, pending=%08x remaining: %d\n", pending, priv->remaining); - lpc54_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_TIMEOUT); + + lpc54_endtransfer(priv, + SDIOWAIT_TRANSFERDONE | SDIOWAIT_TIMEOUT); } /* Handle RX FIFO overrun error */ @@ -1091,7 +1109,9 @@ static int lpc54_sdmmc_interrupt(int irq, void *context, FAR void *arg) mcerr("ERROR: RX FIFO overrun, pending=%08x remaining: %d\n", pending, priv->remaining); - lpc54_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR); + + lpc54_endtransfer(priv, + SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR); } /* Handle TX FIFO underrun error */ @@ -1102,7 +1122,9 @@ static int lpc54_sdmmc_interrupt(int irq, void *context, FAR void *arg) mcerr("ERROR: TX FIFO underrun, pending=%08x remaining: %d\n", pending, priv->remaining); - lpc54_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR); + + lpc54_endtransfer(priv, + SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR); } /* Handle start bit error */ @@ -1113,7 +1135,9 @@ static int lpc54_sdmmc_interrupt(int irq, void *context, FAR void *arg) mcerr("ERROR: Start bit, pending=%08x remaining: %d\n", pending, priv->remaining); - lpc54_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR); + + lpc54_endtransfer(priv, + SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR); } /* Handle data end events. Note that RXDR may accompany DTO, DTO @@ -1259,7 +1283,8 @@ static void lpc54_reset(FAR struct sdio_dev_s *dev) SDMMC_CTRL_DMARESET, LPC54_SDMMC_CTRL); while ((lpc54_getreg(LPC54_SDMMC_CTRL) & - (SDMMC_CTRL_CNTLRRESET | SDMMC_CTRL_FIFORESET | SDMMC_CTRL_DMARESET)) != 0) + (SDMMC_CTRL_CNTLRRESET | SDMMC_CTRL_FIFORESET | + SDMMC_CTRL_DMARESET)) != 0) { } @@ -1597,7 +1622,8 @@ static int lpc54_sendcmd(FAR struct sdio_dev_s *dev, uint32_t cmd, if ((cmd & MMCSD_WRDATAXFR) == MMCSD_WRDATAXFR) { - regval |= SDMMC_CMD_DATAXFREXPTD | SDMMC_CMD_WRITE | SDMMC_CMD_WAITPREV; + regval |= SDMMC_CMD_DATAXFREXPTD | SDMMC_CMD_WRITE | + SDMMC_CMD_WAITPREV; } else if ((cmd & MMCSD_RDDATAXFR) == MMCSD_RDDATAXFR) { @@ -1678,12 +1704,13 @@ static void lpc54_blocksetup(FAR struct sdio_dev_s *dev, * Name: lpc54_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, SDCARD_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, + * SDCARD_WAITEVENT will be called to receive the indication that the + * transfer is complete. * * Input Parameters: * dev - An instance of the SD card device interface @@ -1762,8 +1789,8 @@ static int lpc54_recvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, * ****************************************************************************/ -static int lpc54_sendsetup(FAR struct sdio_dev_s *dev, FAR const uint8_t *buffer, - size_t nbytes) +static int lpc54_sendsetup(FAR struct sdio_dev_s *dev, + FAR const uint8_t *buffer, size_t nbytes) { struct lpc54_dev_s *priv = (struct lpc54_dev_s *)dev; #ifdef CONFIG_LPC54_SDMMC_DMA @@ -1816,9 +1843,9 @@ static int lpc54_sendsetup(FAR struct sdio_dev_s *dev, FAR const uint8_t *buffer * * Description: * Cancel the data transfer setup of SDCARD_RECVSETUP, SDCARD_SENDSETUP, - * SDCARD_DMARECVSETUP or SDCARD_DMASENDSETUP. This must be called to cancel - * the data transfer setup if, for some reason, you cannot perform the - * transfer. + * SDCARD_DMARECVSETUP or SDCARD_DMASENDSETUP. This must be called to + * cancel the data transfer setup if, for some reason, you cannot perform + * the transfer. * * Input Parameters: * dev - An instance of the SD card device interface @@ -1917,7 +1944,8 @@ static int lpc54_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd) { if (clock_systimer() - watchtime > timeout) { - mcerr("ERROR: Timeout cmd: %04x events: %04x STA: %08x RINTSTS: %08x\n", + mcerr("ERROR: Timeout cmd: %04x events: %04x STA: %08x " + "RINTSTS: %08x\n", cmd, events, lpc54_getreg(LPC54_SDMMC_STATUS), lpc54_getreg(LPC54_SDMMC_RINTSTS)); @@ -1925,7 +1953,8 @@ static int lpc54_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd) } else if ((lpc54_getreg(LPC54_SDMMC_RINTSTS) & SDCARD_INT_RESPERR) != 0) { - mcerr("ERROR: SDMMC failure cmd: %04x events: %04x STA: %08x RINTSTS: %08x\n", + mcerr("ERROR: SDMMC failure cmd: %04x events: %04x STA: %08x " + "RINTSTS: %08x\n", cmd, events, lpc54_getreg(LPC54_SDMMC_STATUS), lpc54_getreg(LPC54_SDMMC_RINTSTS)); @@ -1938,7 +1967,7 @@ static int lpc54_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd) } /**************************************************************************** - * Name: lpc54_recvRx + * Name: lpc54_recv* * * Description: * Receive response to SD card command. Only the critical payload is @@ -1990,7 +2019,6 @@ static int lpc54_recvshortcrc(FAR struct sdio_dev_s *dev, uint32_t cmd, * 0 1 End bit */ - #ifdef CONFIG_DEBUG_FEATURES if (!rshort) { @@ -2095,7 +2123,8 @@ static int lpc54_recvlong(FAR struct sdio_dev_s *dev, uint32_t cmd, return ret; } -static int lpc54_recvshort(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t *rshort) +static int lpc54_recvshort(FAR struct sdio_dev_s *dev, uint32_t cmd, + uint32_t *rshort) { uint32_t regval; int ret = OK; @@ -2224,9 +2253,9 @@ static void lpc54_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 SDCARD_WAITEVENTS are disabled when lpc54_eventwait - * returns. SDCARD_WAITEVENTS must be called again before lpc54_eventwait - * can be used again. + * all events enabled by SDCARD_WAITEVENTS are disabled when + * lpc54_eventwait returns. SDCARD_WAITEVENTS must be called again + * before lpc54_eventwait can be used again. * * Input Parameters: * dev - An instance of the SD card device interface @@ -2287,24 +2316,25 @@ static sdio_eventset_t lpc54_eventwait(FAR struct sdio_dev_s *dev, } } - /* Loop until the event (or the timeout occurs). Race conditions are avoided - * by calling lpc54_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 lpc54_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. */ lpc54_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 nonzero value. + * evenset will be set to 0 and wkupevent will be set to a nonzero + * value. */ if (wkupevent != 0) @@ -2329,9 +2359,9 @@ errout: * Name: lpc54_callbackenable * * Description: - * Enable/disable of a set of SD card callback events. This is part of the - * the SD card callback sequence. The set of events is configured to enabled - * callbacks to the function provided in lpc54_registercallback. + * Enable/disable of a set of SD card callback events. This is part of + * the the SD card callback sequence. The set of events is configured to + * enabled callbacks to the function provided in lpc54_registercallback. * * Events are automatically disabled once the callback is performed and no * further callback events will occur until they are again enabled by @@ -2419,8 +2449,8 @@ static int lpc54_registercallback(FAR struct sdio_dev_s *dev, ****************************************************************************/ #ifdef CONFIG_LPC54_SDMMC_DMA -static int lpc54_dmarecvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, - size_t buflen) +static int lpc54_dmarecvsetup(FAR struct sdio_dev_s *dev, + FAR uint8_t *buffer, size_t buflen) { struct lpc54_dev_s *priv = (struct lpc54_dev_s *)dev; uint32_t regval; @@ -2461,12 +2491,13 @@ static int lpc54_dmarecvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, regval |= SDMMC_CTRL_FIFORESET | SDMMC_CTRL_DMARESET; lpc54_putreg(regval, LPC54_SDMMC_CTRL); - while ((lpc54_getreg(LPC54_SDMMC_CTRL) & (SDMMC_CTRL_FIFORESET | SDMMC_CTRL_DMARESET)) != 0) + while ((lpc54_getreg(LPC54_SDMMC_CTRL) & (SDMMC_CTRL_FIFORESET | + SDMMC_CTRL_DMARESET)) != 0) { } - /* Configure the FIFO so that we will receive the DMA/FIFO requests whenever - * there more than than (FIFO_DEPTH/2) - 1 words in the FIFO. + /* Configure the FIFO so that we will receive the DMA/FIFO requests + * whenever there more than than (FIFO_DEPTH/2) - 1 words in the FIFO. */ regval = SDMMC_FIFOTH_RXWMARK(LPC54_RXFIFO_DEPTH / 2 - 1) | @@ -2495,7 +2526,8 @@ static int lpc54_dmarecvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, /* Setup buffer address (chained) */ - g_sdmmc_dmadd[i].des2 = (uint32_t)priv->buffer + (i * MCI_DMADES1_MAXTR); + g_sdmmc_dmadd[i].des2 = (uint32_t)priv->buffer + + (i * MCI_DMADES1_MAXTR); /* Setup basic control */ @@ -2611,12 +2643,13 @@ static int lpc54_dmasendsetup(FAR struct sdio_dev_s *dev, regval |= SDMMC_CTRL_FIFORESET | SDMMC_CTRL_DMARESET; lpc54_putreg(regval, LPC54_SDMMC_CTRL); - while ((lpc54_getreg(LPC54_SDMMC_CTRL) & (SDMMC_CTRL_FIFORESET | SDMMC_CTRL_DMARESET)) != 0) + while ((lpc54_getreg(LPC54_SDMMC_CTRL) & (SDMMC_CTRL_FIFORESET | + SDMMC_CTRL_DMARESET)) != 0) { } - /* Configure the FIFO so that we will receive the DMA/FIFO requests whenever - * there are FIFO_DEPTH/2 or fewer words in the FIFO. + /* Configure the FIFO so that we will receive the DMA/FIFO requests + * whenever there are FIFO_DEPTH/2 or fewer words in the FIFO. */ regval = SDMMC_FIFOTH_TXWMARK(LPC54_TXFIFO_DEPTH / 2) | @@ -2645,7 +2678,8 @@ static int lpc54_dmasendsetup(FAR struct sdio_dev_s *dev, /* Setup buffer address (chained) */ - g_sdmmc_dmadd[i].des2 = (uint32_t)priv->buffer + (i * MCI_DMADES1_MAXTR); + g_sdmmc_dmadd[i].des2 = (uint32_t)priv->buffer + + (i * MCI_DMADES1_MAXTR); /* Setup basic control */ @@ -2750,17 +2784,19 @@ static void lpc54_callback(struct lpc54_dev_s *priv) 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); - work_queue(HPWORK, &priv->cbwork, (worker_t)priv->callback, priv->cbarg, 0); + mcinfo("Queuing callback to %p(%p)\n", + priv->callback, priv->cbarg); + work_queue(HPWORK, &priv->cbwork, (worker_t)priv->callback, + priv->cbarg, 0); } else { @@ -2786,7 +2822,8 @@ static void lpc54_callback(struct lpc54_dev_s *priv) * slotno - Not used. * * Returned Value: - * A reference to an SD card interface structure. NULL is returned on failures. + * A reference to an SD card interface structure. NULL is returned on + * failures. * ****************************************************************************/ diff --git a/arch/arm/src/sam34/sam_hsmci.c b/arch/arm/src/sam34/sam_hsmci.c index f6f01c22ede..5324a45ec19 100644 --- a/arch/arm/src/sam34/sam_hsmci.c +++ b/arch/arm/src/sam34/sam_hsmci.c @@ -1,35 +1,20 @@ /**************************************************************************** * arch/arm/src/sam34/sam_hsmci.c * - * Copyright (C) 2010, 2012-2014, 2016-2017 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt + * 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. * ****************************************************************************/ @@ -151,7 +136,8 @@ * HSMCI_INT_UNRE Data transmit underrun * HSMCI_INT_OVRE Data receive overrun * HSMCI_INT_BLKOVRE DMA receive block overrun error - * HSMCI_INT_CSTOE Completion signal time-out error (see HSMCI_CSTOR) + * HSMCI_INT_CSTOE Completion signal time-out error + * (see HSMCI_CSTOR) * HSMCI_INT_DTOE Data time-out error (see HSMCI_DTOR) * HSMCI_INT_DCRCE Data CRC Error * HSMCI_INT_RTOE Response Time-out @@ -168,7 +154,8 @@ /* Response errors: * - * HSMCI_INT_CSTOE Completion signal time-out error (see HSMCI_CSTOR) + * HSMCI_INT_CSTOE Completion signal time-out error + * (see HSMCI_CSTOR) * HSMCI_INT_RTOE Response Time-out * HSMCI_INT_RENDE Response End Bit Error * HSMCI_INT_RCRCE Response CRC Error @@ -192,7 +179,8 @@ * HSMCI_INT_UNRE Data transmit underrun * HSMCI_INT_OVRE Data receive overrun * HSMCI_INT_BLKOVRE DMA receive block overrun error - * HSMCI_INT_CSTOE Completion signal time-out error (see HSMCI_CSTOR) + * HSMCI_INT_CSTOE Completion signal time-out error + * (see HSMCI_CSTOR) * HSMCI_INT_DTOE Data time-out error (see HSMCI_DTOR) * HSMCI_INT_DCRCE Data CRC Error */ @@ -241,11 +229,13 @@ * write sequence is finished. * * 0: A transfer is in progress. - * 1: Command register is ready to operate and the data bus is in the idle state. + * 1: Command register is ready to operate and the data bus is in the idle + * state. * * DMADONE: DMA Transfer done * - * 0: DMA buffer transfer has not completed since the last read of HSMCI_SR register. + * 0: DMA buffer transfer has not completed since the last read of + * HSMCI_SR register. * 1: DMA buffer transfer has completed. */ @@ -269,7 +259,8 @@ * * 0: A command is in progress * 1: The last command has been sent. The CMDRDY flag is released 8 bits - * after the end of the card response. Cleared when writing in the HSMCI_CMDR + * after the end of the card response. Cleared when writing in the + * HSMCI_CMDR */ #define HSMCI_CMDRESP_INTS \ @@ -309,38 +300,40 @@ struct sam_dev_s { - struct sdio_dev_s dev; /* Standard, base SDIO interface */ + struct sdio_dev_s dev; /* Standard, base SDIO interface */ /* SAM3/4-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 */ - uint32_t cmdrmask; /* Interrupt enables for this particular cmd/response */ + 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 */ + uint32_t cmdrmask; /* Interrupt enables for this + * particular cmd/response */ 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 */ #ifdef CONFIG_SAM34_DMAC0 - bool dmabusy; /* TRUE: DMA is in progress */ + bool dmabusy; /* TRUE: DMA is in progress */ #endif /* 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 xfrmask; /* Interrupt enables for data transfer */ + uint32_t xfrmask; /* Interrupt enables for data transfer */ /* DMA data transfer support */ - bool widebus; /* Required for DMA support */ + bool widebus; /* Required for DMA support */ #ifdef CONFIG_SAM34_DMAC0 - DMA_HANDLE dma; /* Handle for DMA channel */ + DMA_HANDLE dma; /* Handle for DMA channel */ #endif }; @@ -377,7 +370,9 @@ struct sam_hsmciregs_s uint32_t pdc_rncr; /* Receive Next Counter Register */ uint32_t pdc_tnpr; /* Transmit Next Pointer Register */ uint32_t pdc_tncr; /* Transmit Next Counter Register */ -//uint32_t pdc_ptcr; /* Transfer Control Register */ +#if 0 + uint32_t pdc_ptcr; /* Transfer Control Register */ +#endif uint32_t pdc_ptsr; /* Transfer Status Register */ #endif }; @@ -404,8 +399,10 @@ static void sam_takesem(struct sam_dev_s *priv); static void sam_configwaitints(struct sam_dev_s *priv, uint32_t waitmask, sdio_eventset_t waitevents); -static void sam_disablewaitints(struct sam_dev_s *priv, sdio_eventset_t wkupevents); -static inline void sam_configxfrints(struct sam_dev_s *priv, uint32_t xfrmask); +static void sam_disablewaitints(struct sam_dev_s *priv, + sdio_eventset_t wkupevents); +static inline void sam_configxfrints(struct sam_dev_s *priv, + uint32_t xfrmask); static void sam_disablexfrints(struct sam_dev_s *priv); static void sam_enableints(struct sam_dev_s *priv); @@ -453,7 +450,8 @@ static void sam_dmacallback(DMA_HANDLE handle, void *arg, int result); static void sam_eventtimeout(int argc, uint32_t arg); static void sam_endwait(struct sam_dev_s *priv, sdio_eventset_t wkupevent); -static void sam_endtransfer(struct sam_dev_s *priv, sdio_eventset_t wkupevent); +static void sam_endtransfer(struct sam_dev_s *priv, + sdio_eventset_t wkupevent); static void sam_notransfer(struct sam_dev_s *priv); /* Interrupt Handling *******************************************************/ @@ -531,13 +529,13 @@ struct sam_dev_s g_sdiodev = .sendsetup = sam_dmasendsetup, .cancel = sam_cancel, .waitresponse = sam_waitresponse, - .recvR1 = sam_recvshort, - .recvR2 = sam_recvlong, - .recvR3 = sam_recvshort, - .recvR4 = sam_recvnotimpl, - .recvR5 = sam_recvnotimpl, - .recvR6 = sam_recvshort, - .recvR7 = sam_recvshort, + .recv_r1 = sam_recvshort, + .recv_r2 = sam_recvlong, + .recv_r3 = sam_recvshort, + .recv_r4 = sam_recvnotimpl, + .recv_r5 = sam_recvnotimpl, + .recv_r6 = sam_recvshort, + .recv_r7 = sam_recvshort, .waitenable = sam_waitenable, .eventwait = sam_eventwait, .callbackenable = sam_callbackenable, @@ -566,9 +564,6 @@ static bool g_cmdinitialized; * Private Functions ****************************************************************************/ -/**************************************************************************** - * Low-level Helpers - ****************************************************************************/ /**************************************************************************** * Name: sam_takesem * @@ -672,7 +667,8 @@ static void sam_disablewaitints(struct sam_dev_s *priv, * ****************************************************************************/ -static inline void sam_configxfrints(struct sam_dev_s *priv, uint32_t xfrmask) +static inline void sam_configxfrints(struct sam_dev_s *priv, + uint32_t xfrmask) { priv->xfrmask = xfrmask; } @@ -764,10 +760,6 @@ static inline void sam_enable(void) putreg32(HSMCI_CR_MCIEN, SAM_HSMCI_CR); } -/**************************************************************************** - * Register Sampling - ****************************************************************************/ - /**************************************************************************** * Name: sam_hsmcisample * @@ -807,7 +799,9 @@ static void sam_hsmcisample(struct sam_hsmciregs_s *regs) regs->pdc_rncr = getreg32(SAM_HSMCI_PDC_RNCR); regs->pdc_tnpr = getreg32(SAM_HSMCI_PDC_TNPR); regs->pdc_tncr = getreg32(SAM_HSMCI_PDC_TNCR); -//regs->pdc_ptcr = getreg32(SAM_HSMCI_PDC_PTCR); +#if 0 + regs->pdc_ptcr = getreg32(SAM_HSMCI_PDC_PTCR); +#endif regs->pdc_ptsr = getreg32(SAM_HSMCI_PDC_PTSR); #endif } @@ -825,37 +819,65 @@ static void sam_hsmcisample(struct sam_hsmciregs_s *regs) static void sam_hsmcidump(struct sam_hsmciregs_s *regs, const char *msg) { mcinfo("HSMCI Registers: %s\n", msg); - mcinfo(" MR[%08x]: %08x\n", SAM_HSMCI_MR, regs->mr); - mcinfo(" DTOR[%08x]: %08x\n", SAM_HSMCI_DTOR, regs->dtor); - mcinfo(" SDCR[%08x]: %08x\n", SAM_HSMCI_SDCR, regs->sdcr); - mcinfo(" ARGR[%08x]: %08x\n", SAM_HSMCI_ARGR, regs->argr); - mcinfo(" BLKR[%08x]: %08x\n", SAM_HSMCI_BLKR, regs->blkr); - mcinfo(" CSTOR[%08x]: %08x\n", SAM_HSMCI_CSTOR, regs->cstor); - mcinfo(" RSPR0[%08x]: %08x\n", SAM_HSMCI_RSPR0, regs->rsp0); - mcinfo(" RSPR1[%08x]: %08x\n", SAM_HSMCI_RSPR1, regs->rsp1); - mcinfo(" RSPR2[%08x]: %08x\n", SAM_HSMCI_RSPR2, regs->rsp2); - mcinfo(" RSPR3[%08x]: %08x\n", SAM_HSMCI_RSPR3, regs->rsp3); - mcinfo(" SR[%08x]: %08x\n", SAM_HSMCI_SR, regs->sr); - mcinfo(" IMR[%08x]: %08x\n", SAM_HSMCI_IMR, regs->imr); + mcinfo(" MR[%08x]: %08x\n", + SAM_HSMCI_MR, regs->mr); + mcinfo(" DTOR[%08x]: %08x\n", + SAM_HSMCI_DTOR, regs->dtor); + mcinfo(" SDCR[%08x]: %08x\n", + SAM_HSMCI_SDCR, regs->sdcr); + mcinfo(" ARGR[%08x]: %08x\n", + SAM_HSMCI_ARGR, regs->argr); + mcinfo(" BLKR[%08x]: %08x\n", + SAM_HSMCI_BLKR, regs->blkr); + mcinfo(" CSTOR[%08x]: %08x\n", + SAM_HSMCI_CSTOR, regs->cstor); + mcinfo(" RSPR0[%08x]: %08x\n", + SAM_HSMCI_RSPR0, regs->rsp0); + mcinfo(" RSPR1[%08x]: %08x\n", + SAM_HSMCI_RSPR1, regs->rsp1); + mcinfo(" RSPR2[%08x]: %08x\n", + SAM_HSMCI_RSPR2, regs->rsp2); + mcinfo(" RSPR3[%08x]: %08x\n", + SAM_HSMCI_RSPR3, regs->rsp3); + mcinfo(" SR[%08x]: %08x\n", + SAM_HSMCI_SR, regs->sr); + mcinfo(" IMR[%08x]: %08x\n", + SAM_HSMCI_IMR, regs->imr); #if defined(CONFIG_ARCH_CHIP_SAM3U) - mcinfo(" DMA[%08x]: %08x\n", SAM_HSMCI_DMA, regs->dma); + mcinfo(" DMA[%08x]: %08x\n", + SAM_HSMCI_DMA, regs->dma); #endif - mcinfo(" CFG[%08x]: %08x\n", SAM_HSMCI_CFG, regs->cfg); - mcinfo(" WPMR[%08x]: %08x\n", SAM_HSMCI_WPMR, regs->wpmr); - mcinfo(" WPSR[%08x]: %08x\n", SAM_HSMCI_WPSR, regs->wpsr); + mcinfo(" CFG[%08x]: %08x\n", + SAM_HSMCI_CFG, regs->cfg); + mcinfo(" WPMR[%08x]: %08x\n", + SAM_HSMCI_WPMR, regs->wpmr); + mcinfo(" WPSR[%08x]: %08x\n", + SAM_HSMCI_WPSR, regs->wpsr); #ifdef CONFIG_SAM34_PDCA mcinfo("HSMCI PDC Registers:\n"); - mcinfo(" RPR[%08x]: %08x\n", SAM_HSMCI_PDC_RPR, regs->pdc_rpr); - mcinfo(" RCR[%08x]: %08x\n", SAM_HSMCI_PDC_RCR, regs->pdc_rcr); - mcinfo(" TPR[%08x]: %08x\n", SAM_HSMCI_PDC_TPR, regs->pdc_tpr); - mcinfo(" TCR[%08x]: %08x\n", SAM_HSMCI_PDC_TCR, regs->pdc_tcr); - mcinfo(" RNPR[%08x]: %08x\n", SAM_HSMCI_PDC_RNPR, regs->pdc_rnpr); - mcinfo(" RNCR[%08x]: %08x\n", SAM_HSMCI_PDC_RNCR, regs->pdc_rncr); - mcinfo(" TNPR[%08x]: %08x\n", SAM_HSMCI_PDC_TNPR, regs->pdc_tnpr); - mcinfo(" TNCR[%08x]: %08x\n", SAM_HSMCI_PDC_TNCR, regs->pdc_tncr); -//mcinfo(" TCR[%08x]: %08x\n", SAM_HSMCI_PDC_PTCR, regs->pdc_ptcr); - mcinfo(" PTSR[%08x]: %08x\n", SAM_HSMCI_PDC_PTSR, regs->pdc_ptsr); + mcinfo(" RPR[%08x]: %08x\n", + SAM_HSMCI_PDC_RPR, regs->pdc_rpr); + mcinfo(" RCR[%08x]: %08x\n", + SAM_HSMCI_PDC_RCR, regs->pdc_rcr); + mcinfo(" TPR[%08x]: %08x\n", + SAM_HSMCI_PDC_TPR, regs->pdc_tpr); + mcinfo(" TCR[%08x]: %08x\n", + SAM_HSMCI_PDC_TCR, regs->pdc_tcr); + mcinfo(" RNPR[%08x]: %08x\n", + SAM_HSMCI_PDC_RNPR, regs->pdc_rnpr); + mcinfo(" RNCR[%08x]: %08x\n", + SAM_HSMCI_PDC_RNCR, regs->pdc_rncr); + mcinfo(" TNPR[%08x]: %08x\n", + SAM_HSMCI_PDC_TNPR, regs->pdc_tnpr); + mcinfo(" TNCR[%08x]: %08x\n", + SAM_HSMCI_PDC_TNCR, regs->pdc_tncr); +#if 0 + mcinfo(" TCR[%08x]: %08x\n", + SAM_HSMCI_PDC_PTCR, regs->pdc_ptcr); +#endif + mcinfo(" PTSR[%08x]: %08x\n", + SAM_HSMCI_PDC_PTSR, regs->pdc_ptsr); #endif } #endif @@ -890,7 +912,9 @@ static void sam_xfrsample(struct sam_dev_s *priv, int index) #ifdef CONFIG_SAM34_HSMCI_XFRDEBUG static void sam_xfrsampleinit(void) { - memset(g_xfrsamples, 0xff, DEBUG_NDMASAMPLES * sizeof(struct sam_xfrregs_s)); + memset(g_xfrsamples, 0xff, + DEBUG_NDMASAMPLES * sizeof(struct sam_xfrregs_s)); + #ifdef CONFIG_SAM34_HSMCI_CMDDEBUG g_xfrinitialized = true; #endif @@ -931,14 +955,19 @@ static void sam_xfrdump(struct sam_dev_s *priv) if (g_xfrinitialized) #endif { - sam_xfrdumpone(priv, &g_xfrsamples[SAMPLENDX_BEFORE_SETUP], "Before setup"); + sam_xfrdumpone(priv, &g_xfrsamples[SAMPLENDX_BEFORE_SETUP], + "Before setup"); #ifdef CONFIG_DEBUG_DMA - sam_xfrdumpone(priv, &g_xfrsamples[SAMPLENDX_BEFORE_ENABLE], "Before DMA enable"); + sam_xfrdumpone(priv, &g_xfrsamples[SAMPLENDX_BEFORE_ENABLE], + "Before DMA enable"); #endif - sam_xfrdumpone(priv, &g_xfrsamples[SAMPLENDX_AFTER_SETUP], "After setup"); - sam_xfrdumpone(priv, &g_xfrsamples[SAMPLENDX_END_TRANSFER], "End of transfer"); + sam_xfrdumpone(priv, &g_xfrsamples[SAMPLENDX_AFTER_SETUP], + "After setup"); + sam_xfrdumpone(priv, &g_xfrsamples[SAMPLENDX_END_TRANSFER], + "End of transfer"); #if defined(CONFIG_DEBUG_DMA) && defined(CONFIG_SAM34_DMAC0) - sam_xfrdumpone(priv, &g_xfrsamples[SAMPLENDX_DMA_CALLBACK], "DMA Callback"); + sam_xfrdumpone(priv, &g_xfrsamples[SAMPLENDX_DMA_CALLBACK], + "DMA Callback"); #endif #ifdef CONFIG_SAM34_HSMCI_CMDDEBUG g_xfrinitialized = false; @@ -958,7 +987,9 @@ static void sam_xfrdump(struct sam_dev_s *priv) #ifdef CONFIG_SAM34_HSMCI_CMDDEBUG static void sam_cmdsampleinit(void) { - memset(g_cmdsamples, 0xff, DEBUG_NCMDSAMPLES * sizeof(struct sam_hsmciregs_s)); + memset(g_cmdsamples, 0xff, + DEBUG_NCMDSAMPLES * sizeof(struct sam_hsmciregs_s)); + #ifdef CONFIG_SAM34_HSMCI_XFRDEBUG g_cmdinitialized = true; #endif @@ -1001,8 +1032,10 @@ static void sam_cmddump(void) if (g_cmdinitialized) #endif { - sam_hsmcidump(&g_cmdsamples[SAMPLENDX_AFTER_CMDR], "After command setup"); - sam_hsmcidump(&g_cmdsamples[SAMPLENDX_AT_WAKEUP], "After wakeup"); + sam_hsmcidump(&g_cmdsamples[SAMPLENDX_AFTER_CMDR], + "After command setup"); + sam_hsmcidump(&g_cmdsamples[SAMPLENDX_AT_WAKEUP], + "After wakeup"); #ifdef CONFIG_SAM34_HSMCI_XFRDEBUG g_cmdinitialized = false; #endif @@ -1010,10 +1043,6 @@ static void sam_cmddump(void) } #endif -/**************************************************************************** - * DMA Helpers - ****************************************************************************/ - /**************************************************************************** * Name: sam_dmacallback * @@ -1039,10 +1068,6 @@ static void sam_dmacallback(DMA_HANDLE handle, void *arg, int result) } #endif -/**************************************************************************** - * Data Transfer Helpers - ****************************************************************************/ - /**************************************************************************** * Name: sam_eventtimeout * @@ -1215,10 +1240,6 @@ static void sam_notransfer(struct sam_dev_s *priv) #endif } -/**************************************************************************** - * Interrupt Handling - ****************************************************************************/ - /**************************************************************************** * Name: sam_interrupt * @@ -1260,6 +1281,7 @@ static int sam_interrupt(int irq, void *context, FAR void *arg) } /* Handle in progress, interrupt driven data transfers ****************/ + /* Do any of these interrupts signal the end a data transfer? */ pending = enabled & priv->xfrmask; @@ -1271,18 +1293,22 @@ static int sam_interrupt(int irq, void *context, FAR void *arg) { /* Yes.. Was it some kind of timeout error? */ - mcerr("ERROR: enabled: %08x pending: %08x\n", enabled, pending); + mcerr("ERROR: enabled: %08x pending: %08x\n", + enabled, pending); + if ((pending & HSMCI_DATA_TIMEOUT_ERRORS) != 0) { /* Yes.. Terminate with a timeout. */ - sam_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_TIMEOUT); + sam_endtransfer(priv, + SDIOWAIT_TRANSFERDONE | SDIOWAIT_TIMEOUT); } else { /* No.. Terminate with an I/O error. */ - sam_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR); + sam_endtransfer(priv, + SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR); } } else @@ -1294,6 +1320,7 @@ static int sam_interrupt(int irq, void *context, FAR void *arg) } /* Handle wait events *************************************************/ + /* Do any of these interrupts signal wakeup event? */ pending = enabled & priv->waitmask; @@ -1354,9 +1381,6 @@ static int sam_interrupt(int irq, void *context, FAR void *arg) return OK; } -/**************************************************************************** - * SDIO Interface Methods - ****************************************************************************/ /**************************************************************************** * Name: sam_reset * @@ -1627,9 +1651,8 @@ static int sam_attach(FAR struct sdio_dev_s *dev) ret = irq_attach(SAM_IRQ_HSMCI, sam_interrupt, NULL); if (ret == OK) { - - /* Disable all interrupts at the HSMCI controller and clear (most) static - * interrupt flags by reading the status register. + /* Disable all interrupts at the HSMCI controller and clear (most) + * static interrupt flags by reading the status register. */ putreg32(0xffffffff, SAM_HSMCI_IDR); @@ -1698,12 +1721,12 @@ static int sam_sendcmd(FAR struct sdio_dev_s *dev, case MMCSD_R5_RESPONSE: case MMCSD_R6_RESPONSE: priv->cmdrmask = HSMCI_CMDRESP_INTS; - regval |= (HSMCI_CMDR_RSPTYP_48BIT | HSMCI_CMDR_MAXLAT); + regval |= HSMCI_CMDR_RSPTYP_48BIT | HSMCI_CMDR_MAXLAT; break; case MMCSD_R1B_RESPONSE: priv->cmdrmask = HSMCI_CMDRESP_INTS; - regval |= (HSMCI_CMDR_RSPTYP_R1B | HSMCI_CMDR_MAXLAT); + regval |= HSMCI_CMDR_RSPTYP_R1B | HSMCI_CMDR_MAXLAT; break; /* 48-bit response without CRC */ @@ -1711,14 +1734,14 @@ static int sam_sendcmd(FAR struct sdio_dev_s *dev, case MMCSD_R3_RESPONSE: case MMCSD_R7_RESPONSE: priv->cmdrmask = HSMCI_CMDRESP_NOCRC_INTS; - regval |= (HSMCI_CMDR_RSPTYP_48BIT | HSMCI_CMDR_MAXLAT); + regval |= HSMCI_CMDR_RSPTYP_48BIT | HSMCI_CMDR_MAXLAT; break; /* 136-bit response with CRC */ case MMCSD_R2_RESPONSE: priv->cmdrmask = HSMCI_CMDRESP_INTS; - regval |= (HSMCI_CMDR_RSPTYP_136BIT | HSMCI_CMDR_MAXLAT); + regval |= HSMCI_CMDR_RSPTYP_136BIT | HSMCI_CMDR_MAXLAT; break; } @@ -1728,22 +1751,26 @@ static int sam_sendcmd(FAR struct sdio_dev_s *dev, { #if 0 /* No MMC support */ case MMCSD_RDSTREAM: /* MMC Read stream */ - regval |= (HSMCI_CMDR_TRCMD_START | HSMCI_CMDR_TRTYP_STREAM | HSMCI_CMDR_TRDIR_READ); + regval |= HSMCI_CMDR_TRCMD_START | HSMCI_CMDR_TRTYP_STREAM | + HSMCI_CMDR_TRDIR_READ; break; case MMCSD_WRSTREAM: /* MMC Write stream */ - regval |= (HSMCI_CMDR_TRCMD_START | HSMCI_CMDR_TRTYP_STREAM | HSMCI_CMDR_TRDIR_WRITE); + regval |= HSMCI_CMDR_TRCMD_START | HSMCI_CMDR_TRTYP_STREAM | + HSMCI_CMDR_TRDIR_WRITE; break; #endif case MMCSD_RDDATAXFR: /* Read block transfer */ - regval |= (HSMCI_CMDR_TRCMD_START | HSMCI_CMDR_TRDIR_READ); - regval |= (cmd & MMCSD_MULTIBLOCK) ? HSMCI_CMDR_TRTYP_MULTI : HSMCI_CMDR_TRTYP_SINGLE; + regval |= HSMCI_CMDR_TRCMD_START | HSMCI_CMDR_TRDIR_READ; + regval |= (cmd & MMCSD_MULTIBLOCK) ? + HSMCI_CMDR_TRTYP_MULTI : HSMCI_CMDR_TRTYP_SINGLE; break; case MMCSD_WRDATAXFR: /* Write block transfer */ - regval |= (HSMCI_CMDR_TRCMD_START | HSMCI_CMDR_TRDIR_WRITE); - regval |= (cmd & MMCSD_MULTIBLOCK) ? HSMCI_CMDR_TRTYP_MULTI : HSMCI_CMDR_TRTYP_SINGLE; + regval |= HSMCI_CMDR_TRCMD_START | HSMCI_CMDR_TRDIR_WRITE; + regval |= (cmd & MMCSD_MULTIBLOCK) ? + HSMCI_CMDR_TRTYP_MULTI : HSMCI_CMDR_TRTYP_SINGLE; break; case MMCSD_NODATAXFR: @@ -1792,7 +1819,8 @@ static void sam_blocksetup(FAR struct sdio_dev_s *dev, unsigned int blocklen, { uint32_t regval; - DEBUGASSERT(dev != NULL && nblocks > 0 && nblocks < 65535 && blocklen < 65535); + DEBUGASSERT(dev != NULL && nblocks > 0 && nblocks < 65535 && + blocklen < 65535); /* When TRTYP - Single or Multi, blocklen must be 1-511, 0-512 */ @@ -1946,13 +1974,14 @@ static int sam_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd) /* Yes.. Was the error some kind of timeout? */ mcerr("ERROR: cmd: %08x events: %08x SR: %08x\n", - cmd, priv->cmdrmask, sr); + cmd, priv->cmdrmask, sr); if ((pending & HSMCI_RESPONSE_TIMEOUT_ERRORS) != 0) { /* Yes.. return a timeout error */ - priv->wkupevent = SDIOWAIT_CMDDONE | SDIOWAIT_RESPONSEDONE | + priv->wkupevent = SDIOWAIT_CMDDONE | + SDIOWAIT_RESPONSEDONE | SDIOWAIT_TIMEOUT; return -ETIMEDOUT; } @@ -1960,7 +1989,8 @@ static int sam_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd) { /* No.. return some generic I/O error */ - priv->wkupevent = SDIOWAIT_CMDDONE | SDIOWAIT_RESPONSEDONE | + priv->wkupevent = SDIOWAIT_CMDDONE | + SDIOWAIT_RESPONSEDONE | SDIOWAIT_ERROR; return -EIO; } @@ -1985,7 +2015,7 @@ static int sam_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd) } /**************************************************************************** - * Name: sam_recvRx + * Name: sam_recv* * * Description: * Receive response to SDIO command. Only the critical payload is @@ -2093,7 +2123,8 @@ static int sam_recvshort(FAR struct sdio_dev_s *dev, return ret; } -static int sam_recvlong(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t rlong[4]) +static int sam_recvlong(FAR struct sdio_dev_s *dev, uint32_t cmd, + uint32_t rlong[4]) { struct sam_dev_s *priv = (struct sam_dev_s *)dev; int ret = OK; @@ -2174,8 +2205,8 @@ static int sam_recvnotimpl(FAR struct sdio_dev_s *dev, * SDIO_WAITEVENT: Wait for the event of interest (which might * already have occurred) * - * This sequency should eliminate race conditions between the command/trasnfer - * 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 @@ -2298,26 +2329,26 @@ static sdio_eventset_t sam_eventwait(FAR struct sdio_dev_s *dev, } } - /* Loop until the event (or the timeout occurs). Race conditions are avoided - * by calling sam_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 sam_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. */ sam_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 nonzero value. - * When wkupevent becomes non-zero, further interrupts will have already - * been disabled. + * evenset will be set to 0 and wkupevent will be set to a nonzero + * value. When wkupevent becomes non-zero, further interrupts will + * have already been disabled. */ if (wkupevent != 0) @@ -2466,7 +2497,7 @@ static int sam_dmarecvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, mcinfo("SAM_HSMCI_MR = 0x%08X\n", getreg32(SAM_HSMCI_MR)); putreg32((uint32_t)buffer, SAM_HSMCI_PDC_RPR); - putreg32(buflen/4, SAM_HSMCI_PDC_RCR); + putreg32(buflen / 4, SAM_HSMCI_PDC_RCR); putreg32(PDC_PTCR_RXTEN, SAM_HSMCI_PDC_PTCR); sam_xfrsample(priv, SAMPLENDX_BEFORE_ENABLE); #endif @@ -2536,7 +2567,7 @@ static int sam_dmasendsetup(FAR struct sdio_dev_s *dev, mcinfo("SAM_HSMCI_MR = 0x%08X\n", getreg32(SAM_HSMCI_MR)); putreg32((uint32_t)buffer, SAM_HSMCI_PDC_TPR); - putreg32(buflen/4, SAM_HSMCI_PDC_TCR); + putreg32(buflen / 4, SAM_HSMCI_PDC_TCR); putreg32(PDC_PTCR_TXTEN, SAM_HSMCI_PDC_PTCR); sam_xfrsample(priv, SAMPLENDX_BEFORE_ENABLE); #endif @@ -2551,9 +2582,6 @@ static int sam_dmasendsetup(FAR struct sdio_dev_s *dev, return OK; } -/**************************************************************************** - * Initialization/uninitialization/reset - ****************************************************************************/ /**************************************************************************** * Name: sam_callback * @@ -2610,17 +2638,20 @@ static void sam_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); - work_queue(LPWORK, &priv->cbwork, (worker_t)priv->callback, priv->cbarg, 0); + mcinfo("Queuing callback to %p(%p)\n", + priv->callback, priv->cbarg); + + work_queue(LPWORK, &priv->cbwork, + (worker_t)priv->callback, priv->cbarg, 0); } else { @@ -2646,7 +2677,8 @@ static void sam_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. * ****************************************************************************/ @@ -2659,6 +2691,7 @@ FAR struct sdio_dev_s *sdio_initialize(int slotno) mcinfo("slotno: %d\n", slotno); /* Initialize the HSMCI slot structure */ + /* Initialize semaphores */ nxsem_init(&priv->waitsem, 0, 0); @@ -2681,9 +2714,9 @@ FAR struct sdio_dev_s *sdio_initialize(int slotno) DEBUGASSERT(priv->dma); #endif - /* Configure GPIOs for 4-bit, wide-bus operation. NOTE: (1) the chip is capable of - * 8-bit wide bus operation but D4-D7 are not configured, (2) any card detection - * GPIOs must be set up in board-specific logic. + /* Configure GPIOs for 4-bit, wide-bus operation. NOTE: (1) the chip is + * capable of 8-bit wide bus operation but D4-D7 are not configured, (2) + * any card detection GPIOs must be set up in board-specific logic. */ sam_configgpio(GPIO_HSMCI_DAT0); /* Data 0 of Slot A */ diff --git a/arch/arm/src/sama5/sam_hsmci.c b/arch/arm/src/sama5/sam_hsmci.c index 2cb84ce1355..a226b18ddc8 100644 --- a/arch/arm/src/sama5/sam_hsmci.c +++ b/arch/arm/src/sama5/sam_hsmci.c @@ -1,35 +1,20 @@ /**************************************************************************** * arch/arm/src/sama5/sam_hsmci.c * - * Copyright (C) 2013-2014, 2016-2017 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt + * 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. * ****************************************************************************/ @@ -228,7 +213,8 @@ * HSMCI_INT_UNRE Data transmit underrun * HSMCI_INT_OVRE Data receive overrun * HSMCI_INT_BLKOVRE DMA receive block overrun error - * HSMCI_INT_CSTOE Completion signal time-out error (see HSMCI_CSTOR) + * HSMCI_INT_CSTOE Completion signal time-out error + * (see HSMCI_CSTOR) * HSMCI_INT_DTOE Data time-out error (see HSMCI_DTOR) * HSMCI_INT_DCRCE Data CRC Error * HSMCI_INT_RTOE Response Time-out @@ -245,7 +231,8 @@ /* Response errors: * - * HSMCI_INT_CSTOE Completion signal time-out error (see HSMCI_CSTOR) + * HSMCI_INT_CSTOE Completion signal time-out error + * (see HSMCI_CSTOR) * HSMCI_INT_RTOE Response Time-out * HSMCI_INT_RENDE Response End Bit Error * HSMCI_INT_RCRCE Response CRC Error @@ -267,7 +254,8 @@ * HSMCI_INT_UNRE Data transmit underrun * HSMCI_INT_OVRE Data receive overrun * HSMCI_INT_BLKOVRE DMA receive block overrun error - * HSMCI_INT_CSTOE Completion signal time-out error (see HSMCI_CSTOR) + * HSMCI_INT_CSTOE Completion signal time-out error + * (see HSMCI_CSTOR) * HSMCI_INT_DTOE Data time-out error (see HSMCI_DTOR) * HSMCI_INT_DCRCE Data CRC Error */ @@ -292,11 +280,13 @@ * write sequence is finished. * * 0: A transfer is in progress. - * 1: Command register is ready to operate and the data bus is in the idle state. + * 1: Command register is ready to operate and the data bus is in the idle + * state. * * DMADONE: DMA Transfer done * - * 0: DMA buffer transfer has not completed since the last read of HSMCI_SR register. + * 0: DMA buffer transfer has not completed since the last read of + * HSMCI_SR register. * 1: DMA buffer transfer has completed. */ @@ -313,7 +303,8 @@ * * 0: A command is in progress * 1: The last command has been sent. The CMDRDY flag is released 8 bits - * after the end of the card response. Cleared when writing in the HSMCI_CMDR + * after the end of the card response. Cleared when writing in the + * HSMCI_CMDR */ #define HSMCI_CMDRESP_INTS \ @@ -355,6 +346,7 @@ /**************************************************************************** * Private Types ****************************************************************************/ + /* Register logging support */ #if defined(CONFIG_SAMA5_HSMCI_XFRDEBUG) || defined(CONFIG_SAMA5_HSMCI_CMDDEBUG) @@ -393,52 +385,56 @@ struct sam_xfrregs_s struct sam_dev_s { - struct sdio_dev_s dev; /* Standard, base SDIO interface */ + struct sdio_dev_s dev; /* Standard, base SDIO interface */ /* SAMA5-specific extensions */ + /* Event support */ - sem_t waitsem; /* Implements event waiting */ - sdio_eventset_t waitevents; /* Set of events to be waited for */ - uint32_t base; /* HSMCI register base address */ - uint32_t waitmask; /* Interrupt enables for event waiting */ - uint32_t cmdrmask; /* Interrupt enables for this particular cmd/response */ + sem_t waitsem; /* Implements event waiting */ + sdio_eventset_t waitevents; /* Set of events to be waited for */ + uint32_t base; /* HSMCI register base address */ + uint32_t waitmask; /* Interrupt enables for event waiting */ + uint32_t cmdrmask; /* Interrupt enables for this + * particular cmd/response */ volatile sdio_eventset_t wkupevent; /* The event that caused the wakeup */ - WDOG_ID waitwdog; /* Watchdog that handles event timeouts */ - uint8_t hsmci; /* HSMCI (0, 1, or 2) */ - volatile bool dmabusy; /* TRUE: DMA transfer is in progress */ - volatile bool xfrbusy; /* TRUE: Transfer is in progress */ - volatile bool txbusy; /* TRUE: TX transfer is in progress (for delay calculation) */ + WDOG_ID waitwdog; /* Watchdog that handles event timeouts */ + uint8_t hsmci; /* HSMCI (0, 1, or 2) */ + volatile bool dmabusy; /* TRUE: DMA transfer is in progress */ + volatile bool xfrbusy; /* TRUE: Transfer is in progress */ + volatile bool txbusy; /* TRUE: TX transfer is in progress + * (for delay calculation) */ /* 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 xfrmask; /* Interrupt enables for data transfer */ + uint32_t xfrmask; /* Interrupt enables for data transfer */ /* Interrupt mode data transfer support */ - uint32_t *buffer; /* Address of current R/W buffer */ - ssize_t remaining; /* Number of bytes remaining in the transfer */ + uint32_t *buffer; /* Address of current R/W buffer */ + ssize_t remaining; /* Number of bytes remaining in the + * transfer */ /* DMA data transfer support */ - bool widebus; /* Required for DMA support */ - DMA_HANDLE dma; /* Handle for DMA channel */ + bool widebus; /* Required for DMA support */ + DMA_HANDLE dma; /* Handle for DMA channel */ /* Debug stuff */ #ifdef CONFIG_SAMA5_HSMCI_REGDEBUG - bool wrlast; /* Last was a write */ - uint32_t addrlast; /* Last address */ - uint32_t vallast; /* Last value */ - int ntimes; /* Number of times */ + bool wrlast; /* Last was a write */ + uint32_t addrlast; /* Last address */ + uint32_t vallast; /* Last value */ + int ntimes; /* Number of times */ #endif /* Register logging support */ @@ -477,10 +473,12 @@ static inline uint32_t sam_getreg(struct sam_dev_s *priv, static inline void sam_putreg(struct sam_dev_s *priv, uint32_t value, unsigned int offset); -static inline void sam_configwaitints(struct sam_dev_s *priv, uint32_t waitmask, - sdio_eventset_t waitevents); -static void sam_disablewaitints(struct sam_dev_s *priv, sdio_eventset_t wkupevent); -static inline void sam_configxfrints(struct sam_dev_s *priv, uint32_t xfrmask); +static inline void sam_configwaitints(struct sam_dev_s *priv, + uint32_t waitmask, sdio_eventset_t waitevents); +static void sam_disablewaitints(struct sam_dev_s *priv, + sdio_eventset_t wkupevent); +static inline void sam_configxfrints(struct sam_dev_s *priv, + uint32_t xfrmask); static void sam_disablexfrints(struct sam_dev_s *priv); static inline void sam_enableints(struct sam_dev_s *priv); @@ -531,7 +529,8 @@ static inline uintptr_t hsmci_physregaddr(struct sam_dev_s *priv, static void sam_eventtimeout(int argc, uint32_t arg); static void sam_endwait(struct sam_dev_s *priv, sdio_eventset_t wkupevent); -static void sam_endtransfer(struct sam_dev_s *priv, sdio_eventset_t wkupevent); +static void sam_endtransfer(struct sam_dev_s *priv, + sdio_eventset_t wkupevent); static void sam_notransfer(struct sam_dev_s *priv); /* Interrupt Handling *******************************************************/ @@ -558,8 +557,8 @@ static void sam_blocksetup(FAR struct sdio_dev_s *dev, unsigned int blocklen, unsigned int nblocks); static int sam_recvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, size_t nbytes); -static int sam_sendsetup(FAR struct sdio_dev_s *dev, FAR const uint8_t *buffer, - size_t nbytes); +static int sam_sendsetup(FAR struct sdio_dev_s *dev, + FAR const uint8_t *buffer, size_t nbytes); static int sam_cancel(FAR struct sdio_dev_s *dev); static int sam_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd); static int sam_recvshort(FAR struct sdio_dev_s *dev, uint32_t cmd, @@ -600,6 +599,7 @@ static void sam_callback(void *arg); /**************************************************************************** * Private Data ****************************************************************************/ + /* Callbacks */ static const struct sdio_dev_s g_callbacks = @@ -616,13 +616,13 @@ static const struct sdio_dev_s g_callbacks = .sendsetup = sam_sendsetup, .cancel = sam_cancel, .waitresponse = sam_waitresponse, - .recvR1 = sam_recvshort, - .recvR2 = sam_recvlong, - .recvR3 = sam_recvshort, - .recvR4 = sam_recvnotimpl, - .recvR5 = sam_recvnotimpl, - .recvR6 = sam_recvshort, - .recvR7 = sam_recvshort, + .recv_r1 = sam_recvshort, + .recv_r2 = sam_recvlong, + .recv_r3 = sam_recvshort, + .recv_r4 = sam_recvnotimpl, + .recv_r5 = sam_recvnotimpl, + .recv_r6 = sam_recvshort, + .recv_r7 = sam_recvshort, .waitenable = sam_waitenable, .eventwait = sam_eventwait, .callbackenable = sam_callbackenable, @@ -657,9 +657,6 @@ static struct sam_dev_s g_hsmci2; * Private Functions ****************************************************************************/ -/**************************************************************************** - * Low-level Helpers - ****************************************************************************/ /**************************************************************************** * Name: sam_takesem * @@ -700,9 +697,9 @@ static void sam_takesem(struct sam_dev_s *priv) static bool sam_checkreg(struct sam_dev_s *priv, bool wr, uint32_t value, uint32_t address) { - if (wr == priv->wrlast && /* Same kind of access? */ + if (wr == priv->wrlast && /* Same kind of access? */ value == priv->vallast && /* Same value? */ - address == priv->addrlast) /* Same address? */ + address == priv->addrlast) /* Same address? */ { /* Yes, then just keep a count of the number of times we did this. */ @@ -742,7 +739,8 @@ static bool sam_checkreg(struct sam_dev_s *priv, bool wr, uint32_t value, * ****************************************************************************/ -static inline uint32_t sam_getreg(struct sam_dev_s *priv, unsigned int offset) +static inline uint32_t sam_getreg(struct sam_dev_s *priv, + unsigned int offset) { uint32_t address = priv->base + offset; uint32_t value = getreg32(address); @@ -864,7 +862,8 @@ static void sam_disablewaitints(struct sam_dev_s *priv, * ****************************************************************************/ -static inline void sam_configxfrints(struct sam_dev_s *priv, uint32_t xfrmask) +static inline void sam_configxfrints(struct sam_dev_s *priv, + uint32_t xfrmask) { priv->xfrmask = xfrmask; } @@ -948,10 +947,6 @@ static inline void sam_enable(struct sam_dev_s *priv) sam_putreg(priv, HSMCI_CR_MCIEN, SAM_HSMCI_CR_OFFSET); } -/**************************************************************************** - * Register Sampling - ****************************************************************************/ - /**************************************************************************** * Name: sam_hsmcisample * @@ -996,22 +991,38 @@ static void sam_hsmcidump(struct sam_dev_s *priv, struct sam_hsmciregs_s *regs, const char *msg) { lcdinfo("HSMCI Registers: %s\n", msg); - lcdinfo(" MR[%08x]: %08x\n", priv->base + SAM_HSMCI_MR_OFFSET, regs->mr); - lcdinfo(" DTOR[%08x]: %08x\n", priv->base + SAM_HSMCI_DTOR_OFFSET, regs->dtor); - lcdinfo(" SDCR[%08x]: %08x\n", priv->base + SAM_HSMCI_SDCR_OFFSET, regs->sdcr); - lcdinfo(" ARGR[%08x]: %08x\n", priv->base + SAM_HSMCI_ARGR_OFFSET, regs->argr); - lcdinfo(" BLKR[%08x]: %08x\n", priv->base + SAM_HSMCI_BLKR_OFFSET, regs->blkr); - lcdinfo(" CSTOR[%08x]: %08x\n", priv->base + SAM_HSMCI_CSTOR_OFFSET, regs->cstor); - lcdinfo(" RSPR0[%08x]: %08x\n", priv->base + SAM_HSMCI_RSPR0_OFFSET, regs->rsp0); - lcdinfo(" RSPR1[%08x]: %08x\n", priv->base + SAM_HSMCI_RSPR1_OFFSET, regs->rsp1); - lcdinfo(" RSPR2[%08x]: %08x\n", priv->base + SAM_HSMCI_RSPR2_OFFSET, regs->rsp2); - lcdinfo(" RSPR3[%08x]: %08x\n", priv->base + SAM_HSMCI_RSPR3_OFFSET, regs->rsp3); - lcdinfo(" SR[%08x]: %08x\n", priv->base + SAM_HSMCI_SR_OFFSET, regs->sr); - lcdinfo(" IMR[%08x]: %08x\n", priv->base + SAM_HSMCI_IMR_OFFSET, regs->imr); - lcdinfo(" DMA[%08x]: %08x\n", priv->base + SAM_HSMCI_DMA_OFFSET, regs->dma); - lcdinfo(" CFG[%08x]: %08x\n", priv->base + SAM_HSMCI_CFG_OFFSET, regs->cfg); - lcdinfo(" WPMR[%08x]: %08x\n", priv->base + SAM_HSMCI_WPMR_OFFSET, regs->wpmr); - lcdinfo(" WPSR[%08x]: %08x\n", priv->base + SAM_HSMCI_WPSR_OFFSET, regs->wpsr); + lcdinfo(" MR[%08x]: %08x\n", + priv->base + SAM_HSMCI_MR_OFFSET, regs->mr); + lcdinfo(" DTOR[%08x]: %08x\n", + priv->base + SAM_HSMCI_DTOR_OFFSET, regs->dtor); + lcdinfo(" SDCR[%08x]: %08x\n", + priv->base + SAM_HSMCI_SDCR_OFFSET, regs->sdcr); + lcdinfo(" ARGR[%08x]: %08x\n", + priv->base + SAM_HSMCI_ARGR_OFFSET, regs->argr); + lcdinfo(" BLKR[%08x]: %08x\n", + priv->base + SAM_HSMCI_BLKR_OFFSET, regs->blkr); + lcdinfo(" CSTOR[%08x]: %08x\n", + priv->base + SAM_HSMCI_CSTOR_OFFSET, regs->cstor); + lcdinfo(" RSPR0[%08x]: %08x\n", + priv->base + SAM_HSMCI_RSPR0_OFFSET, regs->rsp0); + lcdinfo(" RSPR1[%08x]: %08x\n", + priv->base + SAM_HSMCI_RSPR1_OFFSET, regs->rsp1); + lcdinfo(" RSPR2[%08x]: %08x\n", + priv->base + SAM_HSMCI_RSPR2_OFFSET, regs->rsp2); + lcdinfo(" RSPR3[%08x]: %08x\n", + priv->base + SAM_HSMCI_RSPR3_OFFSET, regs->rsp3); + lcdinfo(" SR[%08x]: %08x\n", + priv->base + SAM_HSMCI_SR_OFFSET, regs->sr); + lcdinfo(" IMR[%08x]: %08x\n", + priv->base + SAM_HSMCI_IMR_OFFSET, regs->imr); + lcdinfo(" DMA[%08x]: %08x\n", + priv->base + SAM_HSMCI_DMA_OFFSET, regs->dma); + lcdinfo(" CFG[%08x]: %08x\n", + priv->base + SAM_HSMCI_CFG_OFFSET, regs->cfg); + lcdinfo(" WPMR[%08x]: %08x\n", + priv->base + SAM_HSMCI_WPMR_OFFSET, regs->wpmr); + lcdinfo(" WPSR[%08x]: %08x\n", + priv->base + SAM_HSMCI_WPSR_OFFSET, regs->wpsr); } #endif @@ -1192,10 +1203,6 @@ static void sam_cmddump(struct sam_dev_s *priv) } #endif -/**************************************************************************** - * DMA Helpers - ****************************************************************************/ - /**************************************************************************** * Name: sam_dmacallback * @@ -1228,32 +1235,37 @@ static void sam_dmacallback(DMA_HANDLE handle, void *arg, int result) if (result < 0) { - wkupevent = (result == -ETIMEDOUT ? SDIOWAIT_TIMEOUT : SDIOWAIT_ERROR); - mcerr("ERROR: DMA failed: result=%d wkupevent=%04x\n", result, wkupevent); + wkupevent = (result == -ETIMEDOUT ? + SDIOWAIT_TIMEOUT : SDIOWAIT_ERROR); - /* sam_endtransfer will terminate the transfer and wait up the waiting - * client in this case. + mcerr("ERROR: DMA failed: result=%d wkupevent=%04x\n", + result, wkupevent); + + /* sam_endtransfer will terminate the transfer and wait up the + * waiting client in this case. */ sam_endtransfer(priv, wkupevent); } - /* The DMA completed without error. Wake-up the waiting client if (1) both the - * HSMCI and DMA completion events, and (2) There is a client waiting for - * this event. + /* The DMA completed without error. Wake-up the waiting client if + * (1) both the HSMCI and DMA completion events, and (2) There is a + * client waiting for this event. * - * If the HSMCI transfer event has already completed, it must have completed - * successfully (because the DMA was not cancelled). sam_endtransfer() should - * have already received the SDIOWAIT_TRANSFERDONE event, but this event would - * not yet have been recorded. We need to post the SDIOWAIT_TRANSFERDONE - * again in this case here. + * If the HSMCI transfer event has already completed, it must have + * completed successfully (because the DMA was not canceled). + * sam_endtransfer() should have already received the + * SDIOWAIT_TRANSFERDONE event, but this event would not yet have been + * recorded. We need to post the SDIOWAIT_TRANSFERDONE again in this + * case here. * - * The timeout will remain active until sam_endwait() is eventually called - * so we should not have any concern about hangs if the HSMCI transfer never - * completed. + * The timeout will remain active until sam_endwait() is eventually + * called so we should not have any concern about hangs if the HSMCI + * transfer never completed. */ - else if (!priv->xfrbusy && (priv->waitevents & SDIOWAIT_TRANSFERDONE) != 0) + else if (!priv->xfrbusy && + (priv->waitevents & SDIOWAIT_TRANSFERDONE) != 0) { /* Okay.. wake up any waiting threads */ @@ -1276,10 +1288,6 @@ static inline uintptr_t hsmci_physregaddr(struct sam_dev_s *priv, return sam_physregaddr(priv->base + offset); } -/**************************************************************************** - * Data Transfer Helpers - ****************************************************************************/ - /**************************************************************************** * Name: sam_eventtimeout * @@ -1425,7 +1433,8 @@ static void sam_endtransfer(struct sam_dev_s *priv, * this event. * * The timeout will remain active until sam_endwait() is eventually called - * so we should not have any concern about hangs if the DMA never completes. + * so we should not have any concern about hangs if the DMA never + * completes. */ if (!priv->dmabusy && (priv->waitevents & wkupevent) != 0) @@ -1474,10 +1483,6 @@ static void sam_notransfer(struct sam_dev_s *priv) priv->txbusy = false; } -/**************************************************************************** - * Interrupt Handling - ****************************************************************************/ - /**************************************************************************** * Name: sam_hsmci_interrupt * @@ -1521,6 +1526,7 @@ static int sam_hsmci_interrupt(int irq, void *context, void *arg) } /* Handle in progress, interrupt driven data transfers ****************/ + /* Do any of these interrupts signal a data transfer event? */ pending = enabled & priv->xfrmask; @@ -1532,18 +1538,21 @@ static int sam_hsmci_interrupt(int irq, void *context, void *arg) { /* Yes.. Was it some kind of timeout error? */ - mcerr("ERROR: enabled: %08x pending: %08x\n", enabled, pending); + mcerr("ERROR: enabled: %08x pending: %08x\n", + enabled, pending); if ((pending & HSMCI_DATA_TIMEOUT_ERRORS) != 0) { /* Yes.. Terminate with a timeout. */ - sam_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_TIMEOUT); + sam_endtransfer(priv, + SDIOWAIT_TRANSFERDONE | SDIOWAIT_TIMEOUT); } else { /* No.. Terminate with an I/O error. */ - sam_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR); + sam_endtransfer(priv, + SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR); } } @@ -1585,6 +1594,7 @@ static int sam_hsmci_interrupt(int irq, void *context, void *arg) } /* Handle wait events *************************************************/ + /* Do any of these interrupts signal wakeup event? */ pending = enabled & priv->waitmask; @@ -1645,9 +1655,6 @@ static int sam_hsmci_interrupt(int irq, void *context, void *arg) return OK; } -/**************************************************************************** - * SDIO Interface Methods - ****************************************************************************/ /**************************************************************************** * Name: sam_reset * @@ -1931,9 +1938,8 @@ static int sam_attach(FAR struct sdio_dev_s *dev) ret = irq_attach(irq, sam_hsmci_interrupt, priv); if (ret == OK) { - - /* Disable all interrupts at the HSMCI controller and clear (most) static - * interrupt flags by reading the status register. + /* Disable all interrupts at the HSMCI controller and clear (most) + * static interrupt flags by reading the status register. */ sam_putreg(priv, 0xffffffff, SAM_HSMCI_IDR_OFFSET); @@ -2002,12 +2008,12 @@ static int sam_sendcmd(FAR struct sdio_dev_s *dev, case MMCSD_R5_RESPONSE: case MMCSD_R6_RESPONSE: priv->cmdrmask = HSMCI_CMDRESP_INTS; - regval |= (HSMCI_CMDR_RSPTYP_48BIT | HSMCI_CMDR_MAXLAT); + regval |= HSMCI_CMDR_RSPTYP_48BIT | HSMCI_CMDR_MAXLAT; break; case MMCSD_R1B_RESPONSE: priv->cmdrmask = HSMCI_CMDRESP_INTS; - regval |= (HSMCI_CMDR_RSPTYP_R1B | HSMCI_CMDR_MAXLAT); + regval |= HSMCI_CMDR_RSPTYP_R1B | HSMCI_CMDR_MAXLAT; break; /* 48-bit response without CRC */ @@ -2015,14 +2021,14 @@ static int sam_sendcmd(FAR struct sdio_dev_s *dev, case MMCSD_R3_RESPONSE: case MMCSD_R7_RESPONSE: priv->cmdrmask = HSMCI_CMDRESP_NOCRC_INTS; - regval |= (HSMCI_CMDR_RSPTYP_48BIT | HSMCI_CMDR_MAXLAT); + regval |= HSMCI_CMDR_RSPTYP_48BIT | HSMCI_CMDR_MAXLAT; break; /* 136-bit response with CRC */ case MMCSD_R2_RESPONSE: priv->cmdrmask = HSMCI_CMDRESP_INTS; - regval |= (HSMCI_CMDR_RSPTYP_136BIT | HSMCI_CMDR_MAXLAT); + regval |= HSMCI_CMDR_RSPTYP_136BIT | HSMCI_CMDR_MAXLAT; break; } @@ -2032,22 +2038,26 @@ static int sam_sendcmd(FAR struct sdio_dev_s *dev, { #if 0 /* No MMC support */ case MMCSD_RDSTREAM: /* MMC Read stream */ - regval |= (HSMCI_CMDR_TRCMD_START | HSMCI_CMDR_TRTYP_STREAM | HSMCI_CMDR_TRDIR_READ); + regval |= HSMCI_CMDR_TRCMD_START | HSMCI_CMDR_TRTYP_STREAM | + HSMCI_CMDR_TRDIR_READ; break; case MMCSD_WRSTREAM: /* MMC Write stream */ - regval |= (HSMCI_CMDR_TRCMD_START | HSMCI_CMDR_TRTYP_STREAM | HSMCI_CMDR_TRDIR_WRITE); + regval |= HSMCI_CMDR_TRCMD_START | HSMCI_CMDR_TRTYP_STREAM | + HSMCI_CMDR_TRDIR_WRITE; break; #endif case MMCSD_RDDATAXFR: /* Read block transfer */ - regval |= (HSMCI_CMDR_TRCMD_START | HSMCI_CMDR_TRDIR_READ); - regval |= (cmd & MMCSD_MULTIBLOCK) ? HSMCI_CMDR_TRTYP_MULTIPLE : HSMCI_CMDR_TRTYP_SINGLE; + regval |= HSMCI_CMDR_TRCMD_START | HSMCI_CMDR_TRDIR_READ; + regval |= (cmd & MMCSD_MULTIBLOCK) ? + HSMCI_CMDR_TRTYP_MULTIPLE : HSMCI_CMDR_TRTYP_SINGLE; break; case MMCSD_WRDATAXFR: /* Write block transfer */ - regval |= (HSMCI_CMDR_TRCMD_START | HSMCI_CMDR_TRDIR_WRITE); - regval |= (cmd & MMCSD_MULTIBLOCK) ? HSMCI_CMDR_TRTYP_MULTIPLE : HSMCI_CMDR_TRTYP_SINGLE; + regval |= HSMCI_CMDR_TRCMD_START | HSMCI_CMDR_TRDIR_WRITE; + regval |= (cmd & MMCSD_MULTIBLOCK) ? + HSMCI_CMDR_TRTYP_MULTIPLE : HSMCI_CMDR_TRTYP_SINGLE; break; case MMCSD_NODATAXFR: @@ -2124,8 +2134,9 @@ static void sam_blocksetup(FAR struct sdio_dev_s *dev, unsigned int blocklen, * (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 @@ -2176,9 +2187,9 @@ static int sam_recvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, * Name: sam_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: @@ -2191,8 +2202,8 @@ static int sam_recvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, * ****************************************************************************/ -static int sam_sendsetup(FAR struct sdio_dev_s *dev, FAR const uint8_t *buffer, - size_t buflen) +static int sam_sendsetup(FAR struct sdio_dev_s *dev, + FAR const uint8_t *buffer, size_t buflen) { struct sam_dev_s *priv = (struct sam_dev_s *)dev; unsigned int nwords; @@ -2381,7 +2392,8 @@ static int sam_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd) { /* Yes.. return a timeout error */ - priv->wkupevent = SDIOWAIT_CMDDONE | SDIOWAIT_RESPONSEDONE | + priv->wkupevent = SDIOWAIT_CMDDONE | + SDIOWAIT_RESPONSEDONE | SDIOWAIT_TIMEOUT; return -ETIMEDOUT; } @@ -2389,7 +2401,8 @@ static int sam_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd) { /* No.. return some generic I/O error */ - priv->wkupevent = SDIOWAIT_CMDDONE | SDIOWAIT_RESPONSEDONE | + priv->wkupevent = SDIOWAIT_CMDDONE | + SDIOWAIT_RESPONSEDONE | SDIOWAIT_ERROR; return -EIO; } @@ -2414,7 +2427,7 @@ static int sam_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd) } /**************************************************************************** - * Name: sam_recvRx + * Name: sam_recv* * * Description: * Receive response to SDIO command. Only the critical payload is @@ -2522,7 +2535,8 @@ static int sam_recvshort(FAR struct sdio_dev_s *dev, return ret; } -static int sam_recvlong(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t rlong[4]) +static int sam_recvlong(FAR struct sdio_dev_s *dev, uint32_t cmd, + uint32_t rlong[4]) { struct sam_dev_s *priv = (struct sam_dev_s *)dev; int ret = OK; @@ -2603,8 +2617,8 @@ static int sam_recvnotimpl(FAR struct sdio_dev_s *dev, * SDIO_WAITEVENT: Wait for the event of interest (which might * already have occurred) * - * This sequency should eliminate race conditions between the command/trasnfer - * 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 @@ -2736,26 +2750,26 @@ static sdio_eventset_t sam_eventwait(FAR struct sdio_dev_s *dev, } } - /* Loop until the event (or the timeout occurs). Race conditions are avoided - * by calling sam_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 sam_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. */ sam_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 nonzero value. - * When wkupevent becomes non-zero, further interrupts will have already - * been disabled. + * evenset will be set to 0 and wkupevent will be set to a nonzero + * value. When wkupevent becomes non-zero, further interrupts will + * have already been disabled. */ if (wkupevent != 0) @@ -2883,8 +2897,10 @@ static int sam_dmarecvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, */ regval = sam_getreg(priv, SAM_HSMCI_BLKR_OFFSET); - nblocks = ((regval & HSMCI_BLKR_BCNT_MASK) >> HSMCI_BLKR_BCNT_SHIFT); - blocksize = ((regval & HSMCI_BLKR_BLKLEN_MASK) >> HSMCI_BLKR_BLKLEN_SHIFT); + nblocks = ((regval & HSMCI_BLKR_BCNT_MASK) >> + HSMCI_BLKR_BCNT_SHIFT); + blocksize = ((regval & HSMCI_BLKR_BLKLEN_MASK) >> + HSMCI_BLKR_BLKLEN_SHIFT); DEBUGASSERT(nblocks > 0 && blocksize > 0 && (blocksize & 3) == 0); @@ -2918,7 +2934,8 @@ static int sam_dmarecvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, /* Enable DMA handshaking */ - sam_putreg(priv, HSMCI_DMA_DMAEN | HSMCI_DMA_CHKSIZE, SAM_HSMCI_DMA_OFFSET); + sam_putreg(priv, + HSMCI_DMA_DMAEN | HSMCI_DMA_CHKSIZE, SAM_HSMCI_DMA_OFFSET); sam_xfrsample(priv, SAMPLENDX_BEFORE_ENABLE); /* Start the DMA */ @@ -2979,8 +2996,10 @@ static int sam_dmasendsetup(FAR struct sdio_dev_s *dev, */ regval = sam_getreg(priv, SAM_HSMCI_BLKR_OFFSET); - nblocks = ((regval & HSMCI_BLKR_BCNT_MASK) >> HSMCI_BLKR_BCNT_SHIFT); - blocksize = ((regval & HSMCI_BLKR_BLKLEN_MASK) >> HSMCI_BLKR_BLKLEN_SHIFT); + nblocks = ((regval & HSMCI_BLKR_BCNT_MASK) >> + HSMCI_BLKR_BCNT_SHIFT); + blocksize = ((regval & HSMCI_BLKR_BLKLEN_MASK) >> + HSMCI_BLKR_BLKLEN_SHIFT); DEBUGASSERT(nblocks > 0 && blocksize > 0 && (blocksize & 3) == 0); @@ -3014,7 +3033,8 @@ static int sam_dmasendsetup(FAR struct sdio_dev_s *dev, /* Enable DMA handshaking */ - sam_putreg(priv, HSMCI_DMA_DMAEN | HSMCI_DMA_CHKSIZE, SAM_HSMCI_DMA_OFFSET); + sam_putreg(priv, + HSMCI_DMA_DMAEN | HSMCI_DMA_CHKSIZE, SAM_HSMCI_DMA_OFFSET); sam_xfrsample(priv, SAMPLENDX_BEFORE_ENABLE); /* Start the DMA */ @@ -3035,9 +3055,6 @@ static int sam_dmasendsetup(FAR struct sdio_dev_s *dev, } #endif -/**************************************************************************** - * Initialization/uninitialization/reset - ****************************************************************************/ /**************************************************************************** * Name: sam_callback * @@ -3104,8 +3121,8 @@ static void sam_callback(void *arg) * * So to minimize the possibility of recursive behavior and to assure * that callback is always performed outside of the interrupt handling - * context and with interrupts enabled, the callback is always performed - * on the lower priority work thread. + * context and with interrupts enabled, the callback is always + * performed on the lower priority work thread. */ /* First cancel any existing work */ @@ -3146,7 +3163,8 @@ static void sam_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. * ****************************************************************************/ @@ -3292,6 +3310,7 @@ FAR struct sdio_dev_s *sdio_initialize(int slotno) priv, priv->base, priv->hsmci, dmac, pid); /* Initialize the HSMCI slot structure */ + /* Initialize semaphores */ nxsem_init(&priv->waitsem, 0, 0); diff --git a/arch/arm/src/samv7/sam_hsmci.c b/arch/arm/src/samv7/sam_hsmci.c index f75ba5c15c7..ece88b472fb 100644 --- a/arch/arm/src/samv7/sam_hsmci.c +++ b/arch/arm/src/samv7/sam_hsmci.c @@ -1,35 +1,20 @@ /**************************************************************************** * arch/arm/src/samv7/sam_hsmci.c * - * Copyright (C) 2015-2017 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt + * 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. * ****************************************************************************/ @@ -161,7 +146,8 @@ * HSMCI_INT_UNRE Data transmit underrun * HSMCI_INT_OVRE Data receive overrun * HSMCI_INT_BLKOVRE DMA receive block overrun error - * HSMCI_INT_CSTOE Completion signal time-out error (see HSMCI_CSTOR) + * HSMCI_INT_CSTOE Completion signal time-out error + * (see HSMCI_CSTOR) * HSMCI_INT_DTOE Data time-out error (see HSMCI_DTOR) * HSMCI_INT_DCRCE Data CRC Error * HSMCI_INT_RTOE Response Time-out @@ -178,7 +164,8 @@ /* Response errors: * - * HSMCI_INT_CSTOE Completion signal time-out error (see HSMCI_CSTOR) + * HSMCI_INT_CSTOE Completion signal time-out error + * (see HSMCI_CSTOR) * HSMCI_INT_RTOE Response Time-out * HSMCI_INT_RENDE Response End Bit Error * HSMCI_INT_RCRCE Response CRC Error @@ -200,7 +187,8 @@ * HSMCI_INT_UNRE Data transmit underrun * HSMCI_INT_OVRE Data receive overrun * HSMCI_INT_BLKOVRE DMA receive block overrun error - * HSMCI_INT_CSTOE Completion signal time-out error (see HSMCI_CSTOR) + * HSMCI_INT_CSTOE Completion signal time-out error + * (see HSMCI_CSTOR) * HSMCI_INT_DTOE Data time-out error (see HSMCI_DTOR) * HSMCI_INT_DCRCE Data CRC Error */ @@ -225,11 +213,13 @@ * write sequence is finished. * * 0: A transfer is in progress. - * 1: Command register is ready to operate and the data bus is in the idle state. + * 1: Command register is ready to operate and the data bus is in the + * idle state. * * DMADONE: DMA Transfer done * - * 0: DMA buffer transfer has not completed since the last read of HSMCI_SR register. + * 0: DMA buffer transfer has not completed since the last read of + * HSMCI_SR register. * 1: DMA buffer transfer has completed. */ @@ -246,7 +236,8 @@ * * 0: A command is in progress * 1: The last command has been sent. The CMDRDY flag is released 8 bits - * after the end of the card response. Cleared when writing in the HSMCI_CMDR + * after the end of the card response. Cleared when writing in the + * HSMCI_CMDR */ #define HSMCI_CMDRESP_INTS \ @@ -288,6 +279,7 @@ /**************************************************************************** * Private Types ****************************************************************************/ + /* Register logging support */ #if defined(CONFIG_SAMV7_HSMCI_XFRDEBUG) || defined(CONFIG_SAMV7_HSMCI_CMDDEBUG) @@ -328,59 +320,63 @@ struct sam_xfrregs_s struct sam_dev_s { - struct sdio_dev_s dev; /* Standard, base SDIO interface */ + struct sdio_dev_s dev; /* Standard, base SDIO interface */ /* SAMV7-specific extensions */ + /* Event support */ - sem_t waitsem; /* Implements event waiting */ - sdio_eventset_t waitevents; /* Set of events to be waited for */ - uint32_t base; /* HSMCI register base address */ - uint32_t waitmask; /* Interrupt enables for event waiting */ - uint32_t cmdrmask; /* Interrupt enables for this particular cmd/response */ + sem_t waitsem; /* Implements event waiting */ + sdio_eventset_t waitevents; /* Set of events to be waited for */ + uint32_t base; /* HSMCI register base address */ + uint32_t waitmask; /* Interrupt enables for event waiting */ + uint32_t cmdrmask; /* Interrupt enables for this + * particular cmd/response */ volatile sdio_eventset_t wkupevent; /* The event that caused the wakeup */ - WDOG_ID waitwdog; /* Watchdog that handles event timeouts */ - uint8_t hsmci; /* HSMCI (0, 1, or 2) */ - volatile bool dmabusy; /* TRUE: DMA transfer is in progress */ - volatile bool xfrbusy; /* TRUE: Transfer is in progress */ - volatile bool txbusy; /* TRUE: TX transfer is in progress (for delay calculation) */ + WDOG_ID waitwdog; /* Watchdog that handles event timeouts */ + uint8_t hsmci; /* HSMCI (0, 1, or 2) */ + volatile bool dmabusy; /* TRUE: DMA transfer is in progress */ + volatile bool xfrbusy; /* TRUE: Transfer is in progress */ + volatile bool txbusy; /* TRUE: TX transfer is in progress + * (for delay calculation) */ /* 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 xfrmask; /* Interrupt enables for data transfer */ + uint32_t xfrmask; /* Interrupt enables for data transfer */ /* Interrupt mode data transfer support */ - uint32_t *buffer; /* Address of current R/W buffer */ - ssize_t remaining; /* Number of bytes remaining in the transfer */ + uint32_t *buffer; /* Address of current R/W buffer */ + ssize_t remaining; /* Number of bytes remaining in the + * transfer */ /* DMA data transfer support */ - bool widebus; /* Required for DMA support */ - DMA_HANDLE dma; /* Handle for DMA channel */ + bool widebus; /* Required for DMA support */ + DMA_HANDLE dma; /* Handle for DMA channel */ /* Debug stuff */ #ifdef CONFIG_SAMV7_HSMCI_REGDEBUG - bool wrlast; /* Last was a write */ - uint32_t addrlast; /* Last address */ - uint32_t vallast; /* Last value */ - int ntimes; /* Number of times */ + bool wrlast; /* Last was a write */ + uint32_t addrlast; /* Last address */ + uint32_t vallast; /* Last value */ + int ntimes; /* Number of times */ #endif /* Register logging support */ #if defined(CONFIG_SAMV7_HSMCI_CMDDEBUG) && defined(CONFIG_SAMV7_HSMCI_XFRDEBUG) - bool xfrinitialized; - bool cmdinitialized; + bool xfrinitialized; + bool cmdinitialized; #endif #ifdef CONFIG_SAMV7_HSMCI_XFRDEBUG uint8_t smplset; @@ -412,10 +408,12 @@ static inline uint32_t sam_getreg(struct sam_dev_s *priv, static inline void sam_putreg(struct sam_dev_s *priv, uint32_t value, unsigned int offset); -static inline void sam_configwaitints(struct sam_dev_s *priv, uint32_t waitmask, - sdio_eventset_t waitevents); -static void sam_disablewaitints(struct sam_dev_s *priv, sdio_eventset_t wkupevent); -static inline void sam_configxfrints(struct sam_dev_s *priv, uint32_t xfrmask); +static inline void sam_configwaitints(struct sam_dev_s *priv, + uint32_t waitmask, sdio_eventset_t waitevents); +static void sam_disablewaitints(struct sam_dev_s *priv, + sdio_eventset_t wkupevent); +static inline void sam_configxfrints(struct sam_dev_s *priv, + uint32_t xfrmask); static void sam_disablexfrints(struct sam_dev_s *priv); static inline void sam_enableints(struct sam_dev_s *priv); @@ -466,7 +464,8 @@ static inline uintptr_t hsmci_regaddr(struct sam_dev_s *priv, static void sam_eventtimeout(int argc, uint32_t arg); static void sam_endwait(struct sam_dev_s *priv, sdio_eventset_t wkupevent); -static void sam_endtransfer(struct sam_dev_s *priv, sdio_eventset_t wkupevent); +static void sam_endtransfer(struct sam_dev_s *priv, + sdio_eventset_t wkupevent); static void sam_notransfer(struct sam_dev_s *priv); /* Interrupt Handling *******************************************************/ @@ -493,8 +492,8 @@ static void sam_blocksetup(FAR struct sdio_dev_s *dev, unsigned int blocklen, unsigned int nblocks); static int sam_recvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, size_t nbytes); -static int sam_sendsetup(FAR struct sdio_dev_s *dev, FAR const uint8_t *buffer, - size_t nbytes); +static int sam_sendsetup(FAR struct sdio_dev_s *dev, + FAR const uint8_t *buffer, size_t nbytes); static int sam_cancel(FAR struct sdio_dev_s *dev); static int sam_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd); static int sam_recvshort(FAR struct sdio_dev_s *dev, uint32_t cmd, @@ -535,6 +534,7 @@ static void sam_callback(void *arg); /**************************************************************************** * Private Data ****************************************************************************/ + /* Callbacks */ static const struct sdio_dev_s g_callbacks = @@ -551,13 +551,13 @@ static const struct sdio_dev_s g_callbacks = .sendsetup = sam_sendsetup, .cancel = sam_cancel, .waitresponse = sam_waitresponse, - .recvR1 = sam_recvshort, - .recvR2 = sam_recvlong, - .recvR3 = sam_recvshort, - .recvR4 = sam_recvnotimpl, - .recvR5 = sam_recvnotimpl, - .recvR6 = sam_recvshort, - .recvR7 = sam_recvshort, + .recv_r1 = sam_recvshort, + .recv_r2 = sam_recvlong, + .recv_r3 = sam_recvshort, + .recv_r4 = sam_recvnotimpl, + .recv_r5 = sam_recvnotimpl, + .recv_r6 = sam_recvshort, + .recv_r7 = sam_recvshort, .waitenable = sam_waitenable, .eventwait = sam_eventwait, .callbackenable = sam_callbackenable, @@ -589,9 +589,6 @@ static struct sam_dev_s g_hsmci1; * Private Functions ****************************************************************************/ -/**************************************************************************** - * Low-level Helpers - ****************************************************************************/ /**************************************************************************** * Name: sam_takesem * @@ -632,9 +629,9 @@ static void sam_takesem(struct sam_dev_s *priv) static bool sam_checkreg(struct sam_dev_s *priv, bool wr, uint32_t value, uint32_t address) { - if (wr == priv->wrlast && /* Same kind of access? */ + if (wr == priv->wrlast && /* Same kind of access? */ value == priv->vallast && /* Same value? */ - address == priv->addrlast) /* Same address? */ + address == priv->addrlast) /* Same address? */ { /* Yes, then just keep a count of the number of times we did this. */ @@ -674,7 +671,8 @@ static bool sam_checkreg(struct sam_dev_s *priv, bool wr, uint32_t value, * ****************************************************************************/ -static inline uint32_t sam_getreg(struct sam_dev_s *priv, unsigned int offset) +static inline uint32_t sam_getreg(struct sam_dev_s *priv, + unsigned int offset) { uint32_t address = priv->base + offset; uint32_t value = getreg32(address); @@ -796,7 +794,8 @@ static void sam_disablewaitints(struct sam_dev_s *priv, * ****************************************************************************/ -static inline void sam_configxfrints(struct sam_dev_s *priv, uint32_t xfrmask) +static inline void sam_configxfrints(struct sam_dev_s *priv, + uint32_t xfrmask) { priv->xfrmask = xfrmask; } @@ -880,10 +879,6 @@ static inline void sam_enable(struct sam_dev_s *priv) sam_putreg(priv, HSMCI_CR_MCIEN, SAM_HSMCI_CR_OFFSET); } -/**************************************************************************** - * Register Sampling - ****************************************************************************/ - /**************************************************************************** * Name: sam_hsmcisample * @@ -930,24 +925,40 @@ static void sam_hsmcidump(struct sam_dev_s *priv, struct sam_hsmciregs_s *regs, const char *msg) { mcinfo("HSMCI Registers: %s\n", msg); - mcinfo(" MR[%08x]: %08x\n", priv->base + SAM_HSMCI_MR_OFFSET, regs->mr); - mcinfo(" DTOR[%08x]: %08x\n", priv->base + SAM_HSMCI_DTOR_OFFSET, regs->dtor); - mcinfo(" SDCR[%08x]: %08x\n", priv->base + SAM_HSMCI_SDCR_OFFSET, regs->sdcr); - mcinfo(" ARGR[%08x]: %08x\n", priv->base + SAM_HSMCI_ARGR_OFFSET, regs->argr); - mcinfo(" BLKR[%08x]: %08x\n", priv->base + SAM_HSMCI_BLKR_OFFSET, regs->blkr); - mcinfo(" CSTOR[%08x]: %08x\n", priv->base + SAM_HSMCI_CSTOR_OFFSET, regs->cstor); + mcinfo(" MR[%08x]: %08x\n", + priv->base + SAM_HSMCI_MR_OFFSET, regs->mr); + mcinfo(" DTOR[%08x]: %08x\n", + priv->base + SAM_HSMCI_DTOR_OFFSET, regs->dtor); + mcinfo(" SDCR[%08x]: %08x\n", + priv->base + SAM_HSMCI_SDCR_OFFSET, regs->sdcr); + mcinfo(" ARGR[%08x]: %08x\n", + priv->base + SAM_HSMCI_ARGR_OFFSET, regs->argr); + mcinfo(" BLKR[%08x]: %08x\n", + priv->base + SAM_HSMCI_BLKR_OFFSET, regs->blkr); + mcinfo(" CSTOR[%08x]: %08x\n", + priv->base + SAM_HSMCI_CSTOR_OFFSET, regs->cstor); #if 0 /* Reading these can cause loss of response data */ - mcinfo(" RSPR0[%08x]: %08x\n", priv->base + SAM_HSMCI_RSPR0_OFFSET, regs->rsp0); - mcinfo(" RSPR1[%08x]: %08x\n", priv->base + SAM_HSMCI_RSPR1_OFFSET, regs->rsp1); - mcinfo(" RSPR2[%08x]: %08x\n", priv->base + SAM_HSMCI_RSPR2_OFFSET, regs->rsp2); - mcinfo(" RSPR3[%08x]: %08x\n", priv->base + SAM_HSMCI_RSPR3_OFFSET, regs->rsp3); + mcinfo(" RSPR0[%08x]: %08x\n", + priv->base + SAM_HSMCI_RSPR0_OFFSET, regs->rsp0); + mcinfo(" RSPR1[%08x]: %08x\n", + priv->base + SAM_HSMCI_RSPR1_OFFSET, regs->rsp1); + mcinfo(" RSPR2[%08x]: %08x\n", + priv->base + SAM_HSMCI_RSPR2_OFFSET, regs->rsp2); + mcinfo(" RSPR3[%08x]: %08x\n", + priv->base + SAM_HSMCI_RSPR3_OFFSET, regs->rsp3); #endif - mcinfo(" SR[%08x]: %08x\n", priv->base + SAM_HSMCI_SR_OFFSET, regs->sr); - mcinfo(" IMR[%08x]: %08x\n", priv->base + SAM_HSMCI_IMR_OFFSET, regs->imr); - mcinfo(" DMA[%08x]: %08x\n", priv->base + SAM_HSMCI_DMA_OFFSET, regs->dma); - mcinfo(" CFG[%08x]: %08x\n", priv->base + SAM_HSMCI_CFG_OFFSET, regs->cfg); - mcinfo(" WPMR[%08x]: %08x\n", priv->base + SAM_HSMCI_WPMR_OFFSET, regs->wpmr); - mcinfo(" WPSR[%08x]: %08x\n", priv->base + SAM_HSMCI_WPSR_OFFSET, regs->wpsr); + mcinfo(" SR[%08x]: %08x\n", + priv->base + SAM_HSMCI_SR_OFFSET, regs->sr); + mcinfo(" IMR[%08x]: %08x\n", + priv->base + SAM_HSMCI_IMR_OFFSET, regs->imr); + mcinfo(" DMA[%08x]: %08x\n", + priv->base + SAM_HSMCI_DMA_OFFSET, regs->dma); + mcinfo(" CFG[%08x]: %08x\n", + priv->base + SAM_HSMCI_CFG_OFFSET, regs->cfg); + mcinfo(" WPMR[%08x]: %08x\n", + priv->base + SAM_HSMCI_WPMR_OFFSET, regs->wpmr); + mcinfo(" WPSR[%08x]: %08x\n", + priv->base + SAM_HSMCI_WPSR_OFFSET, regs->wpsr); } #endif @@ -1128,10 +1139,6 @@ static void sam_cmddump(struct sam_dev_s *priv) } #endif -/**************************************************************************** - * DMA Helpers - ****************************************************************************/ - /**************************************************************************** * Name: sam_dmacallback * @@ -1164,32 +1171,37 @@ static void sam_dmacallback(DMA_HANDLE handle, void *arg, int result) if (result < 0) { - wkupevent = (result == -ETIMEDOUT ? SDIOWAIT_TIMEOUT : SDIOWAIT_ERROR); - mcerr("ERROR: DMA failed: result=%d wkupevent=%04x\n", result, wkupevent); + wkupevent = (result == -ETIMEDOUT ? + SDIOWAIT_TIMEOUT : SDIOWAIT_ERROR); - /* sam_endtransfer will terminate the transfer and wait up the waiting - * client in this case. + mcerr("ERROR: DMA failed: result=%d wkupevent=%04x\n", + result, wkupevent); + + /* sam_endtransfer will terminate the transfer and wait up the + * waiting client in this case. */ sam_endtransfer(priv, wkupevent); } - /* The DMA completed without error. Wake-up the waiting client if (1) both the - * HSMCI and DMA completion events, and (2) There is a client waiting for - * this event. + /* The DMA completed without error. Wake-up the waiting client if + * (1) both the HSMCI and DMA completion events, and (2) There is a + * client waiting for this event. * - * If the HSMCI transfer event has already completed, it must have completed - * successfully (because the DMA was not cancelled). sam_endtransfer() should - * have already received the SDIOWAIT_TRANSFERDONE event, but this event would - * not yet have been recorded. We need to post the SDIOWAIT_TRANSFERDONE - * again in this case here. + * If the HSMCI transfer event has already completed, it must have + * completed successfully (because the DMA was not cancelled). + * sam_endtransfer() should have already received the + * SDIOWAIT_TRANSFERDONE event, but this event would not yet have been + * recorded. We need to post the SDIOWAIT_TRANSFERDONE again in this + * case here. * - * The timeout will remain active until sam_endwait() is eventually called - * so we should not have any concern about hangs if the HSMCI transfer never - * completed. + * The timeout will remain active until sam_endwait() is eventually + * called so we should not have any concern about hangs if the HSMCI + * transfer never completed. */ - else if (!priv->xfrbusy && (priv->waitevents & SDIOWAIT_TRANSFERDONE) != 0) + else if (!priv->xfrbusy && + (priv->waitevents & SDIOWAIT_TRANSFERDONE) != 0) { /* Okay.. wake up any waiting threads */ @@ -1212,10 +1224,6 @@ static inline uintptr_t hsmci_regaddr(struct sam_dev_s *priv, return priv->base + offset; } -/**************************************************************************** - * Data Transfer Helpers - ****************************************************************************/ - /**************************************************************************** * Name: sam_eventtimeout * @@ -1361,7 +1369,8 @@ static void sam_endtransfer(struct sam_dev_s *priv, * this event. * * The timeout will remain active until sam_endwait() is eventually called - * so we should not have any concern about hangs if the DMA never completes. + * so we should not have any concern about hangs if the DMA never + * completes. */ if (!priv->dmabusy && (priv->waitevents & wkupevent) != 0) @@ -1410,10 +1419,6 @@ static void sam_notransfer(struct sam_dev_s *priv) priv->txbusy = false; } -/**************************************************************************** - * Interrupt Handling - ****************************************************************************/ - /**************************************************************************** * Name: sam_hsmci_interrupt * @@ -1456,6 +1461,7 @@ static int sam_hsmci_interrupt(int irq, void *context, void *arg) } /* Handle in progress, interrupt driven data transfers ****************/ + /* Do any of these interrupts signal a data transfer event? */ pending = enabled & priv->xfrmask; @@ -1467,18 +1473,22 @@ static int sam_hsmci_interrupt(int irq, void *context, void *arg) { /* Yes.. Was it some kind of timeout error? */ - mcerr("ERROR: enabled: %08x pending: %08x\n", enabled, pending); + mcerr("ERROR: enabled: %08x pending: %08x\n", + enabled, pending); + if ((pending & HSMCI_DATA_TIMEOUT_ERRORS) != 0) { /* Yes.. Terminate with a timeout. */ - sam_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_TIMEOUT); + sam_endtransfer(priv, + SDIOWAIT_TRANSFERDONE | SDIOWAIT_TIMEOUT); } else { /* No.. Terminate with an I/O error. */ - sam_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR); + sam_endtransfer(priv, + SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR); } } @@ -1569,6 +1579,7 @@ static int sam_hsmci_interrupt(int irq, void *context, void *arg) } /* Handle wait events *************************************************/ + /* Do any of these interrupts signal wakeup event? */ pending = enabled & priv->waitmask; @@ -1629,9 +1640,6 @@ static int sam_hsmci_interrupt(int irq, void *context, void *arg) return OK; } -/**************************************************************************** - * SDIO Interface Methods - ****************************************************************************/ /**************************************************************************** * Name: sam_reset * @@ -1908,9 +1916,8 @@ static int sam_attach(FAR struct sdio_dev_s *dev) ret = irq_attach(irq, sam_hsmci_interrupt, priv); if (ret == OK) { - - /* Disable all interrupts at the HSMCI controller and clear (most) static - * interrupt flags by reading the status register. + /* Disable all interrupts at the HSMCI controller and clear (most) + * static interrupt flags by reading the status register. */ sam_putreg(priv, 0xffffffff, SAM_HSMCI_IDR_OFFSET); @@ -1979,12 +1986,12 @@ static int sam_sendcmd(FAR struct sdio_dev_s *dev, case MMCSD_R5_RESPONSE: case MMCSD_R6_RESPONSE: priv->cmdrmask = HSMCI_CMDRESP_INTS; - regval |= (HSMCI_CMDR_RSPTYP_48BIT | HSMCI_CMDR_MAXLAT); + regval |= HSMCI_CMDR_RSPTYP_48BIT | HSMCI_CMDR_MAXLAT; break; case MMCSD_R1B_RESPONSE: priv->cmdrmask = HSMCI_CMDRESP_INTS; - regval |= (HSMCI_CMDR_RSPTYP_R1B | HSMCI_CMDR_MAXLAT); + regval |= HSMCI_CMDR_RSPTYP_R1B | HSMCI_CMDR_MAXLAT; break; /* 48-bit response without CRC */ @@ -1992,14 +1999,14 @@ static int sam_sendcmd(FAR struct sdio_dev_s *dev, case MMCSD_R3_RESPONSE: case MMCSD_R7_RESPONSE: priv->cmdrmask = HSMCI_CMDRESP_NOCRC_INTS; - regval |= (HSMCI_CMDR_RSPTYP_48BIT | HSMCI_CMDR_MAXLAT); + regval |= HSMCI_CMDR_RSPTYP_48BIT | HSMCI_CMDR_MAXLAT; break; /* 136-bit response with CRC */ case MMCSD_R2_RESPONSE: priv->cmdrmask = HSMCI_CMDRESP_INTS; - regval |= (HSMCI_CMDR_RSPTYP_136BIT | HSMCI_CMDR_MAXLAT); + regval |= HSMCI_CMDR_RSPTYP_136BIT | HSMCI_CMDR_MAXLAT; break; } @@ -2009,22 +2016,26 @@ static int sam_sendcmd(FAR struct sdio_dev_s *dev, { #if 0 /* No MMC support */ case MMCSD_RDSTREAM: /* MMC Read stream */ - regval |= (HSMCI_CMDR_TRCMD_START | HSMCI_CMDR_TRTYP_STREAM | HSMCI_CMDR_TRDIR_READ); + regval |= HSMCI_CMDR_TRCMD_START | HSMCI_CMDR_TRTYP_STREAM | + HSMCI_CMDR_TRDIR_READ; break; case MMCSD_WRSTREAM: /* MMC Write stream */ - regval |= (HSMCI_CMDR_TRCMD_START | HSMCI_CMDR_TRTYP_STREAM | HSMCI_CMDR_TRDIR_WRITE); + regval |= HSMCI_CMDR_TRCMD_START | HSMCI_CMDR_TRTYP_STREAM | + HSMCI_CMDR_TRDIR_WRITE; break; #endif case MMCSD_RDDATAXFR: /* Read block transfer */ - regval |= (HSMCI_CMDR_TRCMD_START | HSMCI_CMDR_TRDIR_READ); - regval |= (cmd & MMCSD_MULTIBLOCK) ? HSMCI_CMDR_TRTYP_MULTIPLE : HSMCI_CMDR_TRTYP_SINGLE; + regval |= HSMCI_CMDR_TRCMD_START | HSMCI_CMDR_TRDIR_READ; + regval |= (cmd & MMCSD_MULTIBLOCK) ? + HSMCI_CMDR_TRTYP_MULTIPLE : HSMCI_CMDR_TRTYP_SINGLE; break; case MMCSD_WRDATAXFR: /* Write block transfer */ - regval |= (HSMCI_CMDR_TRCMD_START | HSMCI_CMDR_TRDIR_WRITE); - regval |= (cmd & MMCSD_MULTIBLOCK) ? HSMCI_CMDR_TRTYP_MULTIPLE : HSMCI_CMDR_TRTYP_SINGLE; + regval |= HSMCI_CMDR_TRCMD_START | HSMCI_CMDR_TRDIR_WRITE; + regval |= (cmd & MMCSD_MULTIBLOCK) ? + HSMCI_CMDR_TRTYP_MULTIPLE : HSMCI_CMDR_TRTYP_SINGLE; break; case MMCSD_NODATAXFR: @@ -2101,8 +2112,9 @@ static void sam_blocksetup(FAR struct sdio_dev_s *dev, unsigned int blocklen, * (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 @@ -2163,9 +2175,9 @@ static int sam_recvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, * Name: sam_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: @@ -2178,8 +2190,8 @@ static int sam_recvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, * ****************************************************************************/ -static int sam_sendsetup(FAR struct sdio_dev_s *dev, FAR const uint8_t *buffer, - size_t buflen) +static int sam_sendsetup(FAR struct sdio_dev_s *dev, + FAR const uint8_t *buffer, size_t buflen) { struct sam_dev_s *priv = (struct sam_dev_s *)dev; unsigned int remaining; @@ -2423,7 +2435,8 @@ static int sam_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd) { /* Yes.. return a timeout error */ - priv->wkupevent = SDIOWAIT_CMDDONE | SDIOWAIT_RESPONSEDONE | + priv->wkupevent = SDIOWAIT_CMDDONE | + SDIOWAIT_RESPONSEDONE | SDIOWAIT_TIMEOUT; return -ETIMEDOUT; } @@ -2431,7 +2444,8 @@ static int sam_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd) { /* No.. return some generic I/O error */ - priv->wkupevent = SDIOWAIT_CMDDONE | SDIOWAIT_RESPONSEDONE | + priv->wkupevent = SDIOWAIT_CMDDONE | + SDIOWAIT_RESPONSEDONE | SDIOWAIT_ERROR; return -EIO; } @@ -2456,7 +2470,7 @@ static int sam_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd) } /**************************************************************************** - * Name: sam_recvRx + * Name: sam_recv* * * Description: * Receive response to SDIO command. Only the critical payload is @@ -2648,8 +2662,8 @@ static int sam_recvnotimpl(FAR struct sdio_dev_s *dev, * SDIO_WAITEVENT: Wait for the event of interest (which might * already have occurred) * - * This sequency should eliminate race conditions between the command/trasnfer - * 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 @@ -2731,12 +2745,14 @@ static sdio_eventset_t sam_eventwait(FAR struct sdio_dev_s *dev, sdio_eventset_t wkupevent = 0; int ret; +#if 0 /* REVISIT */ /* Since interrupts not been enabled to this point, any relevant events * are pending and should not yet have occurred. * REVISIT: Not true. DMA interrupts are enabled. */ - // DEBUGASSERT(priv->waitevents != 0 && priv->wkupevent == 0); + DEBUGASSERT(priv->waitevents != 0 && priv->wkupevent == 0); +#endif /* Now enable event-related interrupts. If the events are pending, they * may happen immediately here before entering the loop. @@ -2782,26 +2798,26 @@ static sdio_eventset_t sam_eventwait(FAR struct sdio_dev_s *dev, } } - /* Loop until the event (or the timeout occurs). Race conditions are avoided - * by calling sam_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 sam_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. */ sam_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 nonzero value. - * When wkupevent becomes non-zero, further interrupts will have already - * been disabled. + * evenset will be set to 0 and wkupevent will be set to a nonzero + * value. When wkupevent becomes non-zero, further interrupts will + * have already been disabled. */ if (wkupevent != 0) @@ -2943,8 +2959,10 @@ static int sam_dmarecvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, */ regval = sam_getreg(priv, SAM_HSMCI_BLKR_OFFSET); - nblocks = ((regval & HSMCI_BLKR_BCNT_MASK) >> HSMCI_BLKR_BCNT_SHIFT); - blocksize = ((regval & HSMCI_BLKR_BLKLEN_MASK) >> HSMCI_BLKR_BLKLEN_SHIFT); + nblocks = ((regval & HSMCI_BLKR_BCNT_MASK) >> + HSMCI_BLKR_BCNT_SHIFT); + blocksize = ((regval & HSMCI_BLKR_BLKLEN_MASK) >> + HSMCI_BLKR_BLKLEN_SHIFT); DEBUGASSERT(nblocks > 0 && blocksize > 0 && (blocksize & 3) == 0); @@ -2978,7 +2996,8 @@ static int sam_dmarecvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, /* Enable DMA handshaking */ - sam_putreg(priv, HSMCI_DMA_DMAEN | HSMCI_DMA_CHKSIZE, SAM_HSMCI_DMA_OFFSET); + sam_putreg(priv, + HSMCI_DMA_DMAEN | HSMCI_DMA_CHKSIZE, SAM_HSMCI_DMA_OFFSET); sam_xfrsample(priv, SAMPLENDX_BEFORE_ENABLE); /* Start the DMA */ @@ -3053,8 +3072,10 @@ static int sam_dmasendsetup(FAR struct sdio_dev_s *dev, */ regval = sam_getreg(priv, SAM_HSMCI_BLKR_OFFSET); - nblocks = ((regval & HSMCI_BLKR_BCNT_MASK) >> HSMCI_BLKR_BCNT_SHIFT); - blocksize = ((regval & HSMCI_BLKR_BLKLEN_MASK) >> HSMCI_BLKR_BLKLEN_SHIFT); + nblocks = ((regval & HSMCI_BLKR_BCNT_MASK) >> + HSMCI_BLKR_BCNT_SHIFT); + blocksize = ((regval & HSMCI_BLKR_BLKLEN_MASK) >> + HSMCI_BLKR_BLKLEN_SHIFT); DEBUGASSERT(nblocks > 0 && blocksize > 0 && (blocksize & 3) == 0); @@ -3088,7 +3109,8 @@ static int sam_dmasendsetup(FAR struct sdio_dev_s *dev, /* Enable DMA handshaking */ - sam_putreg(priv, HSMCI_DMA_DMAEN | HSMCI_DMA_CHKSIZE, SAM_HSMCI_DMA_OFFSET); + sam_putreg(priv, + HSMCI_DMA_DMAEN | HSMCI_DMA_CHKSIZE, SAM_HSMCI_DMA_OFFSET); sam_xfrsample(priv, SAMPLENDX_BEFORE_ENABLE); /* Start the DMA */ @@ -3109,9 +3131,6 @@ static int sam_dmasendsetup(FAR struct sdio_dev_s *dev, } #endif -/**************************************************************************** - * Initialization/uninitialization/reset - ****************************************************************************/ /**************************************************************************** * Name: sam_callback * @@ -3178,8 +3197,8 @@ static void sam_callback(void *arg) * * So to minimize the possibility of recursive behavior and to assure * that callback is always performed outside of the interrupt handling - * context and with interrupts enabled, the callback is always performed - * on the lower priority work thread. + * context and with interrupts enabled, the callback is always + * performed on the lower priority work thread. */ /* First cancel any existing work */ @@ -3220,7 +3239,8 @@ static void sam_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. * ****************************************************************************/ @@ -3324,6 +3344,7 @@ FAR struct sdio_dev_s *sdio_initialize(int slotno) priv, priv->base, priv->hsmci, pid); /* Initialize the HSMCI slot structure */ + /* Initialize semaphores */ nxsem_init(&priv->waitsem, 0, 0); diff --git a/arch/arm/src/stm32/stm32_sdio.c b/arch/arm/src/stm32/stm32_sdio.c index 693b0988e29..ec1f0017121 100644 --- a/arch/arm/src/stm32/stm32_sdio.c +++ b/arch/arm/src/stm32/stm32_sdio.c @@ -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 + * 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()) diff --git a/arch/arm/src/stm32f7/stm32_sdmmc.c b/arch/arm/src/stm32f7/stm32_sdmmc.c index de4b83d07ec..e2a1458dd8d 100644 --- a/arch/arm/src/stm32f7/stm32_sdmmc.c +++ b/arch/arm/src/stm32f7/stm32_sdmmc.c @@ -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. diff --git a/arch/arm/src/stm32h7/stm32_sdmmc.c b/arch/arm/src/stm32h7/stm32_sdmmc.c index cccc2eb960e..f5c329cd7cf 100644 --- a/arch/arm/src/stm32h7/stm32_sdmmc.c +++ b/arch/arm/src/stm32h7/stm32_sdmmc.c @@ -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); } diff --git a/arch/arm/src/stm32l4/stm32l4_sdmmc.c b/arch/arm/src/stm32l4/stm32l4_sdmmc.c index 6d251b28007..5d75f938277 100644 --- a/arch/arm/src/stm32l4/stm32l4_sdmmc.c +++ b/arch/arm/src/stm32l4/stm32l4_sdmmc.c @@ -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. diff --git a/drivers/mmcsd/mmcsd_sdio.c b/drivers/mmcsd/mmcsd_sdio.c index 35043166599..7883dca5376 100644 --- a/drivers/mmcsd/mmcsd_sdio.c +++ b/drivers/mmcsd/mmcsd_sdio.c @@ -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; } diff --git a/include/nuttx/sdio.h b/include/nuttx/sdio.h index aac175c6502..e232b512276 100644 --- a/include/nuttx/sdio.h +++ b/include/nuttx/sdio.h @@ -1,36 +1,20 @@ /**************************************************************************** * include/nuttx/sdio.h * - * Copyright (C) 2009, 2011-2013, 2017, 2019 Gregory Nutt. All rights - * reserved. - * Author: Gregory Nutt + * 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