]> granicus.if.org Git - esp-idf/commitdiff
spi_flash: Add option to log warnings if (spuriously) writing zero bits to ones
authorAngus Gratton <angus@espressif.com>
Wed, 29 Nov 2017 03:26:57 +0000 (14:26 +1100)
committerAngus Gratton <gus@projectgus.com>
Sun, 3 Dec 2017 22:55:05 +0000 (09:55 +1100)
Won't work for SPIFFS, maybe some other implementations?

components/spi_flash/Kconfig
components/spi_flash/flash_ops.c

index 5a05d859bddd53ea6531664ec555dffa8e74e5fd..f5e3c7ecd976fd6f9bb517952618ad10fd98a6ac 100644 (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
index eb2b23cf4946668ecf1bdad09b3c9d0b38ea32f1..aab0c1210fa877d5a6e71d694f42ec57c7975e0e 100644 (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;