From 568a09c13c89bc94da110169a01dbf8fada56151 Mon Sep 17 00:00:00 2001 From: Javier Casas Date: Tue, 25 Mar 2025 16:34:45 +0100 Subject: [PATCH] driver/mtd/at45db.c: write to page without built-in erase Using the FTL driver over a MTD flash device, when writing to flash, eventually the ftl_flush function is called and it does an erase (MTD_ERASE) and then the write (MTD_BWRITE). Currently, the at45db driver (at45db.c), uses a write command 0x82 ("Main Memory Page Program through Buffer 1 with Built-In Erase") that also performs a built-in erase before the write. In summary, each time a write to flash is performed, the page is erased twice before it is written, first in the FTL driver and then in the MTD driver. This PR is to change the page writes to not use that built-in command. Signed-off-by: Javier Casas --- drivers/mtd/at45db.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/at45db.c b/drivers/mtd/at45db.c index 25b94d73e81..d51902fceed 100644 --- a/drivers/mtd/at45db.c +++ b/drivers/mtd/at45db.c @@ -587,10 +587,12 @@ static inline void at45db_pgwrite(FAR struct at45db_dev_s *priv, /* We assume that sectors are not write protected */ - wrcmd[0] = AT45DB_MNTHRUBF1; /* To main memory through buffer 1 */ - wrcmd[1] = (offset >> 16) & 0xff; /* 24-bit address MS byte */ - wrcmd[2] = (offset >> 8) & 0xff; /* 24-bit address middle byte */ - wrcmd[3] = offset & 0xff; /* 24-bit address LS byte */ + /* Write data do SRAM buffer 1, byte offset 0 */ + + wrcmd[0] = AT45DB_WRBF1; /* Buffer 1 write */ + wrcmd[1] = 0; /* 24-bit address MS byte */ + wrcmd[2] = 0; /* 24-bit address middle byte */ + wrcmd[3] = 0; /* 24-bit address LS byte */ /* Higher performance write logic: We leave the chip busy after write and * erase operations. This improves write and erase performance because we @@ -608,6 +610,21 @@ static inline void at45db_pgwrite(FAR struct at45db_dev_s *priv, SPI_SNDBLOCK(priv->spi, buffer, 1 << priv->pageshift); SPI_SELECT(priv->spi, SPIDEV_FLASH(0), false); + /* Write SRAM buffer 1 to flash page */ + + wrcmd[0] = AT45DB_BF1TOMN; /* Buffer 1 to Main Memory Page Program without built-in erase */ + wrcmd[1] = (offset >> 16) & 0xff; /* 24-bit address MS byte */ + wrcmd[2] = (offset >> 8) & 0xff; /* 24-bit address middle byte */ + wrcmd[3] = offset & 0xff; /* 24-bit address LS byte */ + +#ifdef CONFIG_AT45DB_PREWAIT + at45db_waitbusy(priv); +#endif + + SPI_SELECT(priv->spi, SPIDEV_FLASH(0), true); + SPI_SNDBLOCK(priv->spi, wrcmd, 4); + SPI_SELECT(priv->spi, SPIDEV_FLASH(0), false); + /* Wait for any erase to complete if we are not trying to improve write * performance. (see comments above). */