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 /nuttx/drivers | |
parent | 016924ddbd281ccba7ee72fce682ddd9a1fb40e0 (diff) | |
download | px4-nuttx-42593d65b9712714bb41326f4b23f6c62cf0b058.tar.gz px4-nuttx-42593d65b9712714bb41326f4b23f6c62cf0b058.tar.bz2 px4-nuttx-42593d65b9712714bb41326f4b23f6c62cf0b058.zip |
MMC/SD driver needs to manage SPI mode and data width as well
Diffstat (limited to 'nuttx/drivers')
-rw-r--r-- | nuttx/drivers/mmcsd/Kconfig | 13 | ||||
-rw-r--r-- | nuttx/drivers/mmcsd/mmcsd_spi.c | 52 |
2 files changed, 55 insertions, 10 deletions
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) |