spi_flash: Add option to log warnings if (spuriously) writing zero bits to ones

Won't work for SPIFFS, maybe some other implementations?
This commit is contained in:
Angus Gratton 2017-11-29 14:26:57 +11:00 committed by Angus Gratton
parent 892b3ff14b
commit f7ac41c2da
2 changed files with 29 additions and 0 deletions

View file

@ -17,6 +17,20 @@ config SPI_FLASH_LOG_FAILED_WRITE
will be written with the address, expected & actual values. This can be useful when
debugging hardware SPI flash problems.
config SPI_FLASH_WARN_SETTING_ZERO_TO_ONE
bool "Log warning if writing zero bits to ones"
depends on SPI_FLASH_VERIFY_WRITE
default n
help
If this option is enabled, any SPI flash write which tries to set zero bits in the flash to
ones will log a warning. Such writes will not result in the requested data appearing identically
in flash once written, as SPI NOR flash can only set bits to one when an entire sector is erased.
After erasing, individual bits can only be written from one to zero.
Note that some software (such as SPIFFS) which is aware of SPI NOR flash may write one bits as an
optimisation, relying on the data in flash becoming a bitwise AND of the new data and any existing data.
Such software will log spurious warnings if this option is enabled.
config SPI_FLASH_ENABLE_COUNTERS
bool "Enable operation counters"
default 0

View file

@ -260,6 +260,21 @@ static IRAM_ATTR esp_rom_spiflash_result_t spi_flash_write_inner(uint32_t target
break;
}
#ifdef CONFIG_SPI_FLASH_WARN_SETTING_ZERO_TO_ONE
for (int r = 0; r < read_len; r += sizeof(uint32_t)) {
int r_w = r / sizeof(uint32_t); // index in words (r is index in bytes)
uint32_t write = src_addr[i_w + r_w];
uint32_t before = before_buf[r_w];
if ((before & write) != write) {
spi_flash_guard_end();
ESP_LOGW(TAG, "Write at offset 0x%x requests 0x%08x but will write 0x%08x -> 0x%08x",
target + i + r, write, before, before & write);
spi_flash_guard_start();
}
}
#endif
res = esp_rom_spiflash_write(target + i, &src_addr[i_w], read_len);
if (res != ESP_ROM_SPIFLASH_RESULT_OK) {
break;