diff --git a/platform/drivers/NVM/W25Qx.c b/platform/drivers/NVM/W25Qx.c index 07a1835e..bd5a96e4 100644 --- a/platform/drivers/NVM/W25Qx.c +++ b/platform/drivers/NVM/W25Qx.c @@ -34,6 +34,7 @@ #define CMD_RSECR 0x48 /* Read security register */ #define CMD_WKUP 0xAB /* Release power down */ #define CMD_PDWN 0xB9 /* Power down */ +#define CMD_ECHIP 0xC7 /* Full chip erase */ /* * Target-specific SPI interface functions, their implementation can be found @@ -159,6 +160,41 @@ bool W25Qx_eraseSector(uint32_t addr) return false; } +bool W25Qx_eraseChip() +{ + gpio_clearPin(FLASH_CS); + (void) spiFlash_SendRecv(CMD_WREN); /* Write enable */ + gpio_setPin(FLASH_CS); + + delayUs(5); + + gpio_clearPin(FLASH_CS); + (void) spiFlash_SendRecv(CMD_ECHIP); /* Command */ + gpio_setPin(FLASH_CS); + + /* + * Wait till erase terminates. + * Timeout after 200s, at 20ms per tick + */ + uint16_t timeout = 10000; + while(timeout > 0) + { + delayMs(20); + timeout--; + + gpio_clearPin(FLASH_CS); + (void) spiFlash_SendRecv(CMD_RDSTA); /* Read status */ + uint8_t status = spiFlash_SendRecv(0x00); + gpio_setPin(FLASH_CS); + + /* If busy flag is low, we're done */ + if((status & 0x01) == 0) return true; + } + + /* If we get here, we had a timeout */ + return false; +} + ssize_t W25Qx_writePage(uint32_t addr, void* buf, size_t len) { /* Keep 256-byte boundary to avoid wrap-around when writing */ diff --git a/platform/drivers/NVM/W25Qx.h b/platform/drivers/NVM/W25Qx.h index 21e4df01..777ea10f 100644 --- a/platform/drivers/NVM/W25Qx.h +++ b/platform/drivers/NVM/W25Qx.h @@ -86,6 +86,14 @@ void W25Qx_readData(uint32_t addr, void *buf, size_t len); */ bool W25Qx_eraseSector(uint32_t addr); +/** + * Full chip erase. + * Function returns when erase process terminated. + * + * @return true on success, false on failure. + */ +bool W25Qx_eraseChip(); + /** * Write data to a 256-byte flash memory page. * NOTE: if data size goes beyond the 256 byte boundary, length will be truncated