Extend SPI interface to better handle multiple devices on same SPI bus
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2162 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
6d8814ed34
commit
8baaf18f1e
@ -133,12 +133,14 @@ static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t
|
||||
|
||||
static const struct spi_ops_s g_spiops =
|
||||
{
|
||||
.lock = 0, /* Not yet implemented */
|
||||
.select = spi_select,
|
||||
.setfrequency = spi_setfrequency,
|
||||
.status = spi_status,
|
||||
.send = spi_send,
|
||||
.sndblock = spi_sndblock,
|
||||
.recvblock = spi_recvblock,
|
||||
.registercallback = 0, /* Not implemented */
|
||||
};
|
||||
|
||||
static struct spi_dev_s g_spidev = { &g_spiops };
|
||||
|
@ -276,12 +276,14 @@ static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t
|
||||
|
||||
static const struct spi_ops_s g_spiops =
|
||||
{
|
||||
.lock = 0, /* Not yet implemented */
|
||||
.select = spi_select,
|
||||
.setfrequency = spi_setfrequency,
|
||||
.status = spi_status,
|
||||
.send = spi_send,
|
||||
.sndblock = spi_sndblock,
|
||||
.recvblock = spi_recvblock,
|
||||
.registercallback = 0, /* Not implemented */
|
||||
};
|
||||
|
||||
#ifdef CONFIG_STR71X_BSPI0
|
||||
|
@ -70,11 +70,6 @@
|
||||
#define GPIO_LED3 (GPIO_OUTPUT|GPIO_CNF_OUTPP|GPIO_MODE_50MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTF|GPIO_PIN8)
|
||||
#define GPIO_LED4 (GPIO_OUTPUT|GPIO_CNF_OUTPP|GPIO_MODE_50MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTF|GPIO_PIN9)
|
||||
|
||||
/* MMC/SD SPI1 chip select: PC.12 */
|
||||
|
||||
#warning "MicoSD is on SDIO port, not SPI"
|
||||
#define GPIO_MMCSD_CS (GPIO_OUTPUT|GPIO_CNF_OUTPP|GPIO_MODE_50MHz|GPIO_OUTPUT_SET|GPIO_PORTC|GPIO_PIN12)
|
||||
|
||||
/* SPI FLASH chip select: PA.4 */
|
||||
|
||||
#define GPIO_FLASH_CS (GPIO_OUTPUT|GPIO_CNF_OUTPP|GPIO_MODE_50MHz|GPIO_OUTPUT_SET|GPIO_PORTB|GPIO_PIN2)
|
||||
|
@ -45,7 +45,10 @@
|
||||
#include <debug.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/spi.h>
|
||||
#ifdef CONFIG_STM32_SPI1
|
||||
# include <nuttx/spi.h>
|
||||
# include <nuttx/mtd.h>
|
||||
#endif
|
||||
#include <nuttx/mmcsd.h>
|
||||
|
||||
/****************************************************************************
|
||||
@ -54,6 +57,10 @@
|
||||
|
||||
/* Configuration ************************************************************/
|
||||
|
||||
/* For now, don't build in any SPI1 support -- NSH is not using it */
|
||||
|
||||
#undef CONFIG_STM32_SPI1
|
||||
|
||||
/* PORT and SLOT number probably depend on the board configuration */
|
||||
|
||||
/* Can't support USB features if USB is not enabled */
|
||||
@ -62,23 +69,8 @@
|
||||
# undef CONFIG_EXAMPLES_NSH_HAVEUSBDEV
|
||||
#endif
|
||||
|
||||
/* MMC/SD is on SPI1 */
|
||||
#warning "MicoSD is on SDIO port, not SPI"
|
||||
|
||||
#ifndef CONFIG_STM32_SPI1
|
||||
# undef CONFIG_EXAMPLES_NSH_MMCSDSPIPORTNO
|
||||
# undef CONFIG_EXAMPLES_NSH_MMCSDSLOTNO
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_EXAMPLES_NSH_MMCSDSPIPORTNO) && CONFIG_EXAMPLES_NSH_MMCSDSPIPORTNO != 0
|
||||
# error MMC/SD is on SPI1
|
||||
# undef CONFIG_EXAMPLES_NSH_MMCSDSPIPORTNO
|
||||
# undef CONFIG_EXAMPLES_NSH_MMCSDSLOTNO
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_EXAMPLES_NSH_MMCSDSLOTNO) && CONFIG_EXAMPLES_NSH_MMCSDSLOTNO != 0
|
||||
# error "Only one MMC/SD slot"
|
||||
# undef CONFIG_EXAMPLES_NSH_MMCSDSPIPORTNO
|
||||
# undef CONFIG_EXAMPLES_NSH_MMCSDSLOTNO
|
||||
#endif
|
||||
|
||||
@ -124,39 +116,44 @@ int nsh_archinitialize(void)
|
||||
{
|
||||
#ifdef CONFIG_STM32_SPI1
|
||||
FAR struct spi_dev_s *spi;
|
||||
int ret;
|
||||
FAR struct mtd_dev_s *mtd;
|
||||
#endif
|
||||
|
||||
/* Configure SPI-based devices */
|
||||
|
||||
#ifdef CONFIG_STM32_SPI1
|
||||
/* Get the SPI port */
|
||||
|
||||
message("nsh_archinitialize: Initializing SPI port %d\n",
|
||||
CONFIG_EXAMPLES_NSH_MMCSDSPIPORTNO);
|
||||
|
||||
spi = up_spiinitialize(CONFIG_EXAMPLES_NSH_MMCSDSPIPORTNO);
|
||||
message("nsh_archinitialize: Initializing SPI port 0\n");
|
||||
spi = up_spiinitialize(0);
|
||||
if (!spi)
|
||||
{
|
||||
message("nsh_archinitialize: Failed to initialize SPI port %d\n",
|
||||
CONFIG_EXAMPLES_NSH_MMCSDSPIPORTNO);
|
||||
message("nsh_archinitialize: Failed to initialize SPI port 0\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
message("nsh_archinitialize: Successfully initialized SPI port 0\n");
|
||||
|
||||
message("nsh_archinitialize: Successfully initialized SPI port %d\n",
|
||||
CONFIG_EXAMPLES_NSH_MMCSDSPIPORTNO);
|
||||
/* Now bind the SPI interface to the M25P64/128 SPI FLASH driver */
|
||||
|
||||
/* Bind the SPI port to the slot */
|
||||
|
||||
message("nsh_archinitialize: Binding SPI port %d to MMC/SD slot %d\n",
|
||||
CONFIG_EXAMPLES_NSH_MMCSDSPIPORTNO, CONFIG_EXAMPLES_NSH_MMCSDSLOTNO);
|
||||
|
||||
ret = mmcsd_spislotinitialize(CONFIG_EXAMPLES_NSH_MMCSDMINOR, CONFIG_EXAMPLES_NSH_MMCSDSLOTNO, spi);
|
||||
if (ret < 0)
|
||||
message("nsh_archinitialize: Bind SPI to the SPI flash driver\n");
|
||||
mtd = m25p_initialize(spi);
|
||||
if (!mtd)
|
||||
{
|
||||
message("nsh_archinitialize: Failed to bind SPI port %d to MMC/SD slot %d: %d\n",
|
||||
CONFIG_EXAMPLES_NSH_MMCSDSPIPORTNO, CONFIG_EXAMPLES_NSH_MMCSDSLOTNO, ret);
|
||||
return ret;
|
||||
message("nsh_archinitialize: Failed to bind SPI port 0 to the SPI FLASH driver\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
message("nsh_archinitialize: Successfuly bound SPI port %d to MMC/SD slot %d\n",
|
||||
CONFIG_EXAMPLES_NSH_MMCSDSPIPORTNO, CONFIG_EXAMPLES_NSH_MMCSDSLOTNO);
|
||||
message("nsh_archinitialize: Successfully bound SPI port 0 to the SPI FLASH driver\n");
|
||||
#warning "Now what are we going to do with this SPI FLASH driver?"
|
||||
#endif
|
||||
|
||||
/* Create the SPI FLASH MTD instance */
|
||||
|
||||
/* Here we will eventually need to
|
||||
* 1. Get the SDIO interface instance, and
|
||||
* 2. Bind it to the MMC/SD driver (slot CONFIG_EXAMPLES_NSH_MMCSDSLOTNO,
|
||||
* CONFIG_EXAMPLES_NSH_MMCSDMINOR).
|
||||
*/
|
||||
|
||||
#warning "Missing MMC/SD device configuration"
|
||||
return OK;
|
||||
}
|
||||
|
@ -79,36 +79,6 @@
|
||||
* Private Functions
|
||||
************************************************************************************/
|
||||
|
||||
static void stm32_chipselect(FAR struct spi_dev_s *dev, uint32 pinset, boolean pinval, boolean selected)
|
||||
{
|
||||
spidbg("devid: %d CS: %s pinset: %08x pinval: %s\n",
|
||||
(int)devid, selected ? "assert" : "de-assert", pinset, pinval ? "HIGH" : "LOW");
|
||||
|
||||
/* If we are selecting the chip, then we must call stm32_spitake to assure that we
|
||||
* have mutually exclusive access to the SPI bus while the chip is selected.
|
||||
*/
|
||||
|
||||
if (selected)
|
||||
{
|
||||
stm32_spitake(dev);
|
||||
}
|
||||
|
||||
/* Then set the CHIP select. Usually the chip select is LOW to select and HIGH, but
|
||||
* that can vary from part to part.
|
||||
*/
|
||||
|
||||
stm32_gpiowrite(pinset, pinval);
|
||||
|
||||
/* If we just de-selected the chip, then we must call stm32_spigive to to relinquish
|
||||
* our exclusive access to the SPI bus. Now, any waiting threads can have the SPI.
|
||||
*/
|
||||
|
||||
if (!selected)
|
||||
{
|
||||
stm32_spigive(dev);
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
* Public Functions
|
||||
************************************************************************************/
|
||||
@ -130,10 +100,8 @@ void weak_function stm32_spiinitialize(void)
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_STM32_SPI1
|
||||
/* Configure the SPI-based microSD and FLASH CS GPIO */
|
||||
/* Configure the SPI-based FLASH CS GPIO */
|
||||
|
||||
#warning "MicoSD is on SDIO port, not SPI"
|
||||
stm32_configgpio(GPIO_MMCSD_CS);
|
||||
stm32_configgpio(GPIO_FLASH_CS);
|
||||
#endif
|
||||
}
|
||||
@ -154,9 +122,6 @@ void weak_function stm32_spiinitialize(void)
|
||||
* 2. Provide stm32_spi1/2/3select() and stm32_spi1/2/3status() functions in your
|
||||
* board-specific logic. These functions will perform chip selection and
|
||||
* status operations using GPIOs in the way your board is configured.
|
||||
* The select() methods must call stm32_spitake() when the chip is selected
|
||||
* and stm32_spigive() when the chip is deselected. This assures mutually
|
||||
* exclusive access to the SPI for the duration while a chip is selected.
|
||||
* 3. Add a calls to up_spiinitialize() in your low level application
|
||||
* initialization logic
|
||||
* 4. The handle returned by up_spiinitialize() may then be used to bind the
|
||||
@ -171,17 +136,11 @@ void stm32_spi1select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, boolean s
|
||||
{
|
||||
spidbg("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert");
|
||||
|
||||
if (devid == SPIDEV_MMCSD)
|
||||
if (devid == SPIDEV_FLASH)
|
||||
{
|
||||
/* Set the GPIO low to select and high to de-select */
|
||||
|
||||
stm32_chipselect(dev, GPIO_MMCSD_CS,!selected, selected);
|
||||
}
|
||||
else if (devid == SPIDEV_FLASH)
|
||||
{
|
||||
/* Set the GPIO low to select and high to de-select */
|
||||
|
||||
stm32_chipselect(dev, GPIO_FLASH_CS,!selected, selected);
|
||||
stm32_gpiowrite(GPIO_FLASH_CS, !selected);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user