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 <javiercasas@geotab.com>
This commit is contained in:
Javier Casas 2025-03-25 16:34:45 +01:00 committed by Xiang Xiao
parent fbf1ccae0e
commit e0b221016f

View file

@ -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).
*/