From d36e2a8394fe48a9b730b92f1f928dbd45b8fbae Mon Sep 17 00:00:00 2001 From: Sebastien Lorquet Date: Fri, 9 Jun 2023 09:57:01 +0200 Subject: [PATCH] is25xp: Enable usage of several chips on the same spi bus --- drivers/mtd/is25xp.c | 55 +++++++++++++++++++++-------------------- include/nuttx/mtd/mtd.h | 3 ++- 2 files changed, 30 insertions(+), 28 deletions(-) diff --git a/drivers/mtd/is25xp.c b/drivers/mtd/is25xp.c index 66bf75c476..b7e7743588 100644 --- a/drivers/mtd/is25xp.c +++ b/drivers/mtd/is25xp.c @@ -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 */ diff --git a/include/nuttx/mtd/mtd.h b/include/nuttx/mtd/mtd.h index e39c5a32bb..5567a336c3 100644 --- a/include/nuttx/mtd/mtd.h +++ b/include/nuttx/mtd/mtd.h @@ -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