arch/arm/src/stm32f7/stm32_sdmmc.c: Add SDIO coard support.
This commit is contained in:
parent
30657b769f
commit
f39c611d64
@ -666,6 +666,22 @@ config STM32F7_STM32F722XX
|
||||
select STM32F7_HAVE_CRYP
|
||||
select STM32F7_HAVE_SDMMC2 if !STM32F7_IO_CONFIG_R
|
||||
|
||||
config STM32F7_STM32F723XX
|
||||
bool
|
||||
default n
|
||||
select STM32F7_STM32F72XX
|
||||
select ARCH_HAVE_FPU
|
||||
select ARMV7M_HAVE_ICACHE
|
||||
select ARMV7M_HAVE_DCACHE
|
||||
select ARMV7M_HAVE_ITCM
|
||||
select ARMV7M_HAVE_DTCM
|
||||
select STM32F7_HAVE_FMC
|
||||
select STM32F7_HAVE_RNG
|
||||
select STM32F7_HAVE_SPI4 if !STM32F7_IO_CONFIG_R
|
||||
select STM32F7_HAVE_SPI5 if !(STM32F7_IO_CONFIG_R || STM32F7_IO_CONFIG_V)
|
||||
select STM32F7_HAVE_CRYP
|
||||
select STM32F7_HAVE_SDMMC2 if !STM32F7_IO_CONFIG_R
|
||||
|
||||
config STM32F7_STM32F745XX
|
||||
bool
|
||||
default n
|
||||
@ -2000,6 +2016,22 @@ config SDMMC1_WIDTH_D1_ONLY
|
||||
---help---
|
||||
Select 1-bit transfer mode. Default: 4-bit transfer mode.
|
||||
|
||||
config SDMMC1_SDIO_MODE
|
||||
bool "SDIO Card Support"
|
||||
default n
|
||||
---help---
|
||||
Build in additional support needed only for SDIO cards (vs. SD
|
||||
memory cards)
|
||||
|
||||
config SDMMC1_SDIO_PULLUP
|
||||
bool "Enable internal Pull-Ups"
|
||||
default n
|
||||
---help---
|
||||
If you are using an external SDCard module that does not have the
|
||||
pull-up resistors for the SDIO interface (like the Gadgeteer SD Card
|
||||
Module) then enable this option to activate the internal pull-up
|
||||
resistors.
|
||||
|
||||
endmenu # "SDMMC1 Configuration"
|
||||
|
||||
menu "SDMMC2 Configuration"
|
||||
@ -2027,6 +2059,22 @@ config SDMMC2_WIDTH_D1_ONLY
|
||||
---help---
|
||||
Select 1-bit transfer mode. Default: 4-bit transfer mode.
|
||||
|
||||
config SDMMC2_SDIO_MODE
|
||||
bool "SDIO Card Support"
|
||||
default n
|
||||
---help---
|
||||
Build in additional support needed only for SDIO cards (vs. SD
|
||||
memory cards)
|
||||
|
||||
config SDMMC2_SDIO_PULLUP
|
||||
bool "Enable internal Pull-Ups"
|
||||
default n
|
||||
---help---
|
||||
If you are using an external SDCard module that does not have the
|
||||
pull-up resistors for the SDIO interface (like the Gadgeteer SD Card
|
||||
Module) then enable this option to activate the internal pull-up
|
||||
resistors.
|
||||
|
||||
endmenu # "SDMMC2 Configuration"
|
||||
endmenu # "SD/MMC Configuration"
|
||||
|
||||
|
@ -97,8 +97,17 @@
|
||||
* important since interrupt nesting is not currently supported.
|
||||
* CONFIG_SDMMMC_DMAPRIO - SDMMC DMA priority. This can be selecte if
|
||||
* CONFIG_STM32F7_SDMMC_DMA is enabled.
|
||||
* CONFIG_CONFIG_STM32F7_SDMMC_XFRDEBUG - Enables some very low-level debug output
|
||||
* This also requires CONFIG_DEBUG_FS and CONFIG_DEBUG_INFO
|
||||
* CONFIG_CONFIG_STM32F7_SDMMC_XFRDEBUG - Enables some very low-level debug
|
||||
* output. This also requires CONFIG_DEBUG_FS and CONFIG_DEBUG_INFO
|
||||
*
|
||||
* CONFIG_SDMMC1/2_SDIO_MODE
|
||||
* Build ins additional support needed only for SDIO cards (vs. SD memory
|
||||
* cards)
|
||||
* CONFIG_SDMMC1/2_SDIO_PULLUP
|
||||
* If you are using an external SDCard module that does not have the
|
||||
* pull-up resistors for the SDIO interface (like the Gadgeteer SD Card
|
||||
* Module) then enable this option to activate the internal pull-up
|
||||
* resistors.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_STM32F7_SDMMC_DMA
|
||||
@ -150,6 +159,11 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#undef HAVE_SDMMC_SDIO_MODE
|
||||
#if defined(CONFIG_SDMMC1_SDIO_MODE) || defined(CONFIG_SDMMC2_SDIO_MODE)
|
||||
# define HAVE_SDMMC_SDIO_MODE
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_DEBUG_FS) || !defined(CONFIG_DEBUG_FEATURES)
|
||||
# undef CONFIG_CONFIG_STM32F7_SDMMC_XFRDEBUG
|
||||
#endif
|
||||
@ -389,8 +403,18 @@ struct stm32_dev_s
|
||||
DMA_HANDLE dma; /* Handle for DMA channel */
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SDMMC_SDIO_MODE
|
||||
/* Interrupt at SDIO_D1 pin, only for SDIO cards */
|
||||
|
||||
uint32_t sdiointmask; /* STM32 SDIO register mask */
|
||||
int (*do_sdio_card)(void *); /* SDIO card ISR */
|
||||
void *do_sdio_arg; /* arg for SDIO card ISR */
|
||||
bool sdiomode; /* True: in SDIO mode */
|
||||
#endif
|
||||
|
||||
/* Misc */
|
||||
|
||||
uint32_t pullup; /* GPIO pull-up option */
|
||||
uint32_t blocksize; /* Current block size */
|
||||
};
|
||||
|
||||
@ -575,8 +599,8 @@ struct stm32_dev_s g_sdmmcdev1 =
|
||||
.recvR1 = stm32_recvshortcrc,
|
||||
.recvR2 = stm32_recvlong,
|
||||
.recvR3 = stm32_recvshort,
|
||||
.recvR4 = stm32_recvnotimpl,
|
||||
.recvR5 = stm32_recvnotimpl,
|
||||
.recvR4 = stm32_recvshort,
|
||||
.recvR5 = stm32_recvshortcrc,
|
||||
.recvR6 = stm32_recvshortcrc,
|
||||
.recvR7 = stm32_recvshort,
|
||||
.waitenable = stm32_waitenable,
|
||||
@ -610,8 +634,24 @@ struct stm32_dev_s g_sdmmcdev1 =
|
||||
#ifdef CONFIG_STM32F7_SDMMC1_DMAPRIO
|
||||
.dmapri = CONFIG_STM32F7_SDMMC1_DMAPRIO,
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SDMMC_SDIO_MODE
|
||||
#ifdef CONFIG_SDMMC1_SDIO_MODE
|
||||
.sdiomode = true,
|
||||
#else
|
||||
.sdiomode = false,
|
||||
#endif
|
||||
.do_sdio_card = NULL,
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SDMMC1_SDIO_PULLUP
|
||||
.pullup = GPIO_PULLUP,
|
||||
#else
|
||||
.pullup = 0,
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_STM32F7_SDMMC2
|
||||
struct stm32_dev_s g_sdmmcdev2 =
|
||||
{
|
||||
@ -635,8 +675,8 @@ struct stm32_dev_s g_sdmmcdev2 =
|
||||
.recvR1 = stm32_recvshortcrc,
|
||||
.recvR2 = stm32_recvlong,
|
||||
.recvR3 = stm32_recvshort,
|
||||
.recvR4 = stm32_recvnotimpl,
|
||||
.recvR5 = stm32_recvnotimpl,
|
||||
.recvR4 = stm32_recvshort,
|
||||
.recvR5 = stm32_recvshortcrc,
|
||||
.recvR6 = stm32_recvshortcrc,
|
||||
.recvR7 = stm32_recvshort,
|
||||
.waitenable = stm32_waitenable,
|
||||
@ -662,6 +702,21 @@ struct stm32_dev_s g_sdmmcdev2 =
|
||||
#ifdef CONFIG_STM32F7_SDMMC2_DMAPRIO
|
||||
.dmapri = CONFIG_STM32F7_SDMMC2_DMAPRIO,
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SDMMC_SDIO_MODE
|
||||
#ifdef CONFIG_SDMMC2_SDIO_MODE
|
||||
.sdiomode = true,
|
||||
#else
|
||||
.sdiomode = false,
|
||||
#endif
|
||||
.do_sdio_card = NULL,
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SDMMC2_SDIO_PULLUP
|
||||
.pullup = GPIO_PULLUP,
|
||||
#else
|
||||
.pullup = 0,
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
/* Register logging support */
|
||||
@ -857,7 +912,19 @@ static void stm32_configwaitints(struct stm32_dev_s *priv, uint32_t waitmask,
|
||||
#ifdef CONFIG_STM32F7_SDMMC_DMA
|
||||
priv->xfrflags = 0;
|
||||
#endif
|
||||
sdmmc_putreg32(priv, priv->xfrmask | priv->waitmask, STM32_SDMMC_MASK_OFFSET);
|
||||
|
||||
#ifdef HAVE_SDMMC_SDIO_MODE
|
||||
if (priv->sdiomode == true)
|
||||
{
|
||||
sdmmc_putreg32(priv, priv->xfrmask | priv->waitmask | priv->sdiointmask,
|
||||
STM32_SDMMC_MASK_OFFSET);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
sdmmc_putreg32(priv, priv->xfrmask | priv->waitmask, STM32_SDMMC_MASK_OFFSET);
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
}
|
||||
|
||||
@ -881,7 +948,20 @@ static void stm32_configxfrints(struct stm32_dev_s *priv, uint32_t xfrmask)
|
||||
irqstate_t flags;
|
||||
flags = enter_critical_section();
|
||||
priv->xfrmask = xfrmask;
|
||||
sdmmc_putreg32(priv, priv->xfrmask | priv->waitmask, STM32_SDMMC_MASK_OFFSET);
|
||||
|
||||
#ifdef HAVE_SDMMC_SDIO_MODE
|
||||
if (priv->sdiomode == true
|
||||
{
|
||||
sdmmc_putreg32(priv, priv->xfrmask | priv->waitmask | priv->sdiointmask,
|
||||
STM32_SDMMC_MASK_OFFSET);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
sdmmc_putreg32(priv, priv->xfrmask | priv->waitmask,
|
||||
STM32_SDMMC_MASK_OFFSET);
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
}
|
||||
|
||||
@ -1190,7 +1270,18 @@ static void stm32_dataconfig(struct stm32_dev_s *priv, uint32_t timeout,
|
||||
STM32_SDMMC_DCTRL_DBLOCKSIZE_MASK);
|
||||
dctrl &= (STM32_SDMMC_DCTRL_DTDIR | STM32_SDMMC_DCTRL_DTMODE |
|
||||
STM32_SDMMC_DCTRL_DBLOCKSIZE_MASK);
|
||||
regval |= (dctrl | STM32_SDMMC_DCTRL_DTEN);
|
||||
|
||||
#ifdef HAVE_SDMMC_SDIO_MODE
|
||||
if (priv->sdiomode==true
|
||||
{
|
||||
regval |= (dctrl | STM32_SDMMC_DCTRL_DTEN | STM32_SDMMC_DCTRL_SDIOEN);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
regval |= (dctrl | STM32_SDMMC_DCTRL_DTEN );
|
||||
}
|
||||
|
||||
sdmmc_putreg32(priv, regval, STM32_SDMMC_DCTRL_OFFSET);
|
||||
}
|
||||
|
||||
@ -1538,6 +1629,9 @@ static int stm32_sdmmc_interrupt(int irq, void *context, void *arg)
|
||||
struct stm32_dev_s *priv =(struct stm32_dev_s *)arg;
|
||||
uint32_t enabled;
|
||||
uint32_t pending;
|
||||
#ifdef HAVE_SDMMC_SDIO_MODE
|
||||
uint32_t mask;
|
||||
#endif
|
||||
|
||||
DEBUGASSERT(priv != NULL);
|
||||
|
||||
@ -1719,6 +1813,34 @@ static int stm32_sdmmc_interrupt(int irq, void *context, void *arg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_SDMMC_SDIO_MODE
|
||||
if (priv->sdiomode == true)
|
||||
{
|
||||
pending = enabled & priv->sdiointmask;
|
||||
if (pending != 0)
|
||||
{
|
||||
mask = sdmmc_getreg32(priv, STM32_SDMMC_MASK_OFFSET);
|
||||
|
||||
/* Clear the mask so we don't get call'd again */
|
||||
|
||||
sdmmc_putreg32(priv, mask & ~STM32_SDMMC_MASK_SDIOITIE,
|
||||
STM32_SDMMC_MASK_OFFSET);
|
||||
|
||||
/* Now clear the interruption */
|
||||
|
||||
sdmmc_putreg32(priv, STM32_SDMMC_ICR_SDIOITC,
|
||||
STM32_SDMMC_ICR_OFFSET);
|
||||
|
||||
/* Call the ISR that has been registered */
|
||||
|
||||
if (priv->do_sdio_card)
|
||||
{
|
||||
priv->do_sdio_card(priv->do_sdio_arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return OK;
|
||||
@ -1785,27 +1907,30 @@ static void stm32_reset(FAR struct sdio_dev_s *dev)
|
||||
|
||||
/* Reset data */
|
||||
|
||||
priv->waitevents = 0; /* Set of events to be waited for */
|
||||
priv->waitmask = 0; /* Interrupt enables for event waiting */
|
||||
priv->wkupevent = 0; /* The event that caused the wakeup */
|
||||
priv->waitevents = 0; /* Set of events to be waited for */
|
||||
priv->waitmask = 0; /* Interrupt enables for event waiting */
|
||||
priv->wkupevent = 0; /* The event that caused the wakeup */
|
||||
#ifdef CONFIG_STM32F7_SDMMC_DMA
|
||||
priv->xfrflags = 0; /* Used to synchronize SDIO and DMA
|
||||
* completion events */
|
||||
priv->xfrflags = 0; /* Used to synchronize SDIO and DMA
|
||||
* completion events */
|
||||
#endif
|
||||
|
||||
wd_cancel(priv->waitwdog); /* Cancel any timeouts */
|
||||
|
||||
/* Interrupt mode data transfer support */
|
||||
|
||||
priv->buffer = 0; /* Address of current R/W buffer */
|
||||
priv->remaining = 0; /* Number of bytes remaining in the transfer */
|
||||
priv->xfrmask = 0; /* Interrupt enables for data transfer */
|
||||
priv->buffer = 0; /* Address of current R/W buffer */
|
||||
priv->remaining = 0; /* Number of bytes remaining in the transfer */
|
||||
priv->xfrmask = 0; /* Interrupt enables for data transfer */
|
||||
#ifdef HAVE_SDMMC_SDIO_MODE
|
||||
priv->sdiointmask = 0;
|
||||
#endif
|
||||
|
||||
/* DMA data transfer support */
|
||||
|
||||
priv->widebus = false; /* Required for DMA support */
|
||||
priv->widebus = false; /* Required for DMA support */
|
||||
#ifdef CONFIG_STM32F7_SDMMC_DMA
|
||||
priv->dmamode = false; /* true: DMA mode transfer */
|
||||
priv->dmamode = false; /* true: DMA mode transfer */
|
||||
#endif
|
||||
|
||||
/* Configure the SDIO peripheral */
|
||||
@ -2299,14 +2424,13 @@ static int stm32_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd)
|
||||
case MMCSD_R1_RESPONSE:
|
||||
case MMCSD_R1B_RESPONSE:
|
||||
case MMCSD_R2_RESPONSE:
|
||||
case MMCSD_R4_RESPONSE:
|
||||
case MMCSD_R5_RESPONSE:
|
||||
case MMCSD_R6_RESPONSE:
|
||||
events = STM32_SDMMC_RESPDONE_STA;
|
||||
timeout = SDMMC_LONGTIMEOUT;
|
||||
break;
|
||||
|
||||
case MMCSD_R4_RESPONSE:
|
||||
case MMCSD_R5_RESPONSE:
|
||||
return -ENOSYS;
|
||||
|
||||
case MMCSD_R3_RESPONSE:
|
||||
case MMCSD_R7_RESPONSE:
|
||||
@ -2401,6 +2525,7 @@ static int stm32_recvshortcrc(FAR struct sdio_dev_s *dev, uint32_t cmd,
|
||||
|
||||
else if ((cmd & MMCSD_RESPONSE_MASK) != MMCSD_R1_RESPONSE &&
|
||||
(cmd & MMCSD_RESPONSE_MASK) != MMCSD_R1B_RESPONSE &&
|
||||
(cmd & MMCSD_RESPONSE_MASK) != MMCSD_R5_RESPONSE &&
|
||||
(cmd & MMCSD_RESPONSE_MASK) != MMCSD_R6_RESPONSE)
|
||||
{
|
||||
mcerr("ERROR: Wrong response CMD=%08x\n", cmd);
|
||||
@ -2521,6 +2646,7 @@ static int stm32_recvshort(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t *r
|
||||
|
||||
#ifdef CONFIG_DEBUG_FEATURES
|
||||
if ((cmd & MMCSD_RESPONSE_MASK) != MMCSD_R3_RESPONSE &&
|
||||
(cmd & MMCSD_RESPONSE_MASK) != MMCSD_R4_RESPONSE &&
|
||||
(cmd & MMCSD_RESPONSE_MASK) != MMCSD_R7_RESPONSE)
|
||||
{
|
||||
mcerr("ERROR: Wrong response CMD=%08x\n", cmd);
|
||||
@ -3196,14 +3322,14 @@ FAR struct sdio_dev_s *sdio_initialize(int slotno)
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_SDIO_MUXBUS
|
||||
stm32_configgpio(GPIO_SDMMC1_D0);
|
||||
stm32_configgpio(GPIO_SDMMC1_D0 | priv->pullup);
|
||||
#ifndef CONFIG_SDMMC1_WIDTH_D1_ONLY
|
||||
stm32_configgpio(GPIO_SDMMC1_D1);
|
||||
stm32_configgpio(GPIO_SDMMC1_D2);
|
||||
stm32_configgpio(GPIO_SDMMC1_D3);
|
||||
stm32_configgpio(GPIO_SDMMC1_D1 | priv->pullup);
|
||||
stm32_configgpio(GPIO_SDMMC1_D2 | priv->pullup);
|
||||
stm32_configgpio(GPIO_SDMMC1_D3 | priv->pullup);
|
||||
#endif
|
||||
stm32_configgpio(GPIO_SDMMC1_CK);
|
||||
stm32_configgpio(GPIO_SDMMC1_CMD);
|
||||
stm32_configgpio(GPIO_SDMMC1_CMD | priv->pullup);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
@ -3233,14 +3359,14 @@ FAR struct sdio_dev_s *sdio_initialize(int slotno)
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_SDIO_MUXBUS
|
||||
stm32_configgpio(GPIO_SDMMC2_D0);
|
||||
stm32_configgpio(GPIO_SDMMC2_D0 | priv->pullup);
|
||||
#ifndef CONFIG_SDMMC2_WIDTH_D1_ONLY
|
||||
stm32_configgpio(GPIO_SDMMC2_D1);
|
||||
stm32_configgpio(GPIO_SDMMC2_D2);
|
||||
stm32_configgpio(GPIO_SDMMC2_D3);
|
||||
stm32_configgpio(GPIO_SDMMC2_D1 | priv->pullup);
|
||||
stm32_configgpio(GPIO_SDMMC2_D2 | priv->pullup);
|
||||
stm32_configgpio(GPIO_SDMMC2_D3 | priv->pullup);
|
||||
#endif
|
||||
stm32_configgpio(GPIO_SDMMC2_CK);
|
||||
stm32_configgpio(GPIO_SDMMC2_CMD);
|
||||
stm32_configgpio(GPIO_SDMMC2_CMD | priv->pullup);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
@ -3368,3 +3494,26 @@ void sdio_wrprotect(FAR struct sdio_dev_s *dev, bool wrprotect)
|
||||
leave_critical_section(flags);
|
||||
}
|
||||
#endif /* CONFIG_STM32F7_SDMMC1 || CONFIG_STM32F7_SDMMC2 */
|
||||
|
||||
|
||||
#ifdef HAVE_SDMMC_SDIO_MODE
|
||||
void sdio_set_sdio_card_isr(FAR struct sdio_dev_s *dev,
|
||||
int (*func)(void *), void *arg)
|
||||
{
|
||||
struct stm32_dev_s *priv = (struct stm32_dev_s *)dev;
|
||||
|
||||
priv->do_sdio_card = func;
|
||||
|
||||
if (func != NULL)
|
||||
{
|
||||
priv->sdiointmask = STM32_SDMMC_STA_SDIOIT;
|
||||
priv->do_sdio_arg = arg;
|
||||
}
|
||||
else
|
||||
{
|
||||
priv->sdiointmask = 0;
|
||||
}
|
||||
|
||||
sdmmc_putreg32(priv, priv->xfrmask | priv->waitmask | priv->sdiointmask, STM32_SDMMC_MASK_OFFSET);
|
||||
}
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user