mirror of
https://github.com/apache/nuttx.git
synced 2026-06-05 15:58:59 +08:00
MMC/SD driver needs to manage SPI mode and data width as well
This commit is contained in:
@@ -4994,4 +4994,5 @@
|
|||||||
signal (it is active low) (2013-6-16).
|
signal (it is active low) (2013-6-16).
|
||||||
* configs/sam3u-ek/include/board.h: The SAM3U-EK board now runs at
|
* configs/sam3u-ek/include/board.h: The SAM3U-EK board now runs at
|
||||||
96MHz. This might have broken some things? (2013-6-17).
|
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
|
perform good measurements but I am not getting the /PENIRQ
|
||||||
interrupt. The interrupt is set up correctly (I can ground
|
interrupt. The interrupt is set up correctly (I can ground
|
||||||
A24 and I get the interrupt), so apparently the ADS7843E is
|
A24 and I get the interrupt), so apparently the ADS7843E is
|
||||||
not generating interrupts.
|
not generating interrupts. No idea why.
|
||||||
|
|
||||||
nx:
|
nx:
|
||||||
Configures to use examples/nx using the HX834x LCD hardware on
|
Configures to use examples/nx using the HX834x LCD hardware on
|
||||||
the SAM3U-EK development board.
|
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:
|
ostest:
|
||||||
This configuration directory, performs a simple OS test using
|
This configuration directory, performs a simple OS test using
|
||||||
examples/ostest. By default, this project assumes that you are
|
examples/ostest. By default, this project assumes that you are
|
||||||
|
|||||||
@@ -697,6 +697,19 @@ Configuration sub-directories
|
|||||||
System Type -> Peripherals:
|
System Type -> Peripherals:
|
||||||
CONFIG_SAM34_SPI=y : Enable the SAM4L SPI peripheral
|
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
|
Board Selection -> Common Board Options
|
||||||
CONFIG_NSH_MMCSDSLOTNO=0 : Only one MMC/SD slot, slot 0
|
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=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_EXT1=y : In EXT1, or EXT2
|
||||||
CONFIG_SAM4L_XPLAINED_IOMODULE_EXT2=y
|
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
|
Application Configuration -> NSH Library
|
||||||
CONFIG_NSH_ARCHINIT=y : Board has architecture-specific initialization
|
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
|
behave very well (since its outgoing prompts also appear as incoming
|
||||||
commands).
|
commands).
|
||||||
|
|
||||||
STATUS: As of 2013-6-16, the SPI interface is not communicating with
|
NOTE: If you get a compilation error like:
|
||||||
the SD card.
|
|
||||||
|
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.
|
||||||
|
|||||||
+12
-1
@@ -43,6 +43,8 @@ config MMCSD_SPI
|
|||||||
default y
|
default y
|
||||||
depends on SPI
|
depends on SPI
|
||||||
|
|
||||||
|
if MMCSD_SPI
|
||||||
|
|
||||||
config MMCSD_SPICLOCK
|
config MMCSD_SPICLOCK
|
||||||
int "MMC/SD maximum SPI clock"
|
int "MMC/SD maximum SPI clock"
|
||||||
default 20000000
|
default 20000000
|
||||||
@@ -51,11 +53,20 @@ config MMCSD_SPICLOCK
|
|||||||
Maximum SPI clock to drive MMC/SD card.
|
Maximum SPI clock to drive MMC/SD card.
|
||||||
Default is 20MHz.
|
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
|
config MMCSD_SDIO
|
||||||
bool "MMC/SD sdio transfer support"
|
bool "MMC/SD SDIO transfer support"
|
||||||
default n
|
default n
|
||||||
|
|
||||||
if MMCSD_SDIO
|
if MMCSD_SDIO
|
||||||
|
|
||||||
config SDIO_DMA
|
config SDIO_DMA
|
||||||
bool "SDIO DMA support"
|
bool "SDIO DMA support"
|
||||||
default n
|
default n
|
||||||
|
|||||||
@@ -86,6 +86,10 @@
|
|||||||
# define CONFIG_MMCSD_SPICLOCK 20000000
|
# define CONFIG_MMCSD_SPICLOCK 20000000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_MMCSD_SPIMODE
|
||||||
|
# define CONFIG_MMCSD_SPIMODE SPIDEV_MODE0
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef CONFIG_MMCSD_SECTOR512
|
#ifndef CONFIG_MMCSD_SECTOR512
|
||||||
# define CONFIG_MMCSD_SECTOR512 /* Force 512 byte sectors on all cards */
|
# define CONFIG_MMCSD_SECTOR512 /* Force 512 byte sectors on all cards */
|
||||||
#endif
|
#endif
|
||||||
@@ -348,12 +352,13 @@ static void mmcsd_semtake(FAR struct mmcsd_slot_s *slot)
|
|||||||
#ifndef CONFIG_SPI_OWNBUS
|
#ifndef CONFIG_SPI_OWNBUS
|
||||||
(void)SPI_LOCK(slot->spi, true);
|
(void)SPI_LOCK(slot->spi, true);
|
||||||
|
|
||||||
/* Set the frequency, as some other driver could have changed it.
|
/* Set the frequency, bit width and mode, as some other driver could have
|
||||||
* TODO: Also need to restore mode and number-of-bits. Those can also
|
* changed those since the last time that we had the SPI bus.
|
||||||
* change from SPI device-to-device.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SPI_SETFREQUENCY(slot->spi, slot->spispeed);
|
SPI_SETFREQUENCY(slot->spi, slot->spispeed);
|
||||||
|
SPI_SETMODE(slot->sp, CONFIG_MMCSD_SPIMODE);
|
||||||
|
SPI_SETBITS(slot->sp, 8);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Get exclusive access to the MMC/SD device (prossibly un-necessary if
|
/* 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)
|
static void mmcsd_semgive(FAR struct mmcsd_slot_s *slot)
|
||||||
{
|
{
|
||||||
/* Relinquish the lock on the MMC/SD device */
|
/* Relinquish the lock on the MMC/SD device */
|
||||||
@@ -391,6 +400,27 @@ static void mmcsd_semgive(FAR struct mmcsd_slot_s *slot)
|
|||||||
#endif
|
#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
|
* 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 csizemult;
|
||||||
uint32_t csize;
|
uint32_t csize;
|
||||||
|
|
||||||
/* Calculate SPI max clock */
|
/* Calculate the SPI max clock frequency */
|
||||||
|
|
||||||
maxfrequency =
|
maxfrequency =
|
||||||
g_transpeedtu[MMCSD_CSD_TRANSPEED_TIMEVALUE(csd)] *
|
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;
|
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;
|
slot->spispeed = frequency;
|
||||||
|
|
||||||
/* Set the actual SPI frequency as close as possible to that value */
|
|
||||||
|
|
||||||
frequency = SPI_SETFREQUENCY(spi, frequency);
|
frequency = SPI_SETFREQUENCY(spi, frequency);
|
||||||
|
|
||||||
/* Now determine the delay to access data */
|
/* 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 */
|
/* Clock Freq. Identification Mode < 400kHz */
|
||||||
|
|
||||||
|
slot->spispeed = MMCSD_IDMODE_CLOCK;
|
||||||
SPI_SETFREQUENCY(spi, MMCSD_IDMODE_CLOCK);
|
SPI_SETFREQUENCY(spi, MMCSD_IDMODE_CLOCK);
|
||||||
|
|
||||||
/* Set the maximum access time out */
|
/* 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->spi = spi;
|
||||||
slot->spispeed = MMCSD_IDMODE_CLOCK;
|
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_semtake(slot);
|
||||||
|
mmcsd_spiinit(slot);
|
||||||
|
|
||||||
|
/* Ininitialize for the media in the slot (if any) */
|
||||||
|
|
||||||
ret = mmcsd_mediainitialize(slot);
|
ret = mmcsd_mediainitialize(slot);
|
||||||
mmcsd_semgive(slot);
|
mmcsd_semgive(slot);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
|
|||||||
Reference in New Issue
Block a user