diff --git a/tasmota/settings.ino b/tasmota/settings.ino index 753e8602b..ae442069b 100644 --- a/tasmota/settings.ino +++ b/tasmota/settings.ino @@ -542,7 +542,7 @@ void SettingsErase(uint8_t type) For Esptool: 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 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; } - 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); +/* + bool _serialoutput = (LOG_LEVEL_DEBUG_MORE <= seriallog_level); + 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 = EsptoolEraseSector(_sector); // Esptool - erases flash completely +// bool result = EsptoolEraseSector(_sector); // Esptool - erases flash completely (slow) if (_serialoutput) { Serial.print(F(D_LOG_APPLICATION D_ERASED_SECTOR " ")); @@ -588,6 +589,9 @@ void SettingsErase(uint8_t type) } OsWatchLoop(); } +*/ + EsptoolErase(_sectorStart, _sectorEnd); // Esptool - erases flash completely (fast) + #endif // FIRMWARE_MINIMAL } diff --git a/tasmota/support_esptool.ino b/tasmota/support_esptool.ino index 45e5245bf..f030e113d 100644 --- a/tasmota/support_esptool.ino +++ b/tasmota/support_esptool.ino @@ -46,14 +46,16 @@ #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 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. inline static void spi_wait_ready(void) { - // Wait for SPI state machine ready - while((READ_REG(SPI_EXT2_REG) & SPI_ST)) { } + while((READ_REG(SPI_EXT2_REG) & SPI_ST)) { } // Wait for SPI state machine ready } // 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) { } } +/* bool EsptoolEraseSector(uint32_t sector) { spi_write_enable(); @@ -87,5 +90,36 @@ bool EsptoolEraseSector(uint32_t sector) 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