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"
default n
select ARCH_HAVE_SDIO
select SDIO_BLOCKSETUP
depends on EXPERIMENTAL
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,
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",
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)
{
struct lpc43_dev_s *priv = (struct lpc43_dev_s *)dev;
uint32_t blocksize;
uint32_t bytecnt;
#ifdef CONFIG_LPC43_SDMMC_DMA
uint32_t regval;
#endif
mcinfo("nbytes=%ld\n", (long) nbytes);
DEBUGASSERT(priv != NULL && buffer != NULL && nbytes > 0);

View File

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

View File

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

View File

@ -124,6 +124,10 @@
# error "Callback support requires CONFIG_SCHED_WORKQUEUE"
#endif
#ifndef CONFIG_SDIO_BLOCKSETUP
# error "Driver requires CONFIG_SDIO_BLOCKSETUP to be set"
#endif
/* Timing */
#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,
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,
size_t nbytes);
static int lpc54_sendsetup(FAR struct sdio_dev_s *dev,
@ -367,6 +375,9 @@ struct lpc54_dev_s g_scard_dev =
.clock = lpc54_clock,
.attach = lpc54_attach,
.sendcmd = lpc54_sendcmd,
#ifdef CONFIG_SDIO_BLOCKSETUP
.blocksetup = lpc54_blocksetup,
#endif
.recvsetup = lpc54_recvsetup,
.sendsetup = lpc54_sendsetup,
.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;
#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);
return priv->cdstatus;
@ -1648,6 +1670,36 @@ static int lpc54_sendcmd(FAR struct sdio_dev_s *dev, uint32_t cmd,
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
*
@ -1673,8 +1725,6 @@ static int lpc54_recvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer,
size_t nbytes)
{
struct lpc54_dev_s *priv = (struct lpc54_dev_s *)dev;
uint32_t blocksize;
uint32_t bytecnt;
#ifdef CONFIG_LPC54_SDMMC_DMA
uint32_t regval;
#endif
@ -1693,23 +1743,6 @@ static int lpc54_recvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer,
priv->dmamode = false;
#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
* 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();
/* 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.
* Here we just leave these at the default settings.
*/
/* Initialize semaphores */