mirror of
https://github.com/apache/nuttx.git
synced 2025-01-13 12:08:36 +08:00
is25xp: Enable usage of several chips on the same spi bus
This commit is contained in:
parent
37bf542c9e
commit
d36e2a8394
2 changed files with 30 additions and 28 deletions
|
@ -179,6 +179,7 @@ struct is25xp_dev_s
|
|||
{
|
||||
struct mtd_dev_s mtd; /* MTD interface */
|
||||
FAR struct spi_dev_s *dev; /* Saved SPI interface instance */
|
||||
uint16_t spi_devid; /* SPIDEV_FLASH index */
|
||||
uint8_t sectorshift; /* 12 */
|
||||
uint8_t pageshift; /* 8 */
|
||||
uint16_t nsectors; /* 2,048 or 4,096 or 8,192 or 16,384 */
|
||||
|
@ -286,7 +287,7 @@ static inline int is25xp_readid(struct is25xp_dev_s *priv)
|
|||
/* Lock the SPI bus, configure the bus, and select this FLASH part. */
|
||||
|
||||
is25xp_lock(priv->dev);
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH(0), true);
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH(priv->spi_devid), true);
|
||||
|
||||
/* Send the "Read ID (RDID)" command and read the first three ID bytes */
|
||||
|
||||
|
@ -297,7 +298,7 @@ static inline int is25xp_readid(struct is25xp_dev_s *priv)
|
|||
|
||||
/* Deselect the FLASH and unlock the bus */
|
||||
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH(0), false);
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH(priv->spi_devid), false);
|
||||
is25xp_unlock(priv->dev);
|
||||
|
||||
finfo("manufacturer: %02x memory: %02x capacity: %02x\n",
|
||||
|
@ -367,7 +368,7 @@ static void is25xp_enable4byteaddr(struct is25xp_dev_s *priv)
|
|||
/* Lock the SPI bus, configure the bus, and select this FLASH part. */
|
||||
|
||||
is25xp_lock(priv->dev);
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH(0), true);
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH(priv->spi_devid), true);
|
||||
|
||||
/* Send the "Enter 4-byte Address Mode (EN4B)" command */
|
||||
|
||||
|
@ -375,7 +376,7 @@ static void is25xp_enable4byteaddr(struct is25xp_dev_s *priv)
|
|||
|
||||
/* Deselect the FLASH and unlock the bus */
|
||||
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH(0), false);
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH(priv->spi_devid), false);
|
||||
is25xp_unlock(priv->dev);
|
||||
}
|
||||
|
||||
|
@ -402,7 +403,7 @@ static void is25xp_waitwritecomplete(struct is25xp_dev_s *priv)
|
|||
|
||||
/* Select this FLASH part */
|
||||
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH(0), true);
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH(priv->spi_devid), true);
|
||||
|
||||
/* Send "Read Status Register (RDSR)" command */
|
||||
|
||||
|
@ -422,7 +423,7 @@ static void is25xp_waitwritecomplete(struct is25xp_dev_s *priv)
|
|||
|
||||
/* Deselect the FLASH */
|
||||
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH(0), false);
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH(priv->spi_devid), false);
|
||||
|
||||
#else
|
||||
|
||||
|
@ -432,7 +433,7 @@ static void is25xp_waitwritecomplete(struct is25xp_dev_s *priv)
|
|||
{
|
||||
/* Select this FLASH part */
|
||||
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH(0), true);
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH(priv->spi_devid), true);
|
||||
|
||||
/* Send "Read Status Register (RDSR)" command */
|
||||
|
||||
|
@ -446,7 +447,7 @@ static void is25xp_waitwritecomplete(struct is25xp_dev_s *priv)
|
|||
|
||||
/* Deselect the FLASH */
|
||||
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH(0), false);
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH(priv->spi_devid), false);
|
||||
|
||||
/* Given that writing could take up to few tens of milliseconds,
|
||||
* and erasing could take more. The following short delay in the
|
||||
|
@ -476,7 +477,7 @@ static void is25xp_writeenable(struct is25xp_dev_s *priv)
|
|||
{
|
||||
/* Select this FLASH part */
|
||||
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH(0), true);
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH(priv->spi_devid), true);
|
||||
|
||||
/* Send "Write Enable (WREN)" command */
|
||||
|
||||
|
@ -484,7 +485,7 @@ static void is25xp_writeenable(struct is25xp_dev_s *priv)
|
|||
|
||||
/* Deselect the FLASH */
|
||||
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH(0), false);
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH(priv->spi_devid), false);
|
||||
finfo("Enabled\n");
|
||||
}
|
||||
|
||||
|
@ -500,14 +501,14 @@ static void is25xp_unprotect(struct is25xp_dev_s *priv)
|
|||
|
||||
/* Send "Write status (WRSR)" */
|
||||
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH(0), true);
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH(priv->spi_devid), true);
|
||||
SPI_SEND(priv->dev, IS25_WRSR);
|
||||
|
||||
/* Followed by the new status value */
|
||||
|
||||
SPI_SEND(priv->dev, 0);
|
||||
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH(0), false);
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH(priv->spi_devid), false);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -538,7 +539,7 @@ static void is25xp_sectorerase(struct is25xp_dev_s *priv,
|
|||
|
||||
/* Select this FLASH part */
|
||||
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH(0), true);
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH(priv->spi_devid), true);
|
||||
|
||||
/* Send the "Sector Erase (SE)" or Sub-Sector Erase (SSE) instruction
|
||||
* that was passed in as the erase type.
|
||||
|
@ -563,7 +564,7 @@ static void is25xp_sectorerase(struct is25xp_dev_s *priv,
|
|||
|
||||
/* Deselect the FLASH */
|
||||
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH(0), false);
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH(priv->spi_devid), false);
|
||||
finfo("Erased\n");
|
||||
}
|
||||
|
||||
|
@ -589,7 +590,7 @@ static inline int is25xp_bulkerase(struct is25xp_dev_s *priv)
|
|||
|
||||
/* Select this FLASH part */
|
||||
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH(0), true);
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH(priv->spi_devid), true);
|
||||
|
||||
/* Send the "Chip Erase (CER)" instruction */
|
||||
|
||||
|
@ -597,7 +598,7 @@ static inline int is25xp_bulkerase(struct is25xp_dev_s *priv)
|
|||
|
||||
/* Deselect the FLASH */
|
||||
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH(0), false);
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH(priv->spi_devid), false);
|
||||
is25xp_waitwritecomplete(priv);
|
||||
|
||||
finfo("Return: OK\n");
|
||||
|
@ -630,7 +631,7 @@ static inline void is25xp_pagewrite(struct is25xp_dev_s *priv,
|
|||
|
||||
/* Select this FLASH part */
|
||||
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH(0), true);
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH(priv->spi_devid), true);
|
||||
|
||||
/* Send "Page Program (PP)" command */
|
||||
|
||||
|
@ -654,7 +655,7 @@ static inline void is25xp_pagewrite(struct is25xp_dev_s *priv,
|
|||
|
||||
/* Deselect the FLASH: Chip Select high */
|
||||
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH(0), false);
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH(priv->spi_devid), false);
|
||||
finfo("Written\n");
|
||||
}
|
||||
|
||||
|
@ -683,7 +684,7 @@ static inline void is25xp_bytewrite(struct is25xp_dev_s *priv,
|
|||
|
||||
/* Select this FLASH part */
|
||||
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH(0), true);
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH(priv->spi_devid), true);
|
||||
|
||||
/* Send "Page Program (PP)" command */
|
||||
|
||||
|
@ -707,7 +708,7 @@ static inline void is25xp_bytewrite(struct is25xp_dev_s *priv,
|
|||
|
||||
/* Deselect the FLASH: Chip Select high */
|
||||
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH(0), false);
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH(priv->spi_devid), false);
|
||||
finfo("Written\n");
|
||||
}
|
||||
#endif
|
||||
|
@ -881,7 +882,7 @@ static ssize_t is25xp_read(FAR struct mtd_dev_s *dev,
|
|||
|
||||
/* Select this FLASH part */
|
||||
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH(0), true);
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH(priv->spi_devid), true);
|
||||
|
||||
/* Send "Read from Memory " instruction */
|
||||
|
||||
|
@ -904,7 +905,7 @@ static ssize_t is25xp_read(FAR struct mtd_dev_s *dev,
|
|||
|
||||
/* Deselect the FLASH and unlock the SPI bus */
|
||||
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH(0), false);
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH(priv->spi_devid), false);
|
||||
is25xp_unlock(priv->dev);
|
||||
|
||||
finfo("return nbytes: %d\n", (int)nbytes);
|
||||
|
@ -1084,7 +1085,8 @@ static int is25xp_ioctl(FAR struct mtd_dev_s *dev,
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct mtd_dev_s *is25xp_initialize(FAR struct spi_dev_s *dev)
|
||||
FAR struct mtd_dev_s *is25xp_initialize(FAR struct spi_dev_s *dev,
|
||||
uint16_t spi_devid)
|
||||
{
|
||||
FAR struct is25xp_dev_s *priv;
|
||||
int ret;
|
||||
|
@ -1093,9 +1095,7 @@ FAR struct mtd_dev_s *is25xp_initialize(FAR struct spi_dev_s *dev)
|
|||
|
||||
/* Allocate a state structure (we allocate the structure instead of using
|
||||
* a fixed, static allocation so that we can handle multiple FLASH devices.
|
||||
* The current implementation would handle only one FLASH part per SPI
|
||||
* device (only because of the SPIDEV_FLASH(0) definition) and so would
|
||||
* have to be extended to handle multiple FLASH parts on the same SPI bus.
|
||||
* The current implementation handles several FLASH part per SPI bus.
|
||||
*/
|
||||
|
||||
priv = (FAR struct is25xp_dev_s *)kmm_zalloc(sizeof(struct is25xp_dev_s));
|
||||
|
@ -1115,11 +1115,12 @@ FAR struct mtd_dev_s *is25xp_initialize(FAR struct spi_dev_s *dev)
|
|||
priv->mtd.ioctl = is25xp_ioctl;
|
||||
priv->mtd.name = "is25xp";
|
||||
priv->dev = dev;
|
||||
priv->spi_devid = spi_devid;
|
||||
priv->lastwaswrite = false;
|
||||
|
||||
/* Deselect the FLASH */
|
||||
|
||||
SPI_SELECT(dev, SPIDEV_FLASH(0), false);
|
||||
SPI_SELECT(dev, SPIDEV_FLASH(priv->spi_devid), false);
|
||||
|
||||
/* Identify the FLASH chip and get its capacity */
|
||||
|
||||
|
|
|
@ -429,7 +429,8 @@ FAR struct mtd_dev_s *at25_initialize(FAR struct spi_dev_s *dev);
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct mtd_dev_s *is25xp_initialize(FAR struct spi_dev_s *dev);
|
||||
FAR struct mtd_dev_s *is25xp_initialize(FAR struct spi_dev_s *dev,
|
||||
uint16_t spi_devid);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: m25p_initialize
|
||||
|
|
Loading…
Reference in a new issue