Speedup flash erase using block erase

This commit is contained in:
Theo Arends 2019-11-15 16:58:22 +01:00
parent 822b719a5d
commit 4c2ad64056
2 changed files with 45 additions and 7 deletions

View File

@ -542,7 +542,7 @@ void SettingsErase(uint8_t type)
For Esptool: For Esptool:
The only way to erase whole flash is esptool which uses direct SPI writes to flash. The only way to erase whole flash is esptool which uses direct SPI writes to flash.
The default erase function is EspTool (EsptoolEraseSector) The default erase function is EspTool (EsptoolErase)
0 = Erase from program end until end of flash as seen by SDK 0 = Erase from program end until end of flash as seen by SDK
1 = Erase 16k SDK parameter area near end of flash as seen by SDK (0x0xFCxxx - 0x0xFFFFF) solving possible wifi errors 1 = Erase 16k SDK parameter area near end of flash as seen by SDK (0x0xFCxxx - 0x0xFFFFF) solving possible wifi errors
@ -564,15 +564,16 @@ void SettingsErase(uint8_t type)
_sectorEnd = SETTINGS_LOCATION +1; _sectorEnd = SETTINGS_LOCATION +1;
} }
bool _serialoutput = (LOG_LEVEL_DEBUG_MORE <= seriallog_level);
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION D_ERASE " %d " D_UNIT_SECTORS), _sectorEnd - _sectorStart); AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION D_ERASE " %d " D_UNIT_SECTORS), _sectorEnd - _sectorStart);
/*
bool _serialoutput = (LOG_LEVEL_DEBUG_MORE <= seriallog_level);
for (uint32_t _sector = _sectorStart; _sector < _sectorEnd; _sector++) { for (uint32_t _sector = _sectorStart; _sector < _sectorEnd; _sector++) {
// bool result = ESP.flashEraseSector(_sector); // Arduino core - erases flash as seen by SDK bool result = ESP.flashEraseSector(_sector); // Arduino core - erases flash as seen by SDK
// bool result = !SPIEraseSector(_sector); // SDK - erases flash as seen by SDK // bool result = !SPIEraseSector(_sector); // SDK - erases flash as seen by SDK
bool result = EsptoolEraseSector(_sector); // Esptool - erases flash completely // bool result = EsptoolEraseSector(_sector); // Esptool - erases flash completely (slow)
if (_serialoutput) { if (_serialoutput) {
Serial.print(F(D_LOG_APPLICATION D_ERASED_SECTOR " ")); Serial.print(F(D_LOG_APPLICATION D_ERASED_SECTOR " "));
@ -588,6 +589,9 @@ void SettingsErase(uint8_t type)
} }
OsWatchLoop(); OsWatchLoop();
} }
*/
EsptoolErase(_sectorStart, _sectorEnd); // Esptool - erases flash completely (fast)
#endif // FIRMWARE_MINIMAL #endif // FIRMWARE_MINIMAL
} }

View File

@ -46,14 +46,16 @@
#define SPI_ST 0x7 // Done state value #define SPI_ST 0x7 // Done state value
// *** flasher_stub/include/stub_flasher.h
#define SECTORS_PER_BLOCK (FLASH_BLOCK_SIZE / SPI_FLASH_SEC_SIZE)
// *** flasher_stub/stub_write_flash.c // *** flasher_stub/stub_write_flash.c
static const uint32_t STATUS_WIP_BIT = (1 << 0); // SPI status bits static const uint32_t STATUS_WIP_BIT = (1 << 0); // SPI status bits
// Wait for the SPI state machine to be ready, ie no command in progress in the internal host. // Wait for the SPI state machine to be ready, ie no command in progress in the internal host.
inline static void spi_wait_ready(void) inline static void spi_wait_ready(void)
{ {
// Wait for SPI state machine ready while((READ_REG(SPI_EXT2_REG) & SPI_ST)) { } // Wait for SPI state machine ready
while((READ_REG(SPI_EXT2_REG) & SPI_ST)) { }
} }
// Returns true if the spiflash is ready for its next write operation. // Returns true if the spiflash is ready for its next write operation.
@ -75,6 +77,7 @@ static void spi_write_enable(void)
while(READ_REG(SPI_CMD_REG) != 0) { } while(READ_REG(SPI_CMD_REG) != 0) { }
} }
/*
bool EsptoolEraseSector(uint32_t sector) bool EsptoolEraseSector(uint32_t sector)
{ {
spi_write_enable(); spi_write_enable();
@ -87,5 +90,36 @@ bool EsptoolEraseSector(uint32_t sector)
return true; return true;
} }
*/
void EsptoolErase(uint32_t start_sector, uint32_t end_sector)
{
int next_erase_sector = start_sector;
int remaining_erase_sector = end_sector - start_sector;
while (remaining_erase_sector > 0) {
spi_write_enable();
uint32_t command = SPI_FLASH_SE; // Sector erase, 4KB
uint32_t sectors_to_erase = 1;
if (remaining_erase_sector >= SECTORS_PER_BLOCK &&
next_erase_sector % SECTORS_PER_BLOCK == 0) {
command = SPI_FLASH_BE; // Block erase 64KB if we have space for it
sectors_to_erase = SECTORS_PER_BLOCK;
}
uint32_t addr = next_erase_sector * SPI_FLASH_SEC_SIZE;
spi_wait_ready();
WRITE_REG(SPI_ADDR_REG, addr & 0xffffff);
WRITE_REG(SPI_CMD_REG, command); // Sector erase, 4KB
while(READ_REG(SPI_CMD_REG) != 0) { }
remaining_erase_sector -= sectors_to_erase;
next_erase_sector += sectors_to_erase;
while (!spiflash_is_ready()) { }
yield();
OsWatchLoop();
}
}
#endif // USE_ESPTOOL #endif // USE_ESPTOOL