arch/arm/src/lpc54/lpc54_sdmmc: Port Dave Marple's LPC43 USB DCD fix to the LPC54 with appropriate changed.

This commit is contained in:
Gregory Nutt 2018-10-21 17:55:51 -06:00
parent b71e0a199a
commit 4b0327d845
5 changed files with 62 additions and 26 deletions

View File

@ -255,6 +255,7 @@ config LPC43_SDMMC
bool "SD/MMC" bool "SD/MMC"
default n default n
select ARCH_HAVE_SDIO select ARCH_HAVE_SDIO
select SDIO_BLOCKSETUP
depends on EXPERIMENTAL depends on EXPERIMENTAL
config LPC43_SPI config LPC43_SPI

View File

@ -1690,8 +1690,6 @@ static int lpc43_sendcmd(FAR struct sdio_dev_s *dev, uint32_t cmd,
static void lpc43_blocksetup(FAR struct sdio_dev_s *dev, static void lpc43_blocksetup(FAR struct sdio_dev_s *dev,
unsigned int blocklen, unsigned int nblocks) unsigned int blocklen, unsigned int nblocks)
{ {
struct stm32_dev_s *priv = (struct stm32_dev_s *)dev;
mcinfo("blocklen=%ld, total transfer=%ld (%ld blocks)\n", mcinfo("blocklen=%ld, total transfer=%ld (%ld blocks)\n",
blocklen, blocklen*nblocks, nblocks); blocklen, blocklen*nblocks, nblocks);
@ -1727,11 +1725,10 @@ static int lpc43_recvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer,
size_t nbytes) size_t nbytes)
{ {
struct lpc43_dev_s *priv = (struct lpc43_dev_s *)dev; struct lpc43_dev_s *priv = (struct lpc43_dev_s *)dev;
uint32_t blocksize;
uint32_t bytecnt;
#ifdef CONFIG_LPC43_SDMMC_DMA #ifdef CONFIG_LPC43_SDMMC_DMA
uint32_t regval; uint32_t regval;
#endif #endif
mcinfo("nbytes=%ld\n", (long) nbytes); mcinfo("nbytes=%ld\n", (long) nbytes);
DEBUGASSERT(priv != NULL && buffer != NULL && nbytes > 0); DEBUGASSERT(priv != NULL && buffer != NULL && nbytes > 0);

View File

@ -426,6 +426,7 @@ config LPC54_SDMMC
bool "SD/MMC" bool "SD/MMC"
default n default n
select ARCH_HAVE_SDIO select ARCH_HAVE_SDIO
select SDIO_BLOCKSETUP
depends on EXPERIMENTAL depends on EXPERIMENTAL
config LPC54_WWDT config LPC54_WWDT

View File

@ -737,8 +737,11 @@
#define SYSCON_SDIOCLKCTRL_CCLK_SMPDLYACTIVE (1 << 31) /* Bit 31: Enables sample delay */ #define SYSCON_SDIOCLKCTRL_CCLK_SMPDLYACTIVE (1 << 31) /* Bit 31: Enables sample delay */
/* FRO oscillator control */ /* FRO oscillator control */
#define SYSCON_FROCTRL_ #define SYSCON_FROCTRL_
/* System oscillator control */ /* System oscillator control */
#define SYSCON_SYSOSCCTRL_ #define SYSCON_SYSOSCCTRL_
/* Watchdog oscillator control */ /* Watchdog oscillator control */

View File

@ -124,6 +124,10 @@
# error "Callback support requires CONFIG_SCHED_WORKQUEUE" # error "Callback support requires CONFIG_SCHED_WORKQUEUE"
#endif #endif
#ifndef CONFIG_SDIO_BLOCKSETUP
# error "Driver requires CONFIG_SDIO_BLOCKSETUP to be set"
#endif
/* Timing */ /* Timing */
#define SDCARD_CMDTIMEOUT (10000) #define SDCARD_CMDTIMEOUT (10000)
@ -312,6 +316,10 @@ static int lpc54_attach(FAR struct sdio_dev_s *dev);
static int lpc54_sendcmd(FAR struct sdio_dev_s *dev, uint32_t cmd, static int lpc54_sendcmd(FAR struct sdio_dev_s *dev, uint32_t cmd,
uint32_t arg); uint32_t arg);
#ifdef CONFIG_SDIO_BLOCKSETUP
static void lpc54_blocksetup(FAR struct sdio_dev_s *dev,
unsigned int blocklen, unsigned int nblocks);
#endif
static int lpc54_recvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, static int lpc54_recvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer,
size_t nbytes); size_t nbytes);
static int lpc54_sendsetup(FAR struct sdio_dev_s *dev, static int lpc54_sendsetup(FAR struct sdio_dev_s *dev,
@ -367,6 +375,9 @@ struct lpc54_dev_s g_scard_dev =
.clock = lpc54_clock, .clock = lpc54_clock,
.attach = lpc54_attach, .attach = lpc54_attach,
.sendcmd = lpc54_sendcmd, .sendcmd = lpc54_sendcmd,
#ifdef CONFIG_SDIO_BLOCKSETUP
.blocksetup = lpc54_blocksetup,
#endif
.recvsetup = lpc54_recvsetup, .recvsetup = lpc54_recvsetup,
.sendsetup = lpc54_sendsetup, .sendsetup = lpc54_sendsetup,
.cancel = lpc54_cancel, .cancel = lpc54_cancel,
@ -1395,6 +1406,17 @@ static sdio_statset_t lpc54_status(FAR struct sdio_dev_s *dev)
{ {
struct lpc54_dev_s *priv = (struct lpc54_dev_s *)dev; struct lpc54_dev_s *priv = (struct lpc54_dev_s *)dev;
#ifdef CONFIG_MMCSD_HAVE_CARDDETECT
if ((lpc54_getreg(LPC54_SDMMC_CDETECT) & SDMMC_CDETECT_NOTPRESENT) == 0)
{
priv->cdstatus |= SDIO_STATUS_PRESENT;
}
else
{
priv->cdstatus &= ~SDIO_STATUS_PRESENT;
}
#endif
mcinfo("cdstatus=%02x\n", priv->cdstatus); mcinfo("cdstatus=%02x\n", priv->cdstatus);
return priv->cdstatus; return priv->cdstatus;
@ -1648,6 +1670,36 @@ static int lpc54_sendcmd(FAR struct sdio_dev_s *dev, uint32_t cmd,
return OK; return OK;
} }
/****************************************************************************
* Name: lpc54_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 lpc54_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 */
lpc54_putreg(blocklen, LPC54_SDMMC_BLKSIZ);
lpc54_putreg(blocklen * nblocks, LPC54_SDMMC_BYTCNT);
}
#endif
/**************************************************************************** /****************************************************************************
* Name: lpc54_recvsetup * Name: lpc54_recvsetup
* *
@ -1673,8 +1725,6 @@ static int lpc54_recvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer,
size_t nbytes) size_t nbytes)
{ {
struct lpc54_dev_s *priv = (struct lpc54_dev_s *)dev; struct lpc54_dev_s *priv = (struct lpc54_dev_s *)dev;
uint32_t blocksize;
uint32_t bytecnt;
#ifdef CONFIG_LPC54_SDMMC_DMA #ifdef CONFIG_LPC54_SDMMC_DMA
uint32_t regval; uint32_t regval;
#endif #endif
@ -1693,23 +1743,6 @@ static int lpc54_recvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer,
priv->dmamode = false; priv->dmamode = false;
#endif #endif
/* Then set up the SD card data path */
if (nbytes < 64)
{
blocksize = nbytes;
bytecnt = nbytes;
}
else
{
blocksize = 64;
bytecnt = nbytes;
DEBUGASSERT((nbytes & 0x3f) == 0);
}
lpc54_putreg(blocksize, LPC54_SDMMC_BLKSIZ);
lpc54_putreg(bytecnt, LPC54_SDMMC_BYTCNT);
/* Configure the FIFO so that we will receive the RXDR interrupt whenever /* Configure the FIFO so that we will receive the RXDR interrupt whenever
* there are more than 1 words (at least 8 bytes) in the RX FIFO. * there are more than 1 words (at least 8 bytes) in the RX FIFO.
*/ */
@ -2739,8 +2772,9 @@ FAR struct sdio_dev_s *lpc54_sdmmc_initialize(int slotno)
lpc54_sdmmc_enableclk(); lpc54_sdmmc_enableclk();
/* REVISIT: The delay values on the sample and drive inputs and outputs /* The delay values on the sample and drive inputs and outputs
* can be adjusted using the SDIOCLKCTRL register in the SYSCON block. * can be adjusted using the SDIOCLKCTRL register in the SYSCON block.
* Here we just leave these at the default settings.
*/ */
/* Initialize semaphores */ /* Initialize semaphores */