From 01fe33211ec07e3af207e280d7470f99e0b06f45 Mon Sep 17 00:00:00 2001 From: "sonika.rathi" Date: Tue, 22 Oct 2024 11:34:39 +0200 Subject: [PATCH] feat(spi_nand_flash): Add Kconfig option to verify write operations --- spi_nand_flash/Kconfig | 10 +++++++ spi_nand_flash/README.md | 20 +++++++++++++ spi_nand_flash/idf_component.yml | 2 +- spi_nand_flash/src/nand.c | 29 +++++++++++++++++++ .../test_app/main/test_spi_nand_flash.c | 2 ++ 5 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 spi_nand_flash/Kconfig diff --git a/spi_nand_flash/Kconfig b/spi_nand_flash/Kconfig new file mode 100644 index 0000000000..4bfdee2913 --- /dev/null +++ b/spi_nand_flash/Kconfig @@ -0,0 +1,10 @@ +menu "SPI NAND Flash configuration" + + config NAND_FLASH_VERIFY_WRITE + bool "Verify SPI NAND flash writes" + default n + help + If this option is enabled, any time SPI NAND flash is written then the data will be read + back and verified. This can catch hardware problems with SPI NAND flash, or flash which + was not erased before verification. +endmenu diff --git a/spi_nand_flash/README.md b/spi_nand_flash/README.md index 88f68ccd0c..23d4635a55 100644 --- a/spi_nand_flash/README.md +++ b/spi_nand_flash/README.md @@ -25,3 +25,23 @@ At present, `spi_nand_flash` component is compatible with the chips produced by * Winbond - W25N01GVxxxG/T/R, W25N512GVxIG/IT, W25N512GWxxR/T, W25N01JWxxxG/T, W25N01JWxxxG/T * Gigadevice - GD5F1GQ5UExxG, GD5F1GQ5RExxG, GD5F2GQ5UExxG, GD5F2GQ5RExxG, GD5F4GQ6UExxG, GD5F4GQ6RExxG, GD5F4GQ6UExxG, GD5F4GQ6RExxG * Alliance - AS5F31G04SND-08LIN, AS5F32G04SND-08LIN, AS5F12G04SND-10LIN, AS5F34G04SND-08LIN, AS5F14G04SND-10LIN, AS5F38G04SND-08LIN, AS5F18G04SND-10LIN +* Micron - MT29F4G01ABAFDWB + +## Troubleshooting + +To verify SPI NAND Flash writes, enable the `NAND_FLASH_VERIFY_WRITE` option in menuconfig. When this option is enabled, every time data is written to the SPI NAND Flash, it will be read back and verified. This helps in identifying hardware issues with the SPI NAND Flash. + +To configure the project for this setting, follow these steps: + +``` +idf.py menuconfig +-> Component config +-> SPI NAND Flash configuration +-> NAND_FLASH_VERIFY_WRITE +``` + +Run `idf.py -p PORT flash monitor` and if the write verification is successful, the following result will be printed: + +``` +I nand_flash: spi_nand_flash_write_sector: Write buffer verification succeeded +``` diff --git a/spi_nand_flash/idf_component.yml b/spi_nand_flash/idf_component.yml index 068f188442..dedf8f9f80 100644 --- a/spi_nand_flash/idf_component.yml +++ b/spi_nand_flash/idf_component.yml @@ -1,4 +1,4 @@ -version: "0.4.1" +version: "0.4.2" description: Driver for accessing SPI NAND Flash url: https://github.com/espressif/idf-extra-components/tree/master/spi_nand_flash issues: https://github.com/espressif/idf-extra-components/issues diff --git a/spi_nand_flash/src/nand.c b/spi_nand_flash/src/nand.c index b0a0979f98..e5680d1355 100644 --- a/spi_nand_flash/src/nand.c +++ b/spi_nand_flash/src/nand.c @@ -279,6 +279,8 @@ esp_err_t spi_nand_erase_chip(spi_nand_flash_device_t *handle) end, TAG, ""); } + xSemaphoreGive(handle->mutex); + // clear dhara map dhara_map_init(&handle->dhara_map, &handle->dhara_nand, handle->work_buffer, handle->config.gc_factor); dhara_map_clear(&handle->dhara_map); @@ -310,6 +312,23 @@ esp_err_t spi_nand_flash_read_sector(spi_nand_flash_device_t *handle, uint8_t *b return ret; } +#if CONFIG_NAND_FLASH_VERIFY_WRITE +static esp_err_t s_verify_write(spi_nand_flash_device_t *handle, dhara_sector_t sector_id, const uint8_t *expected_buffer, dhara_error_t *err) +{ + esp_err_t ret = ESP_OK; + if (dhara_map_read(&handle->dhara_map, sector_id, handle->read_buffer, err)) { + ret = ESP_ERR_FLASH_BASE + *err; + ESP_LOGE(TAG, "failed to read nand flash to verify previous write, err: 0x%x", *err); + return ret; + } + + if (memcmp(handle->read_buffer, expected_buffer, handle->page_size)) { + ret = ESP_FAIL; + } + return ret; +} +#endif //CONFIG_NAND_FLASH_VERIFY_WRITE + esp_err_t spi_nand_flash_write_sector(spi_nand_flash_device_t *handle, const uint8_t *buffer, dhara_sector_t sector_id) { dhara_error_t err; @@ -320,6 +339,16 @@ esp_err_t spi_nand_flash_write_sector(spi_nand_flash_device_t *handle, const uin if (dhara_map_write(&handle->dhara_map, sector_id, buffer, &err)) { ret = ESP_ERR_FLASH_BASE + err; } +#if CONFIG_NAND_FLASH_VERIFY_WRITE + if (ret == ESP_OK) { + ret = s_verify_write(handle, sector_id, buffer, &err); + if (ret == ESP_OK) { + ESP_LOGI(TAG, "%s: Write buffer verification succeeded", __func__); + } else { + ESP_LOGE(TAG, "%s: Write buffer verification failed", __func__); + } + } +#endif //CONFIG_NAND_FLASH_VERIFY_WRITE xSemaphoreGive(handle->mutex); return ret; diff --git a/spi_nand_flash/test_app/main/test_spi_nand_flash.c b/spi_nand_flash/test_app/main/test_spi_nand_flash.c index 5682378051..7b6cfd92a2 100644 --- a/spi_nand_flash/test_app/main/test_spi_nand_flash.c +++ b/spi_nand_flash/test_app/main/test_spi_nand_flash.c @@ -47,6 +47,7 @@ #define PATTERN_SEED 0x12345678 +static void do_single_write_test(spi_nand_flash_device_t *flash, uint32_t start_sec, uint16_t sec_count); static void setup_bus(spi_host_device_t host_id) { spi_bus_config_t spi_bus_cfg = { @@ -104,6 +105,7 @@ TEST_CASE("erase nand flash", "[spi_nand_flash]") spi_device_handle_t spi; setup_nand_flash(&nand_flash_device_handle, &spi); TEST_ESP_OK(spi_nand_erase_chip(nand_flash_device_handle)); + do_single_write_test(nand_flash_device_handle, 1, 1); deinit_nand_flash(nand_flash_device_handle, spi); }