diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2013-06-17 12:31:24 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2013-06-17 12:31:24 -0600 |
commit | 42593d65b9712714bb41326f4b23f6c62cf0b058 (patch) | |
tree | 7104b8971397e504e66bbc550de93629a2a5690f | |
parent | 016924ddbd281ccba7ee72fce682ddd9a1fb40e0 (diff) | |
download | nuttx-42593d65b9712714bb41326f4b23f6c62cf0b058.tar.gz nuttx-42593d65b9712714bb41326f4b23f6c62cf0b058.tar.bz2 nuttx-42593d65b9712714bb41326f4b23f6c62cf0b058.zip |
MMC/SD driver needs to manage SPI mode and data width as well
-rw-r--r-- | nuttx/ChangeLog | 3 | ||||
-rw-r--r-- | nuttx/configs/sam3u-ek/README.txt | 11 | ||||
-rw-r--r-- | nuttx/configs/sam4l-xplained/README.txt | 40 | ||||
-rw-r--r-- | nuttx/drivers/mmcsd/Kconfig | 13 | ||||
-rw-r--r-- | nuttx/drivers/mmcsd/mmcsd_spi.c | 52 |
5 files changed, 85 insertions, 34 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog index 3cbfc42be..830f01f7d 100644 --- a/nuttx/ChangeLog +++ b/nuttx/ChangeLog @@ -4994,4 +4994,5 @@ signal (it is active low) (2013-6-16). * configs/sam3u-ek/include/board.h: The SAM3U-EK board now runs at 96MHz. This might have broken some things? (2013-6-17). - + * drivers/mmcsd/mmcsd-spi.c: Driver need to make sure that the SPI mode + and data width are correct (2013-6-17). diff --git a/nuttx/configs/sam3u-ek/README.txt b/nuttx/configs/sam3u-ek/README.txt index 3ee86c94f..4bb8caa2e 100644 --- a/nuttx/configs/sam3u-ek/README.txt +++ b/nuttx/configs/sam3u-ek/README.txt @@ -615,21 +615,12 @@ Configuration sub-directories perform good measurements but I am not getting the /PENIRQ interrupt. The interrupt is set up correctly (I can ground A24 and I get the interrupt), so apparently the ADS7843E is - not generating interrupts. + not generating interrupts. No idea why. nx: Configures to use examples/nx using the HX834x LCD hardware on the SAM3U-EK development board. - STATUS: - This configuration used to work well in an older NuttX version - on an older SAM3U-EK board (my old board was bricked and I got - another after a lapse of a couple of years). But now it no - longer works! There appears to be some bug, perhaps a memory - clobbering bug, that causes a variety of symptons: Hangs on - UART0 or hard faults. The LCD functionality is basically intact, - but not usable because of these problems. - ostest: This configuration directory, performs a simple OS test using examples/ostest. By default, this project assumes that you are diff --git a/nuttx/configs/sam4l-xplained/README.txt b/nuttx/configs/sam4l-xplained/README.txt index 4b67f6513..906efdd10 100644 --- a/nuttx/configs/sam4l-xplained/README.txt +++ b/nuttx/configs/sam4l-xplained/README.txt @@ -697,16 +697,6 @@ Configuration sub-directories System Type -> Peripherals: CONFIG_SAM34_SPI=y : Enable the SAM4L SPI peripheral - Board Selection -> Common Board Options - CONFIG_NSH_MMCSDSLOTNO=0 : Only one MMC/SD slot, slot 0 - CONFIG_NSH_MMCSDSPIPORTNO=0 : Use CS=0 if the I/O1 is in EXT1, OR - CONFIG_NSH_MMCSDSPIPORTNO=2 : Use CS=2 if the I/O1 is in EXT2 - - Board Selection -> SAM4L Xplained Pro Modules - CONFIG_SAM4L_XPLAINED_IOMODULE=y : I/O1 module is connected - CONFIG_SAM4L_XPLAINED_IOMODULE_EXT1=y : In EXT1, or EXT2 - CONFIG_SAM4L_XPLAINED_IOMODULE_EXT2=y - Device Drivers CONFIG_SPI=y : Enable SPI support CONFIG_SPI_EXCHANGE=y : The exchange() method is supported @@ -714,10 +704,21 @@ Configuration sub-directories CONFIG_MMCSD=y : Enable MMC/SD support CONFIG_MMCSD_NSLOTS=1 : Only one MMC/SD card slot - CONFIG_MMCSD_MULTIBLOCK_DISABLE=y : I tested this way, but this may not be required + CONFIG_MMCSD_MULTIBLOCK_DISABLE=n : Should not need to disable multi-block transfers CONFIG_MMCSD_HAVECARDDETECT=y : I/O1 module as a card detect GPIO CONFIG_MMCSD_SPI=y : Use the SPI interface to the MMC/SD card CONFIG_MMCSD_SPICLOCK=20000000 : This is a guess for the optimal MMC/SD frequency + CONFIG_MMCSD_SPIMODE=0 : Mode 0 is required + + Board Selection -> Common Board Options + CONFIG_NSH_MMCSDSLOTNO=0 : Only one MMC/SD slot, slot 0 + CONFIG_NSH_MMCSDSPIPORTNO=0 : Use CS=0 if the I/O1 is in EXT1, OR + CONFIG_NSH_MMCSDSPIPORTNO=2 : Use CS=2 if the I/O1 is in EXT2 + + Board Selection -> SAM4L Xplained Pro Modules + CONFIG_SAM4L_XPLAINED_IOMODULE=y : I/O1 module is connected + CONFIG_SAM4L_XPLAINED_IOMODULE_EXT1=y : In EXT1, or EXT2 + CONFIG_SAM4L_XPLAINED_IOMODULE_EXT2=y Application Configuration -> NSH Library CONFIG_NSH_ARCHINIT=y : Board has architecture-specific initialization @@ -728,5 +729,18 @@ Configuration sub-directories behave very well (since its outgoing prompts also appear as incoming commands). - STATUS: As of 2013-6-16, the SPI interface is not communicating with - the SD card.
\ No newline at end of file + NOTE: If you get a compilation error like: + + libxx_new.cxx:74:40: error: 'operator new' takes type 'size_t' + ('unsigned int') as first parameter [-fper + + Sometimes NuttX and your toolchain will disagree on the underlying + type of size_t; sometimes it is an 'unsigned int' and sometimes it is + an 'unsigned long int'. If this error occurs, then you may need to + toggle the value of CONFIG_CXX_NEWLONG. + + STATUS: As of 2013-6-16, the microSD slot on the I/O1 is not working. + This could be an SPI communication issues, but it appears more like + a card interfacing problems. The card does make some appropriate + responses but also reports some other issues (erase reset) and will + not exit IDLE most. diff --git a/nuttx/drivers/mmcsd/Kconfig b/nuttx/drivers/mmcsd/Kconfig index 720bbf20a..7e3843faa 100644 --- a/nuttx/drivers/mmcsd/Kconfig +++ b/nuttx/drivers/mmcsd/Kconfig @@ -43,6 +43,8 @@ config MMCSD_SPI default y depends on SPI +if MMCSD_SPI + config MMCSD_SPICLOCK int "MMC/SD maximum SPI clock" default 20000000 @@ -51,11 +53,20 @@ config MMCSD_SPICLOCK Maximum SPI clock to drive MMC/SD card. Default is 20MHz. +config MMCSD_SPIMODE + int "MMC/SD SPI mode" + default 0 + ---help--- + Should be mode 0. However, sometimes this is useful for experimenting. + +endif + config MMCSD_SDIO - bool "MMC/SD sdio transfer support" + bool "MMC/SD SDIO transfer support" default n if MMCSD_SDIO + config SDIO_DMA bool "SDIO DMA support" default n diff --git a/nuttx/drivers/mmcsd/mmcsd_spi.c b/nuttx/drivers/mmcsd/mmcsd_spi.c index 71fe5c625..46d624d3c 100644 --- a/nuttx/drivers/mmcsd/mmcsd_spi.c +++ b/nuttx/drivers/mmcsd/mmcsd_spi.c @@ -86,6 +86,10 @@ # define CONFIG_MMCSD_SPICLOCK 20000000 #endif +#ifndef CONFIG_MMCSD_SPIMODE +# define CONFIG_MMCSD_SPIMODE SPIDEV_MODE0 +#endif + #ifndef CONFIG_MMCSD_SECTOR512 # define CONFIG_MMCSD_SECTOR512 /* Force 512 byte sectors on all cards */ #endif @@ -348,12 +352,13 @@ static void mmcsd_semtake(FAR struct mmcsd_slot_s *slot) #ifndef CONFIG_SPI_OWNBUS (void)SPI_LOCK(slot->spi, true); - /* Set the frequency, as some other driver could have changed it. - * TODO: Also need to restore mode and number-of-bits. Those can also - * change from SPI device-to-device. + /* Set the frequency, bit width and mode, as some other driver could have + * changed those since the last time that we had the SPI bus. */ SPI_SETFREQUENCY(slot->spi, slot->spispeed); + SPI_SETMODE(slot->sp, CONFIG_MMCSD_SPIMODE); + SPI_SETBITS(slot->sp, 8); #endif /* Get exclusive access to the MMC/SD device (prossibly un-necessary if @@ -370,6 +375,10 @@ static void mmcsd_semtake(FAR struct mmcsd_slot_s *slot) } } +/**************************************************************************** + * Name: mmcsd_semgive + ****************************************************************************/ + static void mmcsd_semgive(FAR struct mmcsd_slot_s *slot) { /* Relinquish the lock on the MMC/SD device */ @@ -392,6 +401,27 @@ static void mmcsd_semgive(FAR struct mmcsd_slot_s *slot) } /**************************************************************************** + * Name: mmcsd_spiinit + * + * Description: + * Set SPI mode and data width. + * + * Assumptions: + * MMC/SD card already selected + * + ****************************************************************************/ + +#ifdef CONFIG_SPI_OWNBUS +static inline void mmcsd_spiinit(FAR struct mmcsd_slot_s *slot) +{ + SPI_SETMODE(slot->spi, CONFIG_MMCSD_SPIMODE); + SPI_SETBITS(slot->spi, 8); +} +#else +# define mmcsd_spiinit(slot) +#endif + +/**************************************************************************** * Name: mmcsd_waitready * * Description: @@ -682,7 +712,7 @@ static void mmcsd_decodecsd(FAR struct mmcsd_slot_s *slot, uint8_t *csd) uint32_t csizemult; uint32_t csize; - /* Calculate SPI max clock */ + /* Calculate the SPI max clock frequency */ maxfrequency = g_transpeedtu[MMCSD_CSD_TRANSPEED_TIMEVALUE(csd)] * @@ -696,12 +726,9 @@ static void mmcsd_decodecsd(FAR struct mmcsd_slot_s *slot, uint8_t *csd) frequency = CONFIG_MMCSD_SPICLOCK; } - /* Store the value for future use */ + /* Set the actual SPI frequency as close as possible to the max frequency */ slot->spispeed = frequency; - - /* Set the actual SPI frequency as close as possible to that value */ - frequency = SPI_SETFREQUENCY(spi, frequency); /* Now determine the delay to access data */ @@ -1548,6 +1575,7 @@ static int mmcsd_mediainitialize(FAR struct mmcsd_slot_s *slot) /* Clock Freq. Identification Mode < 400kHz */ + slot->spispeed = MMCSD_IDMODE_CLOCK; SPI_SETFREQUENCY(spi, MMCSD_IDMODE_CLOCK); /* Set the maximum access time out */ @@ -1910,9 +1938,15 @@ int mmcsd_spislotinitialize(int minor, int slotno, FAR struct spi_dev_s *spi) slot->spi = spi; slot->spispeed = MMCSD_IDMODE_CLOCK; - /* Ininitialize for the media in the slot (if any) */ + /* Get exclusvice access to the SPI bus and make sure that SPI is properly + * configured for the MMC/SD card + */ mmcsd_semtake(slot); + mmcsd_spiinit(slot); + + /* Ininitialize for the media in the slot (if any) */ + ret = mmcsd_mediainitialize(slot); mmcsd_semgive(slot); if (ret == 0) |