From 41ebb6d672803a85a9f634a22961d3cfbc27637b Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 22 Oct 2018 09:35:02 -0600 Subject: [PATCH] arch/arm/src/lpc54xx/lpc54_sdmmc.c: Tested Dave Marple's LPC43 fix with the LPC54. Does not work. This commit adds support for and SDMMC errata and setting of the delay register which was missing in the previous commit. It appears that now I can read the SD card successfully, but I get CRC errors when writing to the card. --- arch/arm/src/lpc43xx/Kconfig | 1 - arch/arm/src/lpc43xx/lpc43_sdmmc.c | 2 +- arch/arm/src/lpc54xx/chip/lpc546x_pinmux.h | 20 +++++++------- arch/arm/src/lpc54xx/chip/lpc54_syscon.h | 19 ++++++++++--- arch/arm/src/lpc54xx/lpc54_sdmmc.c | 30 ++++++++++++++++----- configs/lpcxpresso-lpc54628/README.txt | 17 +++++++++++- configs/lpcxpresso-lpc54628/include/board.h | 9 +++++++ 7 files changed, 76 insertions(+), 22 deletions(-) diff --git a/arch/arm/src/lpc43xx/Kconfig b/arch/arm/src/lpc43xx/Kconfig index a33e4154be..71d2e13743 100644 --- a/arch/arm/src/lpc43xx/Kconfig +++ b/arch/arm/src/lpc43xx/Kconfig @@ -256,7 +256,6 @@ config LPC43_SDMMC default n select ARCH_HAVE_SDIO select SDIO_BLOCKSETUP - depends on EXPERIMENTAL config LPC43_SPI bool "SPI" diff --git a/arch/arm/src/lpc43xx/lpc43_sdmmc.c b/arch/arm/src/lpc43xx/lpc43_sdmmc.c index facaf0c304..6ff0343d51 100644 --- a/arch/arm/src/lpc43xx/lpc43_sdmmc.c +++ b/arch/arm/src/lpc43xx/lpc43_sdmmc.c @@ -1691,7 +1691,7 @@ static void lpc43_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); + blocklen, blocklen * nblocks, nblocks); /* Configure block size for next transfer */ diff --git a/arch/arm/src/lpc54xx/chip/lpc546x_pinmux.h b/arch/arm/src/lpc54xx/chip/lpc546x_pinmux.h index c4e6d39b57..5bfb7c66e1 100644 --- a/arch/arm/src/lpc54xx/chip/lpc546x_pinmux.h +++ b/arch/arm/src/lpc54xx/chip/lpc546x_pinmux.h @@ -757,10 +757,10 @@ #define GPIO_SD_BACKEND_PWR_1 (GPIO_ALT2 | GPIO_MODE_DIGITAL | GPIO_PORT3 | GPIO_PIN21) /* Type A */ #define GPIO_SD_BACKEND_PWR_2 (GPIO_ALT2 | GPIO_MODE_DIGITAL | GPIO_PORT5 | GPIO_PIN4) -#define GPIO_SD_CARD_DET_N_1 (GPIO_ALT2 | GPIO_MODE_DIGITAL | GPIO_PORT0 | GPIO_PIN17) -#define GPIO_SD_CARD_DET_N_2 (GPIO_ALT2 | GPIO_MODE_DIGITAL | GPIO_PORT2 | GPIO_PIN10) -#define GPIO_SD_CARD_DET_N_3 (GPIO_ALT2 | GPIO_MODE_DIGITAL | GPIO_PORT4 | GPIO_PIN22) -#define GPIO_SD_CARD_INT_N_1 (GPIO_ALT2 | GPIO_MODE_DIGITAL | GPIO_PORT3 | GPIO_PIN20) +#define GPIO_SD_CARD_DET_N_1 (GPIO_ALT2 | GPIO_MODE_DIGITAL | GPIO_SLEW_FAST | GPIO_FILTER_OFF | GPIO_PORT0 | GPIO_PIN17) +#define GPIO_SD_CARD_DET_N_2 (GPIO_ALT2 | GPIO_MODE_DIGITAL | GPIO_SLEW_FAST | GPIO_FILTER_OFF | GPIO_PORT2 | GPIO_PIN10) +#define GPIO_SD_CARD_DET_N_3 (GPIO_ALT2 | GPIO_MODE_DIGITAL | GPIO_SLEW_FAST | GPIO_FILTER_OFF | GPIO_PORT4 | GPIO_PIN22) +#define GPIO_SD_CARD_INT_N_1 (GPIO_ALT2 | GPIO_MODE_DIGITAL | GPIO_SLEW_FAST | GPIO_FILTER_OFF | GPIO_PORT3 | GPIO_PIN20) #define GPIO_SD_CARD_INT_N_2 (GPIO_ALT2 | GPIO_MODE_DIGITAL | GPIO_SLEW_FAST | GPIO_FILTER_OFF | GPIO_PORT4 | GPIO_PIN24) #define GPIO_SD_CLK_1 (GPIO_ALT2 | GPIO_MODE_DIGITAL | GPIO_SLEW_FAST | GPIO_FILTER_OFF | GPIO_PORT0 | GPIO_PIN7) #define GPIO_SD_CLK_2 (GPIO_ALT2 | GPIO_MODE_DIGITAL | GPIO_SLEW_FAST | GPIO_FILTER_OFF | GPIO_PORT1 | GPIO_PIN8) @@ -799,18 +799,18 @@ #define GPIO_SD_D7_1 (GPIO_ALT2 | GPIO_MODE_DIGITAL | GPIO_SLEW_FAST | GPIO_FILTER_OFF | GPIO_PORT1 | GPIO_PIN30) #define GPIO_SD_D7_2 (GPIO_ALT2 | GPIO_MODE_DIGITAL | GPIO_SLEW_FAST | GPIO_FILTER_OFF | GPIO_PORT3 | GPIO_PIN19) #define GPIO_SD_D7_3 (GPIO_ALT2 | GPIO_MODE_DIGITAL | GPIO_SLEW_FAST | GPIO_FILTER_OFF | GPIO_PORT5 | GPIO_PIN0) -#define GPIO_SD_POW_EN_1 (GPIO_ALT2 | GPIO_MODE_DIGITAL | GPIO_PORT0 | GPIO_PIN9) -#define GPIO_SD_POW_EN_2 (GPIO_ALT2 | GPIO_MODE_DIGITAL | GPIO_PORT2 | GPIO_PIN5) -#define GPIO_SD_POW_EN_3 (GPIO_ALT2 | GPIO_MODE_DIGITAL | GPIO_PORT4 | GPIO_PIN21) +#define GPIO_SD_POW_EN_1 (GPIO_ALT2 | GPIO_MODE_DIGITAL | GPIO_SLEW_STANDARD | GPIO_FILTER_OFF | GPIO_PORT0 | GPIO_PIN9) +#define GPIO_SD_POW_EN_2 (GPIO_ALT2 | GPIO_MODE_DIGITAL | GPIO_SLEW_STANDARD | GPIO_FILTER_OFF | GPIO_PORT2 | GPIO_PIN5) +#define GPIO_SD_POW_EN_3 (GPIO_ALT2 | GPIO_MODE_DIGITAL | GPIO_SLEW_STANDARD | GPIO_FILTER_OFF | GPIO_PORT4 | GPIO_PIN21) #define GPIO_SD_VOLT0_1 (GPIO_ALT2 | GPIO_MODE_DIGITAL | GPIO_PORT2 | GPIO_PIN11) #define GPIO_SD_VOLT0_2 (GPIO_ALT2 | GPIO_MODE_DIGITAL | GPIO_PORT5 | GPIO_PIN1) #define GPIO_SD_VOLT1_1 (GPIO_ALT2 | GPIO_MODE_DIGITAL | GPIO_PORT2 | GPIO_PIN12) #define GPIO_SD_VOLT1_2 (GPIO_ALT2 | GPIO_MODE_DIGITAL | GPIO_PORT5 | GPIO_PIN2) #define GPIO_SD_VOLT2_1 (GPIO_ALT2 | GPIO_MODE_DIGITAL | GPIO_PORT2 | GPIO_PIN13) #define GPIO_SD_VOLT2_2 (GPIO_ALT2 | GPIO_MODE_DIGITAL | GPIO_PORT5 | GPIO_PIN3) -#define GPIO_SD_WR_PRT_1 (GPIO_ALT2 | GPIO_MODE_DIGITAL | GPIO_PORT0 | GPIO_PIN18) -#define GPIO_SD_WR_PRT_2 (GPIO_ALT2 | GPIO_MODE_DIGITAL | GPIO_PORT3 | GPIO_PIN15) -#define GPIO_SD_WR_PRT_3 (GPIO_ALT2 | GPIO_MODE_DIGITAL | GPIO_PORT4 | GPIO_PIN23) +#define GPIO_SD_WR_PRT_1 (GPIO_ALT2 | GPIO_MODE_DIGITAL | GPIO_SLEW_FAST | GPIO_FILTER_OFF | GPIO_PORT0 | GPIO_PIN18) +#define GPIO_SD_WR_PRT_2 (GPIO_ALT2 | GPIO_MODE_DIGITAL | GPIO_SLEW_FAST | GPIO_FILTER_OFF | GPIO_PORT3 | GPIO_PIN15) +#define GPIO_SD_WR_PRT_3 (GPIO_ALT2 | GPIO_MODE_DIGITAL | GPIO_SLEW_FAST | GPIO_FILTER_OFF | GPIO_PORT4 | GPIO_PIN23) /* SPIFI */ diff --git a/arch/arm/src/lpc54xx/chip/lpc54_syscon.h b/arch/arm/src/lpc54xx/chip/lpc54_syscon.h index aba819a31b..43e366139a 100644 --- a/arch/arm/src/lpc54xx/chip/lpc54_syscon.h +++ b/arch/arm/src/lpc54xx/chip/lpc54_syscon.h @@ -731,11 +731,24 @@ #define SYSCON_SDIOCLKCTRL_DRVDLY_MASK (0x1f << SYSCON_SDIOCLKCTRL_DRVDLY_SHIFT) # define SYSCON_SDIOCLKCTRL_DRVDLY(n) ((uint32_t)((n)-1) << SYSCON_SDIOCLKCTRL_DRVDLY_SHIFT) #define SYSCON_SDIOCLKCTRL_DRVDLYACTIVE (1 << 23) /* Bit 23: Enables drive delay */ -#define SYSCON_SDIOCLKCTRL_SMP_DLY_SHIFT (24) /* Bits 24-28: cclk_in_sample delay */ -#define SYSCON_SDIOCLKCTRL_SMP_DLY_MASK (0x1f << SYSCON_SDIOCLKCTRL_SMP_DLY_SHIFT) -# define SYSCON_SDIOCLKCTRL_SMP_DLY(n) ((uint32_t)((n)-1) << SYSCON_SDIOCLKCTRL_SMP_DLY_SHIFT) +#define SYSCON_SDIOCLKCTRL_SMPDLY_SHIFT (24) /* Bits 24-28: cclk_in_sample delay */ +#define SYSCON_SDIOCLKCTRL_SMPDLY_MASK (0x1f << SYSCON_SDIOCLKCTRL_SMP_DLYSHIFT) +# define SYSCON_SDIOCLKCTRL_SMPDLY(n) ((uint32_t)((n)-1) << SYSCON_SDIOCLKCTRL_SMPDLY_SHIFT) #define SYSCON_SDIOCLKCTRL_CCLK_SMPDLYACTIVE (1 << 31) /* Bit 31: Enables sample delay */ +/* Default phase and delay settings. */ + +#if 1 /* REVISIT. Phase settings are only needed for clocking >= 50MHz. */ +# define SYSCON_SDIOCLKCTRL_DRVPHASE_DEFAULT 0 +# define SYSCON_SDIOCLKCTRL_SMPPHASE_DEFAULT 0 +#else +# define SYSCON_SDIOCLKCTRL_DRVPHASE_DEFAULT (SYSCON_SDIOCLKCTRL_SMPPHASE_90 | SYSCON_SDIOCLKCTRL_PHASEACTIVE) +# define SYSCON_SDIOCLKCTRL_SMPPHASE_DEFAULT (SYSCON_SDIOCLKCTRL_SMPPHASE_0 | SYSCON_SDIOCLKCTRL_PHASEACTIVE) +#endif + +#define SYSCON_SDIOCLKCTRL_DRVDLY_DEFAULT (SYSCON_SDIOCLKCTRL_DRVDLY(32) | SYSCON_SDIOCLKCTRL_DRVDLYACTIVE) +#define SYSCON_SDIOCLKCTRL_SMPDLY_DEFAULT (SYSCON_SDIOCLKCTRL_SMPDLY(1) | SYSCON_SDIOCLKCTRL_CCLK_SMPDLYACTIVE) + /* FRO oscillator control */ #define SYSCON_FROCTRL_ diff --git a/arch/arm/src/lpc54xx/lpc54_sdmmc.c b/arch/arm/src/lpc54xx/lpc54_sdmmc.c index 7cf9fb300b..057037911d 100644 --- a/arch/arm/src/lpc54xx/lpc54_sdmmc.c +++ b/arch/arm/src/lpc54xx/lpc54_sdmmc.c @@ -1691,7 +1691,7 @@ 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); + blocklen, blocklen * nblocks, nblocks); /* Configure block size for next transfer */ @@ -2768,15 +2768,22 @@ FAR struct sdio_dev_s *lpc54_sdmmc_initialize(int slotno) lpc54_putreg(regval, LPC54_SYSCON_SDIOCLKDIV); lpc54_putreg(regval | SYSCON_SDIOCLKDIV_REQFLAG, LPC54_SYSCON_SDIOCLKDIV); +#if 1 /* REVISIT */ + /* Set delay values on the sample and drive inputs and outputs using the + * SDIOCLKCTRL register in the SYSCON block. + */ + + regval = SYSCON_SDIOCLKCTRL_DRVPHASE_DEFAULT | + SYSCON_SDIOCLKCTRL_SMPPHASE_DEFAULT | + SYSCON_SDIOCLKCTRL_DRVDLY_DEFAULT | + SYSCON_SDIOCLKCTRL_SMPDLY_DEFAULT; + lpc54_putreg(regval, LPC54_SYSCON_SDIOCLKCTRL); +#endif + /* Enable clocking to the SD/MMC peripheral */ lpc54_sdmmc_enableclk(); - /* 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 */ sem_init(&priv->waitsem, 0, 0); @@ -2812,6 +2819,17 @@ FAR struct sdio_dev_s *lpc54_sdmmc_initialize(int slotno) lpc54_gpio_config(GPIO_SD_WR_PRT); #endif +#ifndef CONFIG_SDIO_WIDTH_D1_ONLY + /* REVISIT: Due to a chip errata, DAT4-7 must also be configured. + * Otherwise the SD interface will not work. + */ + + lpc54_gpio_config(GPIO_SD_D4); + lpc54_gpio_config(GPIO_SD_D5); + lpc54_gpio_config(GPIO_SD_D6); + lpc54_gpio_config(GPIO_SD_D7); +#endif + /* Reset the card and assure that it is in the initial, unconfigured * state. */ diff --git a/configs/lpcxpresso-lpc54628/README.txt b/configs/lpcxpresso-lpc54628/README.txt index af3b957e2b..b4e7fef3aa 100644 --- a/configs/lpcxpresso-lpc54628/README.txt +++ b/configs/lpcxpresso-lpc54628/README.txt @@ -97,9 +97,24 @@ STATUS is "basic" in the sense that it supports only polled mode (no DMA). 2018-01-18: Added the lvgl configuration. See notes under "Configuration Sub-directories" for additional status. + 2018-10-22: Dave Marples recently fixed the LPC43 version of the USB + device controller driver. That driver is a clone from the LPC54 USB + DCD. I have backported Dave's changes to the LPC54 DCD. Unfortunately, + it did not fixe the problem. Then I discovered this errata for the LPC54: + + For the 4-bit mode to work successfully, four otherwise unused upper + data bits (SD_D[4] to SD_D[7]) must be functionally assigned to GPIO + pins with pull-up resistor. These pins do not need to be physically + connected on the hardware. + + With that change (and a lot of other fidgeting), there is some + improvement. I am able to mount and read the SD card .. at least most + of the time. I still get CRC errors when writing and I have not + successfully written to the SD card. It is closer but more TLC is + needed. There is still no support for the Accelerometer, SPIFI, or USB. There is - a complete but not-yet-functional SD card driver and and tested SPI + a complete but not entirely functional SD card driver and and tested SPI driver. There are no on-board devices to support SPI testing. Configurations diff --git a/configs/lpcxpresso-lpc54628/include/board.h b/configs/lpcxpresso-lpc54628/include/board.h index 950d5c6466..523fe12ab3 100644 --- a/configs/lpcxpresso-lpc54628/include/board.h +++ b/configs/lpcxpresso-lpc54628/include/board.h @@ -436,6 +436,15 @@ #define GPIO_SD_POW_EN GPIO_SD_POW_EN_2 /* P2.5 */ #define GPIO_SD_WR_PRT GPIO_SD_WR_PRT_2 /* P2.15 */ +/* Due to a chip errata, DAT4-7 must also be configured. Otherwise the SD + * interface will not work. + */ + +#define GPIO_SD_D4 (GPIO_SD_D4_3 | GPIO_PULLUP) /* P4.29 */ +#define GPIO_SD_D5 (GPIO_SD_D5_3 | GPIO_PULLUP) /* P4.30 */ +#define GPIO_SD_D6 (GPIO_SD_D6_3 | GPIO_PULLUP) /* P4.31 */ +#define GPIO_SD_D7 (GPIO_SD_D7_3 | GPIO_PULLUP) /* P5.0 */ + /* LCD * * There are no alternatives for LCD pins except for the VD0-VD3 pins.