From 50a1b9eddf729ca7dd012d3f555b4f261db1ad76 Mon Sep 17 00:00:00 2001 From: Dave Marples Date: Mon, 12 Nov 2018 13:47:44 -0600 Subject: [PATCH] arch/arm/src/imxrt: This commit complete the interrupt driven USDHC1 functionality for the IMXRT EVKB. There is more work to be done to complete DMA mode and further changes will follow. --- arch/arm/src/imxrt/chip/imxrt_usdhc.h | 42 +-- arch/arm/src/imxrt/imxrt_clockconfig.c | 4 +- arch/arm/src/imxrt/imxrt_usdhc.c | 385 +++++++++++-------------- configs/imxrt1050-evk/include/board.h | 36 ++- 4 files changed, 221 insertions(+), 246 deletions(-) diff --git a/arch/arm/src/imxrt/chip/imxrt_usdhc.h b/arch/arm/src/imxrt/chip/imxrt_usdhc.h index 5294b57e9d..9cc10b997c 100644 --- a/arch/arm/src/imxrt/chip/imxrt_usdhc.h +++ b/arch/arm/src/imxrt/chip/imxrt_usdhc.h @@ -155,10 +155,12 @@ /* Block Attributes Register */ #define USDHC_BLKATTR_SIZE_SHIFT (0) /* Bits 0-12: Transfer Block Size */ -#define USDHC_BLKATTR_SIZE_MASK (0x1fff << USDHC_BLKATTR_BLKSIZE_SHIFT) +#define USDHC_BLKATTR_SIZE_MASK (0x1fff << USDHC_BLKATTR_SIZE_SHIFT) +# define USDHC_BLKATTR_SIZE(n) ((n) << USDHC_BLKATTR_SIZE_SHIFT) /* Bits 13-15: Reserved */ #define USDHC_BLKATTR_CNT_SHIFT (16) /* Bits 16-31: Blocks Count For Current Transfer */ -#define USDHC_BLKATTR_CNT_MASK (0xffff << USDHC_BLKATTR_BLKCNT_SHIFT) +#define USDHC_BLKATTR_CNT_MASK (0xffff << USDHC_BLKATTR_CNT_SHIFT) +# define USDHC_BLKATTR_CNT(n) ((n) << USDHC_BLKATTR_CNT_SHIFT) /* Command Argument Register (32-bit cmd/arg data) */ @@ -266,7 +268,7 @@ #define USDHC_SYSCTL_RES0 (0x0F << 0) /* Bit 0-3: Reserved, set to 1 */ #define USDHC_SYSCTL_DVS_SHIFT (4) /* Bits 4-7: Divisor */ #define USDHC_SYSCTL_DVS_MASK (0x0f << USDHC_SYSCTL_DVS_SHIFT) -# define USDHC_SYSCTL_DVS_DIV(n) (((n)-1) << USDHC_SYSCTL_DVS_SHIFT) /* Divide by n, n=1..16 */ +# define USDHC_SYSCTL_DVS_DIV(n) (((n) - 1) << USDHC_SYSCTL_DVS_SHIFT) /* Divide by n, n=1..16 */ #define USDHC_SYSCTL_SDCLKFS_SHIFT (8) /* Bits 8-15: SDCLK Frequency Select */ #define USDHC_SYSCTL_SDCLKFS_MASK (0xff << USDHC_SYSCTL_SDCLKFS_SHIFT) # define USDHC_SYSCTL_SDCLKFS_BYPASS (0x00 << USDHC_SYSCTL_SDCLKFS_SHIFT) /* Bypass the prescaler */ @@ -280,7 +282,7 @@ # define USDHC_SYSCTL_SDCLKFS_DIV256 (0x80 << USDHC_SYSCTL_SDCLKFS_SHIFT) /* Base clock / 256 */ #define USDHC_SYSCTL_DTOCV_SHIFT (16) /* Bits 16-19: Data Timeout Counter Value */ #define USDHC_SYSCTL_DTOCV_MASK (0x0f << USDHC_SYSCTL_DTOCV_SHIFT) -# define USDHC_SYSCTL_DTOCV_MUL(n) (((n)-213) << USDHC_SYSCTL_DTOCV_SHIFT) /* SDCLK x n, n=213..227 */ +# define USDHC_SYSCTL_DTOCV_MUL(n) (((n) - 213) << USDHC_SYSCTL_DTOCV_SHIFT) /* SDCLK x n, n=213..227 */ /* Bits 20-22: Reserved */ #define USDHC_SYSCTL_IPPRSTN (1 << 23) /* Bit 23: Card /reset (default 1) */ #define USDHC_SYSCTL_RSTA (1 << 24) /* Bit 24: Software Reset For ALL */ @@ -346,7 +348,7 @@ /* Bits 3-7: Reserved */ #define USDHC_HTCAPBLT_TCR_SHIFT (8) /* Bits 8-11: Time count retuning */ #define USDHC_HTCAPBLT_TCR_MASK (0xF << USDHC_HTCAPBLT_TCR_SHIFT) -#define USDHC_HTCAPBLT_TCR(x) (((x)&0x0f) << USDHC_HTCAPBLT_TCR_SHIFT) +# define USDHC_HTCAPBLT_TCR(n) ((n) << USDHC_HTCAPBLT_TCR_SHIFT) #define USDHC_HTCAPBLT_USE_TUNING_SDR50 (1 << 13) /* Bit 13: Use tuning for SDR50 */ #define USDHC_HTCAPBLT_RET_MODE_SHIFT (14) /* bit 14-15: Retuning mode */ #define USDHC_HTCAPBLT_RET_MODE_MASK (3< + * Dave Marples * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -86,19 +87,14 @@ # error "Callback support requires CONFIG_SCHED_WORKQUEUE and CONFIG_SCHED_HPWORK" #endif +#if !defined(CONFIG_SDIO_BLOCKSETUP) +# error "CONFIG_SDIO_BLOCKSETUP is mandatory for this driver" +#endif + #ifndef CONFIG_DEBUG_MEMCARD_INFO # undef CONFIG_SDIO_XFRDEBUG #endif -/* SDCLK frequencies corresponding to various modes of operation. These - * values may be provided in either the NuttX configuration file or in - * 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. - */ - /* Timing in ms for commands wait response */ #define USDHC_CMDTIMEOUT MSEC2TICK(100) @@ -249,9 +245,7 @@ static void imxrt_showregs(struct imxrt_dev_s *priv, const char *msg); /* Data Transfer Helpers ****************************************************/ static void imxrt_dataconfig(struct imxrt_dev_s *priv, bool bwrite, - unsigned int blocksize, unsigned int nblocks, - unsigned int timeout); -static void imxrt_datadisable(void); + unsigned int dataLen, unsigned int timeout); #ifndef CONFIG_IMXRT_USDHC_DMA static void imxrt_transmit(struct imxrt_dev_s *priv); static void imxrt_receive(struct imxrt_dev_s *priv); @@ -289,6 +283,11 @@ static int imxrt_attach(FAR struct sdio_dev_s *dev); static int imxrt_sendcmd(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t arg); +#ifdef CONFIG_SDIO_BLOCKSETUP +static void imxrt_blocksetup(FAR struct sdio_dev_s *dev, + unsigned int blocklen, unsigned int nblocks); +#endif + #ifndef CONFIG_IMXRT_USDHC_DMA static int imxrt_recvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, size_t nbytes); @@ -349,6 +348,10 @@ struct imxrt_dev_s g_sdhcdev = .clock = imxrt_clock, .attach = imxrt_attach, .sendcmd = imxrt_sendcmd, +#ifdef CONFIG_SDIO_BLOCKSETUP + .blocksetup = imxrt_blocksetup, +#endif + #ifndef CONFIG_IMXRT_USDHC_DMA .recvsetup = imxrt_recvsetup, .sendsetup = imxrt_sendsetup, @@ -459,8 +462,7 @@ static void imxrt_configwaitints(struct imxrt_dev_s *priv, uint32_t waitints, #ifdef CONFIG_IMXRT_USDHC_DMA priv->xfrflags = 0; #endif - putreg32(priv->xfrints | priv->waitints | USDHC_INT_CINT, - IMXRT_USDHC1_IRQSIGEN); + putreg32(priv->xfrints | priv->waitints, IMXRT_USDHC1_IRQSIGEN); leave_critical_section(flags); } @@ -485,8 +487,7 @@ static void imxrt_configxfrints(struct imxrt_dev_s *priv, uint32_t xfrints) flags = enter_critical_section(); priv->xfrints = xfrints; - putreg32(priv->xfrints | priv->waitints | USDHC_INT_CINT, - IMXRT_USDHC1_IRQSIGEN); + putreg32(priv->xfrints | priv->waitints, IMXRT_USDHC1_IRQSIGEN); leave_critical_section(flags); } @@ -640,8 +641,7 @@ static void imxrt_showregs(struct imxrt_dev_s *priv, const char *msg) ****************************************************************************/ static void imxrt_dataconfig(struct imxrt_dev_s *priv, bool bwrite, - unsigned int blocksize, unsigned int nblocks, - unsigned int timeout) + unsigned int dataLen, unsigned int timeout) { unsigned int watermark; uint32_t regval = 0; @@ -653,23 +653,15 @@ static void imxrt_dataconfig(struct imxrt_dev_s *priv, bool bwrite, regval |= timeout << USDHC_SYSCTL_DTOCV_SHIFT; putreg32(regval, IMXRT_USDHC1_SYSCTL); - /* Set the block size and count in the USDHC_BLKATTR register. The block - * size is only valid for multiple block transfers. - */ - - regval = blocksize << USDHC_BLKATTR_SIZE_SHIFT | - nblocks << USDHC_BLKATTR_CNT_SHIFT; - putreg32(regval, IMXRT_USDHC1_BLKATTR); - /* Set the watermark level */ - /* Set the Read Watermark Level to the blocksize to be read + /* Set the Read Watermark Level to the dataLen to be read * (limited to half of the maximum watermark value). BRR will be * set when the number of queued words is greater than or equal * to this value. */ - watermark = (blocksize + 3) >> 2; + watermark = (dataLen + 3) >> 2; if (watermark > (USDHC_MAX_WATERMARK / 2)) { watermark = (USDHC_MAX_WATERMARK / 2); @@ -704,28 +696,6 @@ static void imxrt_dataconfig(struct imxrt_dev_s *priv, bool bwrite, } } -/**************************************************************************** - * Name: imxrt_datadisable - * - * Description: - * Disable the SDIO data path setup by imxrt_dataconfig() and - * disable DMA. - * - ****************************************************************************/ - -static void imxrt_datadisable(void) -{ - /* Set the data timeout value in the USDHC_SYSCTL field to the maximum value */ - - modifyreg32(IMXRT_USDHC1_SYSCTL, - USDHC_SYSCTL_DTOCV_MASK, - USDHC_DTOCV_MAXTIMEOUT << USDHC_SYSCTL_DTOCV_SHIFT); - - /* Set the block size to zero (no transfer) */ - - putreg32(0, IMXRT_USDHC1_BLKATTR); -} - /**************************************************************************** * Name: imxrt_transmit * @@ -1065,17 +1035,12 @@ static int imxrt_interrupt(int irq, void *context, FAR void *arg) * there are non-zero bits remaining, then we have work to do here. */ - mcerr("**"); regval = getreg32(IMXRT_USDHC1_IRQSIGEN); enabled = getreg32(IMXRT_USDHC1_IRQSTAT) & regval; + mcinfo("IRQSTAT: %08x IRQSIGEN %08x enabled: %08x\n", getreg32(IMXRT_USDHC1_IRQSTAT), regval, enabled); - /* Disable card interrupts to clear the card interrupt to the host system. */ - - regval &= ~USDHC_INT_CINT; - putreg32(regval, IMXRT_USDHC1_IRQSIGEN); - /* Clear all pending interrupts */ putreg32(enabled, IMXRT_USDHC1_IRQSTAT); @@ -1164,12 +1129,6 @@ static int imxrt_interrupt(int irq, void *context, FAR void *arg) } } - /* Re-enable card interrupts */ - - regval = getreg32(IMXRT_USDHC1_IRQSIGEN); - regval |= USDHC_INT_CINT; - putreg32(regval, IMXRT_USDHC1_IRQSIGEN); - return OK; } @@ -1244,7 +1203,7 @@ static void imxrt_reset(FAR struct sdio_dev_s *dev) { } - minfo("Reset complete\n"); + mcinfo("Reset complete\n"); /* Make sure that all clocking is disabled */ @@ -1255,7 +1214,6 @@ static void imxrt_reset(FAR struct sdio_dev_s *dev) */ putreg32(USDHC_INT_ALL, IMXRT_USDHC1_IRQSTATEN); - imxrt_datadisable(); mcinfo("SYSCTL: %08x PRSSTAT: %08x IRQSTATEN: %08x\n", getreg32(IMXRT_USDHC1_SYSCTL), getreg32(IMXRT_USDHC1_PRSSTAT), @@ -1550,8 +1508,8 @@ static void imxrt_clock(FAR struct sdio_dev_s *dev, enum sdio_clock_e rate) /* Select the new prescaler and divisor values based on the requested mode * and the settings from the board.h file. * - * TODO: Investigate using the automatically gated clocks to reduce power - * consumption. + * Clocks are automatically gated by the driver when not needed. + * */ switch (rate) @@ -1568,26 +1526,36 @@ static void imxrt_clock(FAR struct sdio_dev_s *dev, enum sdio_clock_e rate) case CLOCK_IDMODE : /* Initial ID mode clocking (<400KHz) */ mcinfo("IDMODE\n"); - regval |= (BOARD_USDHC_IDMODE_PRESCALER | BOARD_USDHC_IDMODE_DIVISOR); + + /* Put out an additional 80 clocks in case this is a power-up sequence */ + + regval |= (BOARD_USDHC_IDMODE_PRESCALER | + BOARD_USDHC_IDMODE_DIVISOR | USDHC_SYSCTL_INITA); break; case CLOCK_MMC_TRANSFER : /* MMC normal operation clocking */ mcinfo("MMCTRANSFER\n"); - regval |= (BOARD_USDHC_MMCMODE_PRESCALER | BOARD_USDHC_MMCMODE_DIVISOR); + + regval |= (BOARD_USDHC_MMCMODE_PRESCALER | + BOARD_USDHC_MMCMODE_DIVISOR); break; case CLOCK_SD_TRANSFER_1BIT : /* SD normal operation clocking (narrow * 1-bit mode) */ #ifndef CONFIG_IMXRT_USDHC_WIDTH_D1_ONLY mcinfo("1BITTRANSFER\n"); - regval |= (BOARD_USDHC_SD1MODE_PRESCALER | BOARD_USDHC_SD1MODE_DIVISOR); + + regval |= (BOARD_USDHC_SD1MODE_PRESCALER | + BOARD_USDHC_SD1MODE_DIVISOR); break; #endif case CLOCK_SD_TRANSFER_4BIT : /* SD normal operation clocking (wide * 4-bit mode) */ mcinfo("4BITTRANSFER\n"); - regval |= (BOARD_USDHC_SD4MODE_PRESCALER | BOARD_USDHC_SD4MODE_DIVISOR); + + regval |= (BOARD_USDHC_SD4MODE_PRESCALER | + BOARD_USDHC_SD4MODE_DIVISOR); break; } @@ -1657,8 +1625,9 @@ static int imxrt_attach(FAR struct sdio_dev_s *dev) * None * ****************************************************************************/ + static int imxrt_sendcmd(FAR struct sdio_dev_s *dev, uint32_t cmd, - uint32_t arg) + uint32_t arg) { clock_t timeout; clock_t start; @@ -1667,111 +1636,90 @@ static int imxrt_sendcmd(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t mcrregval; uint32_t cmdidx; -#if 1==0 - regval = getreg32(IMXRT_USDHC1_SYSCTL); - regval |= USDHC_SYSCTL_RSTC; - putreg32(regval, IMXRT_USDHC1_SYSCTL); - - while ((getreg32(IMXRT_USDHC1_SYSCTL) & USDHC_SYSCTL_RSTC) != 0) - { - } -#endif - - regval = getreg32(IMXRT_USDHC1_PRSSTAT); - /* Initialize the command index */ cmdidx = (cmd & MMCSD_CMDIDX_MASK) >> MMCSD_CMDIDX_SHIFT; regval = cmdidx << USDHC_XFERTYP_CMDINX_SHIFT; mcrregval = USDHC_MC_DEFAULTVAL; - /* Does a data transfer accompany the command? */ + /* Check if a data transfer accompanies the command */ - if ((cmd & MMCSD_DATAXFR) != 0) + switch (cmd & MMCSD_DATAXFR_MASK) { - /* Yes.. Configure the data transfer */ + default: + case MMCSD_NODATAXFR : /* No.. no data transfer */ + break; - switch (cmd & MMCSD_DATAXFR_MASK) - { - default: - case MMCSD_NODATAXFR : /* No.. no data transfer */ - break; + /* The following two cases are probably missing some setup logic */ - /* The following two cases are probably missing some setup logic */ + case MMCSD_RDSTREAM : /* Yes.. streaming read data transfer */ + regval |= USDHC_XFERTYP_DPSEL; + mcrregval |= USDHC_MC_DTDSEL; + break; - case MMCSD_RDSTREAM : /* Yes.. streaming read data transfer */ - regval |= USDHC_XFERTYP_DPSEL; - mcrregval |= USDHC_MC_DTDSEL; - break; + case MMCSD_WRSTREAM : /* Yes.. streaming write data transfer */ + regval |= USDHC_XFERTYP_DPSEL; + break; - case MMCSD_WRSTREAM : /* Yes.. streaming write data transfer */ - regval |= USDHC_XFERTYP_DPSEL; - break; + case MMCSD_RDDATAXFR : /* Yes.. normal read data transfer */ + regval |= USDHC_XFERTYP_DPSEL; + mcrregval |= USDHC_MC_DTDSEL; + break; - case MMCSD_RDDATAXFR : /* Yes.. normal read data transfer */ - regval |= USDHC_XFERTYP_DPSEL; - mcrregval |= USDHC_MC_DTDSEL; - break; - - case MMCSD_WRDATAXFR : /* Yes.. normal write data transfer */ - regval |= USDHC_XFERTYP_DPSEL; - break; - } - - /* Is it a multi-block transfer? */ - - if ((cmd & MMCSD_MULTIBLOCK) != 0) - { - /* Yes.. should the transfer be stopped with ACMD12? */ - - if ((cmd & MMCSD_STOPXFR) != 0) - { - /* Yes.. Indefinite block transfer */ - - mcrregval |= USDHC_MC_MSBSEL | USDHC_MC_AC12EN; - } - else - { - /* No.. Fixed block transfer */ - - mcrregval |= USDHC_MC_MSBSEL | USDHC_MC_BCEN; - } - } + case MMCSD_WRDATAXFR : /* Yes.. normal write data transfer */ + regval |= USDHC_XFERTYP_DPSEL; + break; } - else + + /* Is it a multi-block transfer? */ + + if ((cmd & MMCSD_MULTIBLOCK) != 0) { - mcrregval |= USDHC_MC_DTDSEL; + /* Yes.. should the transfer be stopped with ACMD12? */ + + if ((cmd & MMCSD_STOPXFR) != 0) + { + /* Yes.. Indefinite block transfer */ + + mcrregval |= USDHC_MC_MSBSEL | USDHC_MC_AC12EN; + } + else + { + /* No.. Fixed block transfer */ + + mcrregval |= USDHC_MC_MSBSEL | USDHC_MC_BCEN; + } } /* Configure response type bits */ switch (cmd & MMCSD_RESPONSE_MASK) { - case MMCSD_NO_RESPONSE: /* No response */ - regval |= USDHC_XFERTYP_RSPTYP_NONE; - break; + case MMCSD_NO_RESPONSE: /* No response */ + regval |= USDHC_XFERTYP_RSPTYP_NONE; + break; - case MMCSD_R1B_RESPONSE: /* Response length 48, check busy & cmdindex */ - regval |= (USDHC_XFERTYP_RSPTYP_LEN48BSY | USDHC_XFERTYP_CICEN | - USDHC_XFERTYP_CCCEN); - break; + case MMCSD_R1B_RESPONSE: /* Response length 48, check busy & cmdindex */ + regval |= (USDHC_XFERTYP_RSPTYP_LEN48BSY | USDHC_XFERTYP_CICEN | + USDHC_XFERTYP_CCCEN); + break; - case MMCSD_R1_RESPONSE: /* Response length 48, check cmdindex */ - case MMCSD_R5_RESPONSE: - case MMCSD_R6_RESPONSE: - regval |= (USDHC_XFERTYP_RSPTYP_LEN48 | USDHC_XFERTYP_CICEN | - USDHC_XFERTYP_CCCEN); - break; + case MMCSD_R1_RESPONSE: /* Response length 48, check cmdindex */ + case MMCSD_R5_RESPONSE: + case MMCSD_R6_RESPONSE: + regval |= (USDHC_XFERTYP_RSPTYP_LEN48 | USDHC_XFERTYP_CICEN | + USDHC_XFERTYP_CCCEN); + break; - case MMCSD_R2_RESPONSE: /* Response length 136, check CRC */ - regval |= (USDHC_XFERTYP_RSPTYP_LEN136 | USDHC_XFERTYP_CCCEN); - break; + case MMCSD_R2_RESPONSE: /* Response length 136, check CRC */ + regval |= (USDHC_XFERTYP_RSPTYP_LEN136 | USDHC_XFERTYP_CCCEN); + break; - case MMCSD_R3_RESPONSE: /* Response length 48 */ - case MMCSD_R4_RESPONSE: - case MMCSD_R7_RESPONSE: - regval |= USDHC_XFERTYP_RSPTYP_LEN48; - break; + case MMCSD_R3_RESPONSE: /* Response length 48 */ + case MMCSD_R4_RESPONSE: + case MMCSD_R7_RESPONSE: + regval |= USDHC_XFERTYP_RSPTYP_LEN48; + break; } /* Enable DMA */ @@ -1793,7 +1741,8 @@ static int imxrt_sendcmd(FAR struct sdio_dev_s *dev, uint32_t cmd, * indicates that the CMD line is not in use and the USDHC can issue a * SD/MMC Command using the CMD line. * - * CIHB should always be clear before this function is called. + * CIHB should always be clear before this function is called, but this + * check is performed here to provide overlap and maximum performance. */ timeout = USDHC_CMDTIMEOUT; @@ -1806,7 +1755,7 @@ static int imxrt_sendcmd(FAR struct sdio_dev_s *dev, uint32_t cmd, elapsed = clock_systimer() - start; if (elapsed >= timeout) { - mcerr("ERROR: Timeout cmd: %08x PRSSTAT: %08x\n", + mcerr("ERROR: Timeout (waiting CIHB) cmd: %08x PRSSTAT: %08x\n", cmd, getreg32(IMXRT_USDHC1_PRSSTAT)); return -EBUSY; @@ -1823,15 +1772,39 @@ static int imxrt_sendcmd(FAR struct sdio_dev_s *dev, uint32_t cmd, putreg32(mcrregval, IMXRT_USDHC1_MIX); putreg32(regval, IMXRT_USDHC1_XFERTYP); - start = 0; - while ((getreg32(IMXRT_USDHC1_PRSSTAT) & USDHC_PRSSTAT_CIHB) != 0) - { - start++; - } - return OK; } +/**************************************************************************** + * Name: imxrt_blocksetup + * + * Description: + * Configure block size and the number of blocks for next transfer + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * blocklen - The selected block size. + * nblocklen - The number of blocks to transfer + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_SDIO_BLOCKSETUP +static void imxrt_blocksetup(FAR struct sdio_dev_s *dev, + unsigned int blocklen, unsigned int nblocks) +{ + mcinfo("blocklen=%ld, total transfer=%ld (%ld blocks)\n", + blocklen, blocklen * nblocks, nblocks); + + /* Configure block size for next transfer */ + + putreg32(USDHC_BLKATTR_SIZE(blocklen) | USDHC_BLKATTR_CNT(nblocks), + IMXRT_USDHC1_BLKATTR); +} +#endif + /**************************************************************************** * Name: imxrt_recvsetup * @@ -1864,7 +1837,6 @@ static int imxrt_recvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, /* Reset the DPSM configuration */ - imxrt_datadisable(); imxrt_sampleinit(); imxrt_sample(priv, SAMPLENDX_BEFORE_SETUP); @@ -1875,7 +1847,7 @@ static int imxrt_recvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, /* Then set up the SDIO data path */ - imxrt_dataconfig(priv, false, nbytes, 1, USDHC_DTOCV_MAXTIMEOUT); + imxrt_dataconfig(priv, false, nbytes, USDHC_DTOCV_MAXTIMEOUT); /* And enable interrupts */ @@ -1915,7 +1887,6 @@ static int imxrt_sendsetup(FAR struct sdio_dev_s *dev, /* Reset the DPSM configuration */ - imxrt_datadisable(); imxrt_sampleinit(); imxrt_sample(priv, SAMPLENDX_BEFORE_SETUP); @@ -1926,7 +1897,7 @@ static int imxrt_sendsetup(FAR struct sdio_dev_s *dev, /* Then set up the SDIO data path */ - imxrt_dataconfig(priv, true, nbytes, 1, USDHC_DTOCV_MAXTIMEOUT); + imxrt_dataconfig(priv, true, nbytes, USDHC_DTOCV_MAXTIMEOUT); /* Enable TX interrupts */ @@ -2019,31 +1990,31 @@ static int imxrt_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd) switch (cmd & MMCSD_RESPONSE_MASK) { - case MMCSD_NO_RESPONSE: - timeout = USDHC_CMDTIMEOUT; - errors = 0; - return OK; + case MMCSD_NO_RESPONSE: + timeout = USDHC_CMDTIMEOUT; + errors = 0; + return OK; - case MMCSD_R1_RESPONSE: - case MMCSD_R1B_RESPONSE: - case MMCSD_R2_RESPONSE: - case MMCSD_R6_RESPONSE: - timeout = USDHC_LONGTIMEOUT; - errors = USDHC_RESPERR_INTS; - break; + case MMCSD_R1_RESPONSE: + case MMCSD_R1B_RESPONSE: + case MMCSD_R2_RESPONSE: + case MMCSD_R6_RESPONSE: + timeout = USDHC_LONGTIMEOUT; + errors = USDHC_RESPERR_INTS; + break; - case MMCSD_R4_RESPONSE: - case MMCSD_R5_RESPONSE: - return -ENOSYS; + case MMCSD_R4_RESPONSE: + case MMCSD_R5_RESPONSE: + return -ENOSYS; - case MMCSD_R3_RESPONSE: - case MMCSD_R7_RESPONSE: - timeout = USDHC_CMDTIMEOUT; - errors = USDHC_RESPERR_INTS; - break; + case MMCSD_R3_RESPONSE: + case MMCSD_R7_RESPONSE: + timeout = USDHC_CMDTIMEOUT; + errors = USDHC_RESPERR_INTS; + break; - default: - return -EINVAL; + default: + return -EINVAL; } /* Then wait for the Command Complete (CC) indication (or timeout). The @@ -2097,9 +2068,9 @@ static int imxrt_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd) * * Returned Value: * Number of bytes sent on success; a negated errno on failure. Here a - * failure means only a faiure to obtain the requested reponse (due to + * failure means only a failure to obtain the requested response (due to * transport problem -- timeout, CRC, etc.). The implementation only - * assures that the response is returned intacta and does not check errors + * assures that the response is returned intact and does not check errors * within the response itself. * ****************************************************************************/ @@ -2554,10 +2525,6 @@ static int imxrt_dmarecvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, DEBUGASSERT(priv != NULL && buffer != NULL && buflen > 0); DEBUGASSERT(((uint32_t)buffer & 3) == 0); - /* Reset the DPSM configuration */ - - imxrt_datadisable(); - /* Begin sampling register values */ imxrt_sampleinit(); @@ -2570,7 +2537,7 @@ static int imxrt_dmarecvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, /* Then set up the SDIO data path */ - imxrt_dataconfig(priv, false, buflen, 1, USDHC_DTOCV_MAXTIMEOUT); + imxrt_dataconfig(priv, false, buflen, USDHC_DTOCV_MAXTIMEOUT); /* Configure the RX DMA */ @@ -2612,10 +2579,6 @@ static int imxrt_dmasendsetup(FAR struct sdio_dev_s *dev, DEBUGASSERT(priv != NULL && buffer != NULL && buflen > 0); DEBUGASSERT(((uint32_t)buffer & 3) == 0); - /* Reset the DPSM configuration */ - - imxrt_datadisable(); - /* Begin sampling register values */ imxrt_sampleinit(); @@ -2628,7 +2591,7 @@ static int imxrt_dmasendsetup(FAR struct sdio_dev_s *dev, /* Then set up the SDIO data path */ - imxrt_dataconfig(priv, true, buflen, 1, USDHC_DTOCV_MAXTIMEOUT); + imxrt_dataconfig(priv, true, buflen, USDHC_DTOCV_MAXTIMEOUT); /* Configure the TX DMA */ @@ -2710,14 +2673,18 @@ static void imxrt_callback(void *arg) { /* Yes.. queue it */ - mcinfo("Queuing callback to %p(%p)\n", priv->callback, priv->cbarg); - (void)work_queue(HPWORK, &priv->cbwork, (worker_t)priv->callback, priv->cbarg, 0); + mcinfo("Queuing callback to %p(%p)\n", + priv->callback, priv->cbarg); + + (void)work_queue(HPWORK, &priv->cbwork, (worker_t)priv->callback, + priv->cbarg, 0); } else { /* No.. then just call the callback here */ mcinfo("Callback to %p(%p)\n", priv->callback, priv->cbarg); + priv->callback(priv->cbarg); } } @@ -2774,33 +2741,33 @@ FAR struct sdio_dev_s *imxrt_usdhc_initialize(int slotno) #ifndef CONFIG_SDIO_MUXBUS /* Data width 1, 4 or 8 */ - (void)imxrt_config_gpio(PIN_USDHC1_D0 | PADCTL_USDHC1_DATAX); + (void)imxrt_config_gpio(PIN_USDHC1_D0 | PINSET_USDHC1_DATAX); /* Data width 4 or 8 */ #ifndef CONFIG_IMXRT_USDHC_WIDTH_D1_ONLY - (void)imxrt_config_gpio(PIN_USDHC1_D1 | PADCTL_USDHC1_DATAX); - (void)imxrt_config_gpio(PIN_USDHC1_D2 | PADCTL_USDHC1_DATAX); - (void)imxrt_config_gpio(PIN_USDHC1_D3 | PADCTL_USDHC1_DATAX); + (void)imxrt_config_gpio(PIN_USDHC1_D1 | PINSET_USDHC1_DATAX); + (void)imxrt_config_gpio(PIN_USDHC1_D2 | PINSET_USDHC1_DATAX); + (void)imxrt_config_gpio(PIN_USDHC1_D3 | PINSET_USDHC1_DATAX); /* Data width 8 (not supported) */ #if 0 - (void)imxrt_config_gpio(PIN_USDHC1_D4 | PADCTL_USDHC1_DATAX); - (void)imxrt_config_gpio(PIN_USDHC1_D5 | PADCTL_USDHC1_DATAX); - (void)imxrt_config_gpio(PIN_USDHC1_D6 | PADCTL_USDHC1_DATAX); - (void)imxrt_config_gpio(PIN_USDHC1_D7 | PADCTL_USDHC1_DATAX); + (void)imxrt_config_gpio(PIN_USDHC1_D4 | PINSET_USDHC1_DATAX); + (void)imxrt_config_gpio(PIN_USDHC1_D5 | PINSET_USDHC1_DATAX); + (void)imxrt_config_gpio(PIN_USDHC1_D6 | PINSET_USDHC1_DATAX); + (void)imxrt_config_gpio(PIN_USDHC1_D7 | PINSET_USDHC1_DATAX); #endif #endif /* Clocking and CMD pins (all data widths) */ - (void)imxrt_config_gpio(PIN_USDHC1_DCLK | PADCTL_USDHC1_CLK); - (void)imxrt_config_gpio(PIN_USDHC1_CMD | PADCTL_USDHC1_CMD); + (void)imxrt_config_gpio(PIN_USDHC1_DCLK | PINSET_USDHC1_CLK); + (void)imxrt_config_gpio(PIN_USDHC1_CMD | PINSET_USDHC1_CMD); #endif #if defined(CONFIG_MMCSD_HAVE_CARDDETECT) && defined(PIN_USDHC1_CD) - (void)imxrt_config_gpio(PIN_USDHC1_CD | PADCTL_USDHC1_CD); + (void)imxrt_config_gpio(PIN_USDHC1_CD | PINSET_USDHC1_CD); /* Daisy chain select the CD pin */ diff --git a/configs/imxrt1050-evk/include/board.h b/configs/imxrt1050-evk/include/board.h index 6180a54985..af41390d69 100644 --- a/configs/imxrt1050-evk/include/board.h +++ b/configs/imxrt1050-evk/include/board.h @@ -108,6 +108,7 @@ (BOARD_XTAL_FREQUENCY * (IMXRT_ARM_PLL_DIV_SELECT / 2)) / IMXRT_ARM_PODF_DIVIDER /* LED definitions ******************************************************************/ + /* There are four LED status indicators located on the EVK Board. The functions of * these LEDs include: * @@ -156,6 +157,7 @@ */ /* Button definitions ***************************************************************/ + /* The IMXRT board has one external user button * * 1. SW8 (IRQ88) GPIO5-00 @@ -167,20 +169,23 @@ /* SDIO *****************************************************************************/ -/* Pin drive characteristics - drive strength in particular may need tuning for specific boards */ +/* Pin drive characteristics - drive strength in particular may need tuning for + * specific boards. + */ -#define PADCTL_USDHC1_DATAX (PADCTL_SRE|PADCTL_DSE_60OHM|PADCTL_HYS) -#define PADCTL_USDHC1_CMD PADCTL_USDHC1_DATAX -#define PADCTL_USDHC1_CLK (PADCTL_SRE|PADCTL_DSE_60OHM|PADCTL_SPEED_MAX) -#define PADCTL_USDHC1_CD (0) +#define PINSET_USDHC1_DATAX (IOMUX_SLEW_FAST | IOMUX_DRIVE_60OHM | \ + IOMUX_PULL_UP_47K | IOMUX_SCHMITT_TRIGGER) +#define PINSET_USDHC1_CMD (PINSET_USDHC1_DATAX) +#define PINSET_USDHC1_CLK (IOMUX_SLEW_FAST | IOMUX_DRIVE_60OHM | IOMUX_SPEED_MAX) +#define PINSET_USDHC1_CD (0) -#define PIN_USDHC1_D0 GPIO_USDHC1_DATA0 -#define PIN_USDHC1_D1 GPIO_USDHC1_DATA1 -#define PIN_USDHC1_D2 GPIO_USDHC1_DATA2 -#define PIN_USDHC1_D3 GPIO_USDHC1_DATA3 -#define PIN_USDHC1_DCLK GPIO_USDHC1_CLK -#define PIN_USDHC1_CMD GPIO_USDHC1_CMD -#define PIN_USDHC1_CD GPIO_USDHC1_CD_2 +#define PIN_USDHC1_D0 GPIO_USDHC1_DATA0 +#define PIN_USDHC1_D1 GPIO_USDHC1_DATA1 +#define PIN_USDHC1_D2 GPIO_USDHC1_DATA2 +#define PIN_USDHC1_D3 GPIO_USDHC1_DATA3 +#define PIN_USDHC1_DCLK GPIO_USDHC1_CLK +#define PIN_USDHC1_CMD GPIO_USDHC1_CMD +#define PIN_USDHC1_CD GPIO_USDHC1_CD_2 /* 386 KHz for initial inquiry stuff */ @@ -190,15 +195,16 @@ /* 24.8MHz for other modes */ #define BOARD_USDHC_MMCMODE_PRESCALER USDHC_SYSCTL_SDCLKFS_DIV8 -#define BOARD_USDHC_MMCMODE_DIVISOR USDHC_SYSCTL_DVS_DIV(1) +#define BOARD_USDHC_MMCMODE_DIVISOR USDHC_SYSCTL_DVS_DIV(4) // FIXME 1 #define BOARD_USDHC_SD1MODE_PRESCALER USDHC_SYSCTL_SDCLKFS_DIV8 -#define BOARD_USDHC_SD1MODE_DIVISOR USDHC_SYSCTL_DVS_DIV(1) +#define BOARD_USDHC_SD1MODE_DIVISOR USDHC_SYSCTL_DVS_DIV(4) // FIXME 1 #define BOARD_USDHC_SD4MODE_PRESCALER USDHC_SYSCTL_SDCLKFS_DIV8 -#define BOARD_USDHC_SD4MODE_DIVISOR USDHC_SYSCTL_DVS_DIV(1) +#define BOARD_USDHC_SD4MODE_DIVISOR USDHC_SYSCTL_DVS_DIV(4) // FIXME 1 /* PIO Disambiguation ***************************************************************/ + /* LPUARTs * * Virtual console port provided by OpenSDA: