diff --git a/configs/mcu123-lpc214x/src/up_spi.c b/configs/mcu123-lpc214x/src/up_spi.c index 0997aa01b1..f517939c48 100644 --- a/configs/mcu123-lpc214x/src/up_spi.c +++ b/configs/mcu123-lpc214x/src/up_spi.c @@ -1,7 +1,7 @@ /**************************************************************************** * config/mcu123-lpc214x/src/up_spi.c * - * Copyright (C) 2008 Gregory Nutt. All rights reserved. + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * This logic emulates the Prolific PL2303 serial/USB converter @@ -88,7 +88,7 @@ * Private Function Prototypes ****************************************************************************/ -static void spi_select(FAR struct spi_dev_s *dev, boolean selected); +static void spi_select(FAR struct spi_dev_s *dev, enum spidev_e devid, boolean selected); static uint32 spi_setfrequency(FAR struct spi_dev_s *dev, uint32 frequency); static ubyte spi_status(FAR struct spi_dev_s *dev); static ubyte spi_sndbyte(FAR struct spi_dev_s *dev, ubyte ch); @@ -123,17 +123,21 @@ static struct spi_dev_s g_spidev = { &g_spiops }; * Name: spi_select * * Description: - * Enable/disable the SPI slave select + * Enable/disable the SPI slave select. The implementation of this method + * must include handshaking: If a device is selected, it must hold off + * all other attempts to select the device until the device is deselecte. * * Input Parameters: - * selected: TRUE: slave selected, FALSE: slave de-selected + * dev - Device-specific state data + * devid - Identifies the device to select + * selected - TRUE: slave selected, FALSE: slave de-selected * * Returned Value: * None * ****************************************************************************/ -static void spi_select(FAR struct spi_dev_s *dev, boolean selected) +static void spi_select(FAR struct spi_dev_s *dev, enum spidev_e devid, boolean selected) { uint32 bit = 1 << 20; diff --git a/configs/olimex-strp711/src/up_spi.c b/configs/olimex-strp711/src/up_spi.c index 43a166b2ab..b30b426fd4 100644 --- a/configs/olimex-strp711/src/up_spi.c +++ b/configs/olimex-strp711/src/up_spi.c @@ -265,7 +265,7 @@ static inline void spi_putreg(FAR struct str71x_spidev_s *priv, ubyte offset, /* SPI methods */ -static void spi_select(FAR struct spi_dev_s *dev, boolean selected); +static void spi_select(FAR struct spi_dev_s *dev, enum spidev_e devid, boolean selected); static uint32 spi_setfrequency(FAR struct spi_dev_s *dev, uint32 frequency); static ubyte spi_status(FAR struct spi_dev_s *dev); static ubyte spi_sndbyte(FAR struct spi_dev_s *dev, ubyte ch); @@ -357,17 +357,21 @@ static inline void spi_putreg(FAR struct str71x_spidev_s *priv, ubyte offset, ui * Name: spi_select * * Description: - * Enable/disable the SPI slave select + * Enable/disable the SPI slave select. The implementation of this method + * must include handshaking: If a device is selected, it must hold off + * all other attempts to select the device until the device is deselected. * * Input Parameters: - * selected: TRUE: slave selected, FALSE: slave de-selected + * dev - Device-specific state data + * devid - Identifies the device to select + * selected - TRUE: slave selected, FALSE: slave de-selected * * Returned Value: * None * ****************************************************************************/ -static void spi_select(FAR struct spi_dev_s *dev, boolean selected) +static void spi_select(FAR struct spi_dev_s *dev, enum spidev_e devid, boolean selected) { FAR struct str71x_spidev_s *priv = (FAR struct str71x_spidev_s *)dev; uint16 reg16; diff --git a/drivers/mmcsd/mmcsd_spi.c b/drivers/mmcsd/mmcsd_spi.c index 7501928d01..fea4548ca3 100644 --- a/drivers/mmcsd/mmcsd_spi.c +++ b/drivers/mmcsd/mmcsd_spi.c @@ -362,7 +362,7 @@ static uint32 mmcsd_sendcmd(FAR struct mmcsd_slot_s *slot, /* Select SPI */ - SPI_SELECT(spi, TRUE); + SPI_SELECT(spi, SPIDEV_MMCSD, TRUE); /* Send command code */ @@ -409,7 +409,7 @@ static uint32 mmcsd_sendcmd(FAR struct mmcsd_slot_s *slot, if (i == 0) { fdbg("Failed: i=%d response=%02x\n", i, response); - SPI_SELECT(spi, FALSE); + SPI_SELECT(spi, SPIDEV_MMCSD, FALSE); return (uint32)-1; } @@ -469,7 +469,7 @@ static void mmcsd_setblklen(FAR struct mmcsd_slot_s *slot, uint32 length) uint32 result; result = mmcsd_sendcmd(slot, &g_cmd16, length); - SPI_SELECT(spi, FALSE); + SPI_SELECT(spi, SPIDEV_MMCSD, FALSE); } /**************************************************************************** @@ -604,7 +604,7 @@ static int mmcsd_getcardinfo(FAR struct mmcsd_slot_s *slot, ubyte *buffer, ubyte response; int i; - SPI_SELECT(spi, FALSE); + SPI_SELECT(spi, SPIDEV_MMCSD, FALSE); SPI_SNDBYTE(spi, 0xff); /* Send the CMD9 or CMD10 */ @@ -644,13 +644,13 @@ static int mmcsd_getcardinfo(FAR struct mmcsd_slot_s *slot, ubyte *buffer, (void)SPI_SNDBYTE(spi, 0xff); (void)SPI_SNDBYTE(spi, 0xff); - SPI_SELECT(spi, FALSE); + SPI_SELECT(spi, SPIDEV_MMCSD, FALSE); return OK; } } errout_with_eio: - SPI_SELECT(spi, FALSE); + SPI_SELECT(spi, SPIDEV_MMCSD, FALSE); return -EIO; } @@ -697,12 +697,12 @@ static int mmcsd_open(FAR struct inode *inode) /* Select the slave */ mmcsd_semtake(&slot->sem); - SPI_SELECT(spi, FALSE); + SPI_SELECT(spi, SPIDEV_MMCSD, FALSE); /* Verify that the MMC/SD card is alive and ready for business */ ret = mmcsd_waitready(slot); - SPI_SELECT(spi, FALSE); + SPI_SELECT(spi, SPIDEV_MMCSD, FALSE); mmcsd_semgive(&slot->sem); return ret; } @@ -790,7 +790,7 @@ static ssize_t mmcsd_read(FAR struct inode *inode, unsigned char *buffer, /* Select the slave and synchronize */ mmcsd_semtake(&slot->sem); - SPI_SELECT(spi, FALSE); + SPI_SELECT(spi, SPIDEV_MMCSD, FALSE); (void)SPI_SNDBYTE(spi, 0xff); /* Send CMD17: Reads a block of the size selected by the SET_BLOCKLEN @@ -836,7 +836,7 @@ static ssize_t mmcsd_read(FAR struct inode *inode, unsigned char *buffer, /* On success, return the number of sectors transfer */ - SPI_SELECT(spi, FALSE); + SPI_SELECT(spi, SPIDEV_MMCSD, FALSE); mmcsd_semgive(&slot->sem); fvdbg("(%d) Read %d bytes:\n", i, nbytes); @@ -846,7 +846,7 @@ static ssize_t mmcsd_read(FAR struct inode *inode, unsigned char *buffer, } errout_with_eio: - SPI_SELECT(spi, FALSE); + SPI_SELECT(spi, SPIDEV_MMCSD, FALSE); mmcsd_semgive(&slot->sem); return -EIO; } @@ -932,7 +932,7 @@ static ssize_t mmcsd_write(FAR struct inode *inode, const unsigned char *buffer, /* Select the slave and synchronize */ mmcsd_semtake(&slot->sem); - SPI_SELECT(spi, FALSE); + SPI_SELECT(spi, SPIDEV_MMCSD, FALSE); (void)SPI_SNDBYTE(spi, 0xff); /* Send CMD24 (WRITE_BLOCK) and verify that good R1 status is returned */ @@ -941,7 +941,7 @@ static ssize_t mmcsd_write(FAR struct inode *inode, const unsigned char *buffer, if (response != MMCSD_SPIR1_OK) { fdbg("CMD24 failed: R1=%02x\n", response); - SPI_SELECT(spi, FALSE); + SPI_SELECT(spi, SPIDEV_MMCSD, FALSE); ret = -EIO; goto errout_with_sem; } @@ -976,7 +976,7 @@ static ssize_t mmcsd_write(FAR struct inode *inode, const unsigned char *buffer, /* Wait until the card is no longer busy */ ret = mmcsd_waitready(slot); - SPI_SELECT(spi, FALSE); + SPI_SELECT(spi, SPIDEV_MMCSD, FALSE); mmcsd_semgive(&slot->sem); /* Verify that the card successfully became non-busy */ @@ -1141,7 +1141,7 @@ static int mmcsd_mediainitialize(FAR struct mmcsd_slot_s *slot) fvdbg("Send CMD0\n"); for (i = 0; i < 2; i++) { - SPI_SELECT(spi, FALSE); + SPI_SELECT(spi, SPIDEV_MMCSD, FALSE); for (j = 10; j; j--) { @@ -1151,7 +1151,7 @@ static int mmcsd_mediainitialize(FAR struct mmcsd_slot_s *slot) /* Send CMD0 (GO_TO_IDLE) to put MMC/SD in IDLE/SPI mode */ result = mmcsd_sendcmd(slot, &g_cmd0, 0); - SPI_SELECT(spi, FALSE); + SPI_SELECT(spi, SPIDEV_MMCSD, FALSE); /* Return from CMD0 is R1 which should now show IDLE STATE */ @@ -1177,16 +1177,16 @@ static int mmcsd_mediainitialize(FAR struct mmcsd_slot_s *slot) for (i = 100; i; --i) { fvdbg("%d. Send CMD55\n", i); - SPI_SELECT(spi, FALSE); + SPI_SELECT(spi, SPIDEV_MMCSD, FALSE); SPI_SNDBYTE(spi, 0xff); result = mmcsd_sendcmd(slot, &g_cmd55, 0); - SPI_SELECT(spi, FALSE); + SPI_SELECT(spi, SPIDEV_MMCSD, FALSE); fvdbg("%d. Send ACMD41\n", i); - SPI_SELECT(spi, FALSE); + SPI_SELECT(spi, SPIDEV_MMCSD, FALSE); SPI_SNDBYTE(spi, 0xff); result = mmcsd_sendcmd(slot, &g_acmd41, 0); - SPI_SELECT(spi, FALSE); + SPI_SELECT(spi, SPIDEV_MMCSD, FALSE); /* If this is an MMC card, it will response with ILLEGAL COMMAND */ @@ -1198,10 +1198,10 @@ static int mmcsd_mediainitialize(FAR struct mmcsd_slot_s *slot) for (i = 100; i; --i) { fvdbg("%d. Send CMD1\n", i); - SPI_SELECT(spi, FALSE); + SPI_SELECT(spi, SPIDEV_MMCSD, FALSE); SPI_SNDBYTE(spi, 0xff); result = mmcsd_sendcmd(slot, &g_cmd1, 0); - SPI_SELECT(spi, FALSE); + SPI_SELECT(spi, SPIDEV_MMCSD, FALSE); if (result == MMCSD_SPIR1_OK) { diff --git a/include/nuttx/spi.h b/include/nuttx/spi.h index 896ed6e8f7..f3dfa82a77 100644 --- a/include/nuttx/spi.h +++ b/include/nuttx/spi.h @@ -53,17 +53,22 @@ * Name: SPI_SELECT * * Description: - * Enable/disable the SPI chip select. Required. + * Enable/disable the SPI chip select. The implementation of this method + * must include handshaking: If a device is selected, it must hold off + * all other attempts to select the device until the device is deselected. + * Required. * * Input Parameters: - * select: TRUE: chip selected, FALSE: chip de-selected + * dev - Device-specific state data + * devid - Identifies the device to select + * selected - TRUE: slave selected, FALSE: slave de-selected * * Returned Value: * None * ****************************************************************************/ -#define SPI_SELECT(d,b) ((d)->ops->select(d,b)) +#define SPI_SELECT(d,id,s) ((d)->ops->select(d,id,s)) /**************************************************************************** * Name: SPI_SETFREQUENCY @@ -183,12 +188,23 @@ typedef void (*mediachange_t)(void *arg); +/* If the board supports multiple SPI devices, this enumeration identifies + * which is selected or de-seleted. + */ + +enum spidev_e +{ + SPIDEV_NONE = 0, /* Not a valid value */ + SPIDEV_MMCSD, /* Select SPI MMC/SD device */ + SPIDEV_ETHERNET /* Select SPI ethernet device */ +}; + /* The SPI vtable */ struct spi_dev_s; struct spi_ops_s { - void (*select)(FAR struct spi_dev_s *dev, boolean selected); + void (*select)(FAR struct spi_dev_s *dev, enum spidev_e devid, boolean selected); uint32 (*setfrequency)(FAR struct spi_dev_s *dev, uint32 frequency); ubyte (*status)(FAR struct spi_dev_s *dev); ubyte (*sndbyte)(FAR struct spi_dev_s *dev, ubyte ch); @@ -223,7 +239,7 @@ extern "C" { * Name: up_spiinitialize * * Description: - * Initialize the selected SPI port + * Initialize the selected SPI port. * * Input Parameter: * Port number (for hardware that has mutiple SPI interfaces)