mirror of
https://github.com/apache/nuttx.git
synced 2025-01-13 09:49:21 +08:00
MMC/SD driver needs to manage SPI mode and data width as well
This commit is contained in:
parent
8db5d403ee
commit
b9ad057972
5 changed files with 86 additions and 35 deletions
|
@ -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).
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -697,6 +697,19 @@ Configuration sub-directories
|
|||
System Type -> Peripherals:
|
||||
CONFIG_SAM34_SPI=y : Enable the SAM4L SPI peripheral
|
||||
|
||||
Device Drivers
|
||||
CONFIG_SPI=y : Enable SPI support
|
||||
CONFIG_SPI_EXCHANGE=y : The exchange() method is supported
|
||||
CONFIG_SPI_OWNBUS=y : Smaller code if this is the only SPI device
|
||||
|
||||
CONFIG_MMCSD=y : Enable MMC/SD support
|
||||
CONFIG_MMCSD_NSLOTS=1 : Only one MMC/SD card slot
|
||||
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
|
||||
|
@ -707,18 +720,6 @@ Configuration sub-directories
|
|||
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
|
||||
CONFIG_SPI_OWNBUS=y : Smaller code if this is the only SPI device
|
||||
|
||||
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_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
|
||||
|
||||
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.
|
||||
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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
@ -391,6 +400,27 @@ static void mmcsd_semgive(FAR struct mmcsd_slot_s *slot)
|
|||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* 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
|
||||
*
|
||||
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue