mirror of
https://github.com/apache/nuttx.git
synced 2026-05-30 05:16:47 +08:00
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.
This commit is contained in:
committed by
Gregory Nutt
parent
a42c5e57fc
commit
50a1b9eddf
@@ -155,10 +155,12 @@
|
|||||||
/* Block Attributes Register */
|
/* Block Attributes Register */
|
||||||
|
|
||||||
#define USDHC_BLKATTR_SIZE_SHIFT (0) /* Bits 0-12: Transfer Block Size */
|
#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 */
|
/* Bits 13-15: Reserved */
|
||||||
#define USDHC_BLKATTR_CNT_SHIFT (16) /* Bits 16-31: Blocks Count For Current Transfer */
|
#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) */
|
/* Command Argument Register (32-bit cmd/arg data) */
|
||||||
|
|
||||||
@@ -346,7 +348,7 @@
|
|||||||
/* Bits 3-7: Reserved */
|
/* Bits 3-7: Reserved */
|
||||||
#define USDHC_HTCAPBLT_TCR_SHIFT (8) /* Bits 8-11: Time count retuning */
|
#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_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_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_SHIFT (14) /* bit 14-15: Retuning mode */
|
||||||
#define USDHC_HTCAPBLT_RET_MODE_MASK (3<<SDHC_HTCAPBLT_RET_MODE_SHIFT)
|
#define USDHC_HTCAPBLT_RET_MODE_MASK (3<<SDHC_HTCAPBLT_RET_MODE_SHIFT)
|
||||||
@@ -373,17 +375,17 @@
|
|||||||
|
|
||||||
#define USDHC_WML_RD_SHIFT (0) /* Bits 0-7: Read Watermark Level */
|
#define USDHC_WML_RD_SHIFT (0) /* Bits 0-7: Read Watermark Level */
|
||||||
#define USDHC_WML_RD_MASK (0xff << USDHC_WML_RDWML_SHIFT)
|
#define USDHC_WML_RD_MASK (0xff << USDHC_WML_RDWML_SHIFT)
|
||||||
#define USDHC_WML_RD(x) ((x)&0xff)<<SDHC_WML_RDWML_SHIFT)
|
# define USDHC_WML_RD(n) ((n) << SDHC_WML_RDWML_SHIFT)
|
||||||
#define USDHC_WML_RD_BL_SHIFT (8) /* Bits 8-12: Read Watermark Burst Length */
|
#define USDHC_WML_RD_BL_SHIFT (8) /* Bits 8-12: Read Watermark Burst Length */
|
||||||
#define USDHC_WML_RD_BL_MASK (0x1f << USDHC_WML_RD_BL_SHIFT)
|
#define USDHC_WML_RD_BL_MASK (0x1f << USDHC_WML_RD_BL_SHIFT)
|
||||||
#define USDHC_WML_RD_BL(x) (((x)&0x1f)<<SDHC_WML_RD_BLL_SHIFT)
|
# define USDHC_WML_RD_BL(n) ((n) << SDHC_WML_RD_BLL_SHIFT)
|
||||||
/* Bits 13-15: Reserved */
|
/* Bits 13-15: Reserved */
|
||||||
#define USDHC_WML_WR_SHIFT (16) /* Bits 16-23: Write Watermark Level */
|
#define USDHC_WML_WR_SHIFT (16) /* Bits 16-23: Write Watermark Level */
|
||||||
#define USDHC_WML_WR_MASK (0xff << USDHC_WML_WRWML_SHIFT)
|
#define USDHC_WML_WR_MASK (0xff << USDHC_WML_WRWML_SHIFT)
|
||||||
#define USDHC_WML_WR(x) ((x)&0xff)<<SDHC_WML_WRWML_SHIFT)
|
# define USDHC_WML_WR(n) ((n) << SDHC_WML_WRWML_SHIFT)
|
||||||
#define USDHC_WML_WR_BL_SHIFT (24) /* Bits 24-28: Write Watermark Burst Length */
|
#define USDHC_WML_WR_BL_SHIFT (24) /* Bits 24-28: Write Watermark Burst Length */
|
||||||
#define USDHC_WML_WR_BL_MASK (0x1f << USDHC_WML_WD_BL_SHIFT)
|
#define USDHC_WML_WR_BL_MASK (0x1f << USDHC_WML_WD_BL_SHIFT)
|
||||||
#define USDHC_WML_WR_BL(x) (((x)&0x1f)<<SDHC_WML_WD_BLL_SHIFT)
|
# define USDHC_WML_WR_BL(n) ((n) << SDHC_WML_WD_BLL_SHIFT)
|
||||||
/* Bits 29-31: Reserved */
|
/* Bits 29-31: Reserved */
|
||||||
|
|
||||||
/* Mixer Control Register */
|
/* Mixer Control Register */
|
||||||
@@ -453,22 +455,22 @@
|
|||||||
#define USDHC_DL_CTRL_SLV_FORCE_UP (1 << 2) /* Bit 2: SLV Force update */
|
#define USDHC_DL_CTRL_SLV_FORCE_UP (1 << 2) /* Bit 2: SLV Force update */
|
||||||
#define USDHC_DL_SLV_DLY_TGT0_SHIFT (3) /* Bits 3-6: Delay Target 0 */
|
#define USDHC_DL_SLV_DLY_TGT0_SHIFT (3) /* Bits 3-6: Delay Target 0 */
|
||||||
#define USDHC_DL_SLV_DLY_TGT0_MASK (0xf << USDHC_DL_SLV_DLY_TGT0_SHIFT)
|
#define USDHC_DL_SLV_DLY_TGT0_MASK (0xf << USDHC_DL_SLV_DLY_TGT0_SHIFT)
|
||||||
# define USDHC_DL_SLV_DLY_TGT0(x) (((x)&0x0f) << USDHC_DL_SLV_DLY_TGT0_SHIFT)
|
# define USDHC_DL_SLV_DLY_TGT0(n) ((n) << USDHC_DL_SLV_DLY_TGT0_SHIFT)
|
||||||
#define USDHC_DL_CTRL_SLV_UPD (1 << 7) /* Bit 7: Delay Control Gate update */
|
#define USDHC_DL_CTRL_SLV_UPD (1 << 7) /* Bit 7: Delay Control Gate update */
|
||||||
#define USDHC_DL_CTRL_SLV_OVR (1 << 8) /* Bit 8: Delay Control Gate override */
|
#define USDHC_DL_CTRL_SLV_OVR (1 << 8) /* Bit 8: Delay Control Gate override */
|
||||||
#define USDHC_DL_CTRL_OVR_VAL_SHIFT (9) /* Bits 9-15: Override Value */
|
#define USDHC_DL_CTRL_OVR_VAL_SHIFT (9) /* Bits 9-15: Override Value */
|
||||||
#define USDHC_DL_CTRL_OVR_VAL_MASK (0x7f << USDHC_DL_CTRL_OVR_VAL_SHIFT)
|
#define USDHC_DL_CTRL_OVR_VAL_MASK (0x7f << USDHC_DL_CTRL_OVR_VAL_SHIFT)
|
||||||
# define USDHC_DL_CTRL_OVR_VAL(x) (((x)&0x7f) << USDHC_DL_CTRL_OVR_VAL_SHIFT)
|
# define USDHC_DL_CTRL_OVR_VAL(n) ((n) << USDHC_DL_CTRL_OVR_VAL_SHIFT)
|
||||||
#define USDHC_DL_SLV_DLY_TGT1_SHIFT (16) /* Bits 16-18: Delay Target 1 */
|
#define USDHC_DL_SLV_DLY_TGT1_SHIFT (16) /* Bits 16-18: Delay Target 1 */
|
||||||
#define USDHC_DL_SLV_DLY_TGT1_MASK (0x7 << USDHC_DL_SLV_DLY_TGT1_SHIFT)
|
#define USDHC_DL_SLV_DLY_TGT1_MASK (0x7 << USDHC_DL_SLV_DLY_TGT1_SHIFT)
|
||||||
# define USDHC_DL_SLV_DLY_TGT1(x) (((x)&0x07) << USDHC_DL_SLV_DLY_TGT1_SHIFT)
|
# define USDHC_DL_SLV_DLY_TGT1(n) ((n) << USDHC_DL_SLV_DLY_TGT1_SHIFT)
|
||||||
/* Bit 19: Reserved */
|
/* Bit 19: Reserved */
|
||||||
#define USDHC_DL_CTRL_SLV_UPDINT_SHIFT (20) /* Bits 20-27: DLL Control SLV Update Interval */
|
#define USDHC_DL_CTRL_SLV_UPDINT_SHIFT (20) /* Bits 20-27: DLL Control SLV Update Interval */
|
||||||
#define USDHC_DL_CTRL_SLV_UPDINT_MASK (0xff << USDHC_DL_CTRL_SLV_UPDINT_SHIFT)
|
#define USDHC_DL_CTRL_SLV_UPDINT_MASK (0xff << USDHC_DL_CTRL_SLV_UPDINT_SHIFT)
|
||||||
# define USDHC_DL_CTRL_SLV_UPDINT(x) (((x)&0xff) << USDHC_DL_CTRL_SLV_UPDINT_SHIFT)
|
# define USDHC_DL_CTRL_SLV_UPDINT(n) ((n) << USDHC_DL_CTRL_SLV_UPDINT_SHIFT)
|
||||||
#define USDHC_DL_CTRL_REF_UPDINT_SHIFT (28) /* Bits 28-31: DLL Control Refernce Update Interval */
|
#define USDHC_DL_CTRL_REF_UPDINT_SHIFT (28) /* Bits 28-31: DLL Control Refernce Update Interval */
|
||||||
#define USDHC_DL_CTRL_REF_UPDINT_MASK (0xf << USDHC_DL_CTRL_REF_UPDINT_SHIFT)
|
#define USDHC_DL_CTRL_REF_UPDINT_MASK (0xf << USDHC_DL_CTRL_REF_UPDINT_SHIFT)
|
||||||
# define USDHC_DL_CTRL_REF_UPDINT(x) (((x)&0xf) << USDHC_DL_CTRL_REF_UPDINT_SHIFT)
|
# define USDHC_DL_CTRL_REF_UPDINT(n) ((n)<< USDHC_DL_CTRL_REF_UPDINT_SHIFT)
|
||||||
|
|
||||||
/* Delay Line Status */
|
/* Delay Line Status */
|
||||||
|
|
||||||
@@ -476,10 +478,10 @@
|
|||||||
#define USDHC_DL_STAT_REF_LOCK (1 << 1) /* Bit 1: Reference delay-line lock status */
|
#define USDHC_DL_STAT_REF_LOCK (1 << 1) /* Bit 1: Reference delay-line lock status */
|
||||||
#define USDHC_DL_STAT_SLV_SEL_SHIFT (2) /* Bits 2-8: Slave delay line select status */
|
#define USDHC_DL_STAT_SLV_SEL_SHIFT (2) /* Bits 2-8: Slave delay line select status */
|
||||||
#define USDHC_DL_STAT_SLV_SEL_MASK (0x7f << USDHC_DL_STAT_SLV_SEL_SHIFT)
|
#define USDHC_DL_STAT_SLV_SEL_MASK (0x7f << USDHC_DL_STAT_SLV_SEL_SHIFT)
|
||||||
# define USDHC_DL_STAT_SLV_SEL(x) (((x)&0x07f) << USDHC_DL_STAT_SLV_SEL_SHIFT)
|
# define USDHC_DL_STAT_SLV_SEL(n) ((n) << USDHC_DL_STAT_SLV_SEL_SHIFT)
|
||||||
#define USDHC_DL_STAT_REF_SEL_SHIFT (9) /* Bits 9-15: Reference delay line select taps */
|
#define USDHC_DL_STAT_REF_SEL_SHIFT (9) /* Bits 9-15: Reference delay line select taps */
|
||||||
#define USDHC_DL_STAT_REF_SEL_MASK (0x7f << USDHC_DL_STAT_REF_SEL_SHIFT)
|
#define USDHC_DL_STAT_REF_SEL_MASK (0x7f << USDHC_DL_STAT_REF_SEL_SHIFT)
|
||||||
# define USDHC_DL_STAT_REF_SEL(x) (((x)&0x07f) << USDHC_DL_STAT_REF_SEL_SHIFT)
|
# define USDHC_DL_STAT_REF_SEL(n) ((n) << USDHC_DL_STAT_REF_SEL_SHIFT)
|
||||||
/* Bits 16-31: Reserved */
|
/* Bits 16-31: Reserved */
|
||||||
|
|
||||||
/* Clk tuning control and status */
|
/* Clk tuning control and status */
|
||||||
@@ -526,14 +528,14 @@
|
|||||||
|
|
||||||
#define USDHC_TC_STARTTAP_SHIFT (0) /* Bits 0-7: Start TAP for CMD19 tuning */
|
#define USDHC_TC_STARTTAP_SHIFT (0) /* Bits 0-7: Start TAP for CMD19 tuning */
|
||||||
#define USDHC_TC_STARTTAP_MASK (0xff << USDHC_TC_STARTTAP_SHIFT)
|
#define USDHC_TC_STARTTAP_MASK (0xff << USDHC_TC_STARTTAP_SHIFT)
|
||||||
# define USDHC_TC_STARTTAP(x) (((x)&0xff) << USDHC_TC_STARTTAP_SHIFT)
|
# define USDHC_TC_STARTTAP(n) ((n) << USDHC_TC_STARTTAP_SHIFT)
|
||||||
#define USDHC_TC_COUNT_SHIFT (8) /* Bits 8-25: Count for CMD19 tuning */
|
#define USDHC_TC_COUNT_SHIFT (8) /* Bits 8-25: Count for CMD19 tuning */
|
||||||
#define USDHC_TC_COUNT_MASK (0xff << USDHC_TC_COUNT_SHIFT)
|
#define USDHC_TC_COUNT_MASK (0xff << USDHC_TC_COUNT_SHIFT)
|
||||||
# define USDHC_TC_COUNT(x) (((x)&0xff) << USDHC_TC_COUNT_SHIFT)
|
# define USDHC_TC_COUNT(n) ((n) << USDHC_TC_COUNT_SHIFT)
|
||||||
/* Bit 19: Reserved */
|
/* Bit 19: Reserved */
|
||||||
#define USDHC_TC_WINDOW_SHIFT (20) /* Bits 20-22: Tuning window */
|
#define USDHC_TC_WINDOW_SHIFT (20) /* Bits 20-22: Tuning window */
|
||||||
#define USDHC_TC_WINDOW_MASK (0x7 << USDHC_TC_WINDOWS_SHIFT)
|
#define USDHC_TC_WINDOW_MASK (0x7 << USDHC_TC_WINDOWS_SHIFT)
|
||||||
# define USDHC_TC_WINDOW(x) (((x)&7) << USDHC_TC_WINDOW_SHIFT)
|
# define USDHC_TC_WINDOW(n) ((n) << USDHC_TC_WINDOW_SHIFT)
|
||||||
/* Bit 23: Reserved */
|
/* Bit 23: Reserved */
|
||||||
#define USDHC_TC_TUNINGEN (1 << 24) /* Bit 24: Tuning enable */
|
#define USDHC_TC_TUNINGEN (1 << 24) /* Bit 24: Tuning enable */
|
||||||
/* Bits 25-31: Reserved */
|
/* Bits 25-31: Reserved */
|
||||||
|
|||||||
@@ -234,10 +234,10 @@ void imxrt_clockconfig(void)
|
|||||||
reg = getreg32(IMXRT_CCM_CSCMR1);
|
reg = getreg32(IMXRT_CCM_CSCMR1);
|
||||||
reg &= ~(CCM_CSCMR1_USDHC1_CLK_SEL | CCM_CSCMR1_USDHC2_CLK_SEL);
|
reg &= ~(CCM_CSCMR1_USDHC1_CLK_SEL | CCM_CSCMR1_USDHC2_CLK_SEL);
|
||||||
#if defined(IMXRT_USDHC1_CLK_SELECT)
|
#if defined(IMXRT_USDHC1_CLK_SELECT)
|
||||||
reg |= IMXRT_USDHC1_CLK_SELECT
|
reg |= IMXRT_USDHC1_CLK_SELECT;
|
||||||
#endif
|
#endif
|
||||||
#if defined(IMXRT_USDHC2_CLK_SELECT)
|
#if defined(IMXRT_USDHC2_CLK_SELECT)
|
||||||
reg |= IMXRT_USDHC2_CLK_SELECT
|
reg |= IMXRT_USDHC2_CLK_SELECT;
|
||||||
#endif
|
#endif
|
||||||
putreg32(reg, IMXRT_CCM_CSCMR1);
|
putreg32(reg, IMXRT_CCM_CSCMR1);
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
|
* Dave Marples <dave@marples.net>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
@@ -86,19 +87,14 @@
|
|||||||
# error "Callback support requires CONFIG_SCHED_WORKQUEUE and CONFIG_SCHED_HPWORK"
|
# error "Callback support requires CONFIG_SCHED_WORKQUEUE and CONFIG_SCHED_HPWORK"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(CONFIG_SDIO_BLOCKSETUP)
|
||||||
|
# error "CONFIG_SDIO_BLOCKSETUP is mandatory for this driver"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef CONFIG_DEBUG_MEMCARD_INFO
|
#ifndef CONFIG_DEBUG_MEMCARD_INFO
|
||||||
# undef CONFIG_SDIO_XFRDEBUG
|
# undef CONFIG_SDIO_XFRDEBUG
|
||||||
#endif
|
#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 */
|
/* Timing in ms for commands wait response */
|
||||||
|
|
||||||
#define USDHC_CMDTIMEOUT MSEC2TICK(100)
|
#define USDHC_CMDTIMEOUT MSEC2TICK(100)
|
||||||
@@ -249,9 +245,7 @@ static void imxrt_showregs(struct imxrt_dev_s *priv, const char *msg);
|
|||||||
/* Data Transfer Helpers ****************************************************/
|
/* Data Transfer Helpers ****************************************************/
|
||||||
|
|
||||||
static void imxrt_dataconfig(struct imxrt_dev_s *priv, bool bwrite,
|
static void imxrt_dataconfig(struct imxrt_dev_s *priv, bool bwrite,
|
||||||
unsigned int blocksize, unsigned int nblocks,
|
unsigned int dataLen, unsigned int timeout);
|
||||||
unsigned int timeout);
|
|
||||||
static void imxrt_datadisable(void);
|
|
||||||
#ifndef CONFIG_IMXRT_USDHC_DMA
|
#ifndef CONFIG_IMXRT_USDHC_DMA
|
||||||
static void imxrt_transmit(struct imxrt_dev_s *priv);
|
static void imxrt_transmit(struct imxrt_dev_s *priv);
|
||||||
static void imxrt_receive(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,
|
static int imxrt_sendcmd(FAR struct sdio_dev_s *dev, uint32_t cmd,
|
||||||
uint32_t arg);
|
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
|
#ifndef CONFIG_IMXRT_USDHC_DMA
|
||||||
static int imxrt_recvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer,
|
static int imxrt_recvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer,
|
||||||
size_t nbytes);
|
size_t nbytes);
|
||||||
@@ -349,6 +348,10 @@ struct imxrt_dev_s g_sdhcdev =
|
|||||||
.clock = imxrt_clock,
|
.clock = imxrt_clock,
|
||||||
.attach = imxrt_attach,
|
.attach = imxrt_attach,
|
||||||
.sendcmd = imxrt_sendcmd,
|
.sendcmd = imxrt_sendcmd,
|
||||||
|
#ifdef CONFIG_SDIO_BLOCKSETUP
|
||||||
|
.blocksetup = imxrt_blocksetup,
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef CONFIG_IMXRT_USDHC_DMA
|
#ifndef CONFIG_IMXRT_USDHC_DMA
|
||||||
.recvsetup = imxrt_recvsetup,
|
.recvsetup = imxrt_recvsetup,
|
||||||
.sendsetup = imxrt_sendsetup,
|
.sendsetup = imxrt_sendsetup,
|
||||||
@@ -459,8 +462,7 @@ static void imxrt_configwaitints(struct imxrt_dev_s *priv, uint32_t waitints,
|
|||||||
#ifdef CONFIG_IMXRT_USDHC_DMA
|
#ifdef CONFIG_IMXRT_USDHC_DMA
|
||||||
priv->xfrflags = 0;
|
priv->xfrflags = 0;
|
||||||
#endif
|
#endif
|
||||||
putreg32(priv->xfrints | priv->waitints | USDHC_INT_CINT,
|
putreg32(priv->xfrints | priv->waitints, IMXRT_USDHC1_IRQSIGEN);
|
||||||
IMXRT_USDHC1_IRQSIGEN);
|
|
||||||
leave_critical_section(flags);
|
leave_critical_section(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -485,8 +487,7 @@ static void imxrt_configxfrints(struct imxrt_dev_s *priv, uint32_t xfrints)
|
|||||||
|
|
||||||
flags = enter_critical_section();
|
flags = enter_critical_section();
|
||||||
priv->xfrints = xfrints;
|
priv->xfrints = xfrints;
|
||||||
putreg32(priv->xfrints | priv->waitints | USDHC_INT_CINT,
|
putreg32(priv->xfrints | priv->waitints, IMXRT_USDHC1_IRQSIGEN);
|
||||||
IMXRT_USDHC1_IRQSIGEN);
|
|
||||||
leave_critical_section(flags);
|
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,
|
static void imxrt_dataconfig(struct imxrt_dev_s *priv, bool bwrite,
|
||||||
unsigned int blocksize, unsigned int nblocks,
|
unsigned int dataLen, unsigned int timeout)
|
||||||
unsigned int timeout)
|
|
||||||
{
|
{
|
||||||
unsigned int watermark;
|
unsigned int watermark;
|
||||||
uint32_t regval = 0;
|
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;
|
regval |= timeout << USDHC_SYSCTL_DTOCV_SHIFT;
|
||||||
putreg32(regval, IMXRT_USDHC1_SYSCTL);
|
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 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
|
* (limited to half of the maximum watermark value). BRR will be
|
||||||
* set when the number of queued words is greater than or equal
|
* set when the number of queued words is greater than or equal
|
||||||
* to this value.
|
* to this value.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
watermark = (blocksize + 3) >> 2;
|
watermark = (dataLen + 3) >> 2;
|
||||||
if (watermark > (USDHC_MAX_WATERMARK / 2))
|
if (watermark > (USDHC_MAX_WATERMARK / 2))
|
||||||
{
|
{
|
||||||
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
|
* 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.
|
* there are non-zero bits remaining, then we have work to do here.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
mcerr("**");
|
|
||||||
regval = getreg32(IMXRT_USDHC1_IRQSIGEN);
|
regval = getreg32(IMXRT_USDHC1_IRQSIGEN);
|
||||||
enabled = getreg32(IMXRT_USDHC1_IRQSTAT) & regval;
|
enabled = getreg32(IMXRT_USDHC1_IRQSTAT) & regval;
|
||||||
|
|
||||||
mcinfo("IRQSTAT: %08x IRQSIGEN %08x enabled: %08x\n",
|
mcinfo("IRQSTAT: %08x IRQSIGEN %08x enabled: %08x\n",
|
||||||
getreg32(IMXRT_USDHC1_IRQSTAT), regval, enabled);
|
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 */
|
/* Clear all pending interrupts */
|
||||||
|
|
||||||
putreg32(enabled, IMXRT_USDHC1_IRQSTAT);
|
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;
|
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 */
|
/* 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);
|
putreg32(USDHC_INT_ALL, IMXRT_USDHC1_IRQSTATEN);
|
||||||
imxrt_datadisable();
|
|
||||||
|
|
||||||
mcinfo("SYSCTL: %08x PRSSTAT: %08x IRQSTATEN: %08x\n",
|
mcinfo("SYSCTL: %08x PRSSTAT: %08x IRQSTATEN: %08x\n",
|
||||||
getreg32(IMXRT_USDHC1_SYSCTL), getreg32(IMXRT_USDHC1_PRSSTAT),
|
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
|
/* Select the new prescaler and divisor values based on the requested mode
|
||||||
* and the settings from the board.h file.
|
* and the settings from the board.h file.
|
||||||
*
|
*
|
||||||
* TODO: Investigate using the automatically gated clocks to reduce power
|
* Clocks are automatically gated by the driver when not needed.
|
||||||
* consumption.
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
switch (rate)
|
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) */
|
case CLOCK_IDMODE : /* Initial ID mode clocking (<400KHz) */
|
||||||
mcinfo("IDMODE\n");
|
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;
|
break;
|
||||||
|
|
||||||
case CLOCK_MMC_TRANSFER : /* MMC normal operation clocking */
|
case CLOCK_MMC_TRANSFER : /* MMC normal operation clocking */
|
||||||
mcinfo("MMCTRANSFER\n");
|
mcinfo("MMCTRANSFER\n");
|
||||||
regval |= (BOARD_USDHC_MMCMODE_PRESCALER | BOARD_USDHC_MMCMODE_DIVISOR);
|
|
||||||
|
regval |= (BOARD_USDHC_MMCMODE_PRESCALER |
|
||||||
|
BOARD_USDHC_MMCMODE_DIVISOR);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CLOCK_SD_TRANSFER_1BIT : /* SD normal operation clocking (narrow
|
case CLOCK_SD_TRANSFER_1BIT : /* SD normal operation clocking (narrow
|
||||||
* 1-bit mode) */
|
* 1-bit mode) */
|
||||||
#ifndef CONFIG_IMXRT_USDHC_WIDTH_D1_ONLY
|
#ifndef CONFIG_IMXRT_USDHC_WIDTH_D1_ONLY
|
||||||
mcinfo("1BITTRANSFER\n");
|
mcinfo("1BITTRANSFER\n");
|
||||||
regval |= (BOARD_USDHC_SD1MODE_PRESCALER | BOARD_USDHC_SD1MODE_DIVISOR);
|
|
||||||
|
regval |= (BOARD_USDHC_SD1MODE_PRESCALER |
|
||||||
|
BOARD_USDHC_SD1MODE_DIVISOR);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case CLOCK_SD_TRANSFER_4BIT : /* SD normal operation clocking (wide
|
case CLOCK_SD_TRANSFER_4BIT : /* SD normal operation clocking (wide
|
||||||
* 4-bit mode) */
|
* 4-bit mode) */
|
||||||
mcinfo("4BITTRANSFER\n");
|
mcinfo("4BITTRANSFER\n");
|
||||||
regval |= (BOARD_USDHC_SD4MODE_PRESCALER | BOARD_USDHC_SD4MODE_DIVISOR);
|
|
||||||
|
regval |= (BOARD_USDHC_SD4MODE_PRESCALER |
|
||||||
|
BOARD_USDHC_SD4MODE_DIVISOR);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1657,6 +1625,7 @@ static int imxrt_attach(FAR struct sdio_dev_s *dev)
|
|||||||
* None
|
* None
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static int imxrt_sendcmd(FAR struct sdio_dev_s *dev, uint32_t cmd,
|
static int imxrt_sendcmd(FAR struct sdio_dev_s *dev, uint32_t cmd,
|
||||||
uint32_t arg)
|
uint32_t arg)
|
||||||
{
|
{
|
||||||
@@ -1667,29 +1636,13 @@ static int imxrt_sendcmd(FAR struct sdio_dev_s *dev, uint32_t cmd,
|
|||||||
uint32_t mcrregval;
|
uint32_t mcrregval;
|
||||||
uint32_t cmdidx;
|
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 */
|
/* Initialize the command index */
|
||||||
|
|
||||||
cmdidx = (cmd & MMCSD_CMDIDX_MASK) >> MMCSD_CMDIDX_SHIFT;
|
cmdidx = (cmd & MMCSD_CMDIDX_MASK) >> MMCSD_CMDIDX_SHIFT;
|
||||||
regval = cmdidx << USDHC_XFERTYP_CMDINX_SHIFT;
|
regval = cmdidx << USDHC_XFERTYP_CMDINX_SHIFT;
|
||||||
mcrregval = USDHC_MC_DEFAULTVAL;
|
mcrregval = USDHC_MC_DEFAULTVAL;
|
||||||
|
|
||||||
/* Does a data transfer accompany the command? */
|
/* Check if a data transfer accompanies the command */
|
||||||
|
|
||||||
if ((cmd & MMCSD_DATAXFR) != 0)
|
|
||||||
{
|
|
||||||
/* Yes.. Configure the data transfer */
|
|
||||||
|
|
||||||
switch (cmd & MMCSD_DATAXFR_MASK)
|
switch (cmd & MMCSD_DATAXFR_MASK)
|
||||||
{
|
{
|
||||||
@@ -1737,11 +1690,6 @@ static int imxrt_sendcmd(FAR struct sdio_dev_s *dev, uint32_t cmd,
|
|||||||
mcrregval |= USDHC_MC_MSBSEL | USDHC_MC_BCEN;
|
mcrregval |= USDHC_MC_MSBSEL | USDHC_MC_BCEN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mcrregval |= USDHC_MC_DTDSEL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Configure response type bits */
|
/* Configure response type bits */
|
||||||
|
|
||||||
@@ -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
|
* indicates that the CMD line is not in use and the USDHC can issue a
|
||||||
* SD/MMC Command using the CMD line.
|
* 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;
|
timeout = USDHC_CMDTIMEOUT;
|
||||||
@@ -1806,7 +1755,7 @@ static int imxrt_sendcmd(FAR struct sdio_dev_s *dev, uint32_t cmd,
|
|||||||
elapsed = clock_systimer() - start;
|
elapsed = clock_systimer() - start;
|
||||||
if (elapsed >= timeout)
|
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));
|
cmd, getreg32(IMXRT_USDHC1_PRSSTAT));
|
||||||
|
|
||||||
return -EBUSY;
|
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(mcrregval, IMXRT_USDHC1_MIX);
|
||||||
putreg32(regval, IMXRT_USDHC1_XFERTYP);
|
putreg32(regval, IMXRT_USDHC1_XFERTYP);
|
||||||
|
|
||||||
start = 0;
|
|
||||||
while ((getreg32(IMXRT_USDHC1_PRSSTAT) & USDHC_PRSSTAT_CIHB) != 0)
|
|
||||||
{
|
|
||||||
start++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return OK;
|
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
|
* 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 */
|
/* Reset the DPSM configuration */
|
||||||
|
|
||||||
imxrt_datadisable();
|
|
||||||
imxrt_sampleinit();
|
imxrt_sampleinit();
|
||||||
imxrt_sample(priv, SAMPLENDX_BEFORE_SETUP);
|
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 */
|
/* 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 */
|
/* And enable interrupts */
|
||||||
|
|
||||||
@@ -1915,7 +1887,6 @@ static int imxrt_sendsetup(FAR struct sdio_dev_s *dev,
|
|||||||
|
|
||||||
/* Reset the DPSM configuration */
|
/* Reset the DPSM configuration */
|
||||||
|
|
||||||
imxrt_datadisable();
|
|
||||||
imxrt_sampleinit();
|
imxrt_sampleinit();
|
||||||
imxrt_sample(priv, SAMPLENDX_BEFORE_SETUP);
|
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 */
|
/* 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 */
|
/* Enable TX interrupts */
|
||||||
|
|
||||||
@@ -2097,9 +2068,9 @@ static int imxrt_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd)
|
|||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* Number of bytes sent on success; a negated errno on failure. Here a
|
* 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
|
* 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.
|
* 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(priv != NULL && buffer != NULL && buflen > 0);
|
||||||
DEBUGASSERT(((uint32_t)buffer & 3) == 0);
|
DEBUGASSERT(((uint32_t)buffer & 3) == 0);
|
||||||
|
|
||||||
/* Reset the DPSM configuration */
|
|
||||||
|
|
||||||
imxrt_datadisable();
|
|
||||||
|
|
||||||
/* Begin sampling register values */
|
/* Begin sampling register values */
|
||||||
|
|
||||||
imxrt_sampleinit();
|
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 */
|
/* 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 */
|
/* 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(priv != NULL && buffer != NULL && buflen > 0);
|
||||||
DEBUGASSERT(((uint32_t)buffer & 3) == 0);
|
DEBUGASSERT(((uint32_t)buffer & 3) == 0);
|
||||||
|
|
||||||
/* Reset the DPSM configuration */
|
|
||||||
|
|
||||||
imxrt_datadisable();
|
|
||||||
|
|
||||||
/* Begin sampling register values */
|
/* Begin sampling register values */
|
||||||
|
|
||||||
imxrt_sampleinit();
|
imxrt_sampleinit();
|
||||||
@@ -2628,7 +2591,7 @@ static int imxrt_dmasendsetup(FAR struct sdio_dev_s *dev,
|
|||||||
|
|
||||||
/* Then set up the SDIO data path */
|
/* 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 */
|
/* Configure the TX DMA */
|
||||||
|
|
||||||
@@ -2710,14 +2673,18 @@ static void imxrt_callback(void *arg)
|
|||||||
{
|
{
|
||||||
/* Yes.. queue it */
|
/* Yes.. queue it */
|
||||||
|
|
||||||
mcinfo("Queuing callback to %p(%p)\n", priv->callback, priv->cbarg);
|
mcinfo("Queuing callback to %p(%p)\n",
|
||||||
(void)work_queue(HPWORK, &priv->cbwork, (worker_t)priv->callback, priv->cbarg, 0);
|
priv->callback, priv->cbarg);
|
||||||
|
|
||||||
|
(void)work_queue(HPWORK, &priv->cbwork, (worker_t)priv->callback,
|
||||||
|
priv->cbarg, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* No.. then just call the callback here */
|
/* 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);
|
priv->callback(priv->cbarg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2774,33 +2741,33 @@ FAR struct sdio_dev_s *imxrt_usdhc_initialize(int slotno)
|
|||||||
#ifndef CONFIG_SDIO_MUXBUS
|
#ifndef CONFIG_SDIO_MUXBUS
|
||||||
/* Data width 1, 4 or 8 */
|
/* 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 */
|
/* Data width 4 or 8 */
|
||||||
|
|
||||||
#ifndef CONFIG_IMXRT_USDHC_WIDTH_D1_ONLY
|
#ifndef CONFIG_IMXRT_USDHC_WIDTH_D1_ONLY
|
||||||
(void)imxrt_config_gpio(PIN_USDHC1_D1 | PADCTL_USDHC1_DATAX);
|
(void)imxrt_config_gpio(PIN_USDHC1_D1 | PINSET_USDHC1_DATAX);
|
||||||
(void)imxrt_config_gpio(PIN_USDHC1_D2 | PADCTL_USDHC1_DATAX);
|
(void)imxrt_config_gpio(PIN_USDHC1_D2 | PINSET_USDHC1_DATAX);
|
||||||
(void)imxrt_config_gpio(PIN_USDHC1_D3 | PADCTL_USDHC1_DATAX);
|
(void)imxrt_config_gpio(PIN_USDHC1_D3 | PINSET_USDHC1_DATAX);
|
||||||
|
|
||||||
/* Data width 8 (not supported) */
|
/* Data width 8 (not supported) */
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
(void)imxrt_config_gpio(PIN_USDHC1_D4 | PADCTL_USDHC1_DATAX);
|
(void)imxrt_config_gpio(PIN_USDHC1_D4 | PINSET_USDHC1_DATAX);
|
||||||
(void)imxrt_config_gpio(PIN_USDHC1_D5 | PADCTL_USDHC1_DATAX);
|
(void)imxrt_config_gpio(PIN_USDHC1_D5 | PINSET_USDHC1_DATAX);
|
||||||
(void)imxrt_config_gpio(PIN_USDHC1_D6 | PADCTL_USDHC1_DATAX);
|
(void)imxrt_config_gpio(PIN_USDHC1_D6 | PINSET_USDHC1_DATAX);
|
||||||
(void)imxrt_config_gpio(PIN_USDHC1_D7 | PADCTL_USDHC1_DATAX);
|
(void)imxrt_config_gpio(PIN_USDHC1_D7 | PINSET_USDHC1_DATAX);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Clocking and CMD pins (all data widths) */
|
/* Clocking and CMD pins (all data widths) */
|
||||||
|
|
||||||
(void)imxrt_config_gpio(PIN_USDHC1_DCLK | PADCTL_USDHC1_CLK);
|
(void)imxrt_config_gpio(PIN_USDHC1_DCLK | PINSET_USDHC1_CLK);
|
||||||
(void)imxrt_config_gpio(PIN_USDHC1_CMD | PADCTL_USDHC1_CMD);
|
(void)imxrt_config_gpio(PIN_USDHC1_CMD | PINSET_USDHC1_CMD);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(CONFIG_MMCSD_HAVE_CARDDETECT) && defined(PIN_USDHC1_CD)
|
#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 */
|
/* Daisy chain select the CD pin */
|
||||||
|
|
||||||
|
|||||||
@@ -108,6 +108,7 @@
|
|||||||
(BOARD_XTAL_FREQUENCY * (IMXRT_ARM_PLL_DIV_SELECT / 2)) / IMXRT_ARM_PODF_DIVIDER
|
(BOARD_XTAL_FREQUENCY * (IMXRT_ARM_PLL_DIV_SELECT / 2)) / IMXRT_ARM_PODF_DIVIDER
|
||||||
|
|
||||||
/* LED definitions ******************************************************************/
|
/* LED definitions ******************************************************************/
|
||||||
|
|
||||||
/* There are four LED status indicators located on the EVK Board. The functions of
|
/* There are four LED status indicators located on the EVK Board. The functions of
|
||||||
* these LEDs include:
|
* these LEDs include:
|
||||||
*
|
*
|
||||||
@@ -156,6 +157,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* Button definitions ***************************************************************/
|
/* Button definitions ***************************************************************/
|
||||||
|
|
||||||
/* The IMXRT board has one external user button
|
/* The IMXRT board has one external user button
|
||||||
*
|
*
|
||||||
* 1. SW8 (IRQ88) GPIO5-00
|
* 1. SW8 (IRQ88) GPIO5-00
|
||||||
@@ -167,12 +169,15 @@
|
|||||||
|
|
||||||
/* SDIO *****************************************************************************/
|
/* 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 PINSET_USDHC1_DATAX (IOMUX_SLEW_FAST | IOMUX_DRIVE_60OHM | \
|
||||||
#define PADCTL_USDHC1_CMD PADCTL_USDHC1_DATAX
|
IOMUX_PULL_UP_47K | IOMUX_SCHMITT_TRIGGER)
|
||||||
#define PADCTL_USDHC1_CLK (PADCTL_SRE|PADCTL_DSE_60OHM|PADCTL_SPEED_MAX)
|
#define PINSET_USDHC1_CMD (PINSET_USDHC1_DATAX)
|
||||||
#define PADCTL_USDHC1_CD (0)
|
#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_D0 GPIO_USDHC1_DATA0
|
||||||
#define PIN_USDHC1_D1 GPIO_USDHC1_DATA1
|
#define PIN_USDHC1_D1 GPIO_USDHC1_DATA1
|
||||||
@@ -190,15 +195,16 @@
|
|||||||
/* 24.8MHz for other modes */
|
/* 24.8MHz for other modes */
|
||||||
|
|
||||||
#define BOARD_USDHC_MMCMODE_PRESCALER USDHC_SYSCTL_SDCLKFS_DIV8
|
#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_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_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 ***************************************************************/
|
/* PIO Disambiguation ***************************************************************/
|
||||||
|
|
||||||
/* LPUARTs
|
/* LPUARTs
|
||||||
*
|
*
|
||||||
* Virtual console port provided by OpenSDA:
|
* Virtual console port provided by OpenSDA:
|
||||||
|
|||||||
Reference in New Issue
Block a user