From 78a2dbe42a13a116c40c48c36c91f7a260e1a814 Mon Sep 17 00:00:00 2001 From: Cao Sen Miao Date: Fri, 27 Nov 2020 19:09:40 +0800 Subject: [PATCH] spi_flash: add a new function to support read the unique id Close https://github.com/espressif/esp-idf/pull/4255 --- components/spi_flash/esp_flash_api.c | 25 ++++++++++++++++++ components/spi_flash/include/esp_flash.h | 13 ++++++++++ .../spi_flash/include/spi_flash_chip_driver.h | 5 ++++ .../include/spi_flash_chip_generic.h | 12 +++++++++ .../private_include/spi_flash_defs.h | 1 + components/spi_flash/spi_flash_chip_boya.c | 1 + components/spi_flash/spi_flash_chip_gd.c | 1 + components/spi_flash/spi_flash_chip_generic.c | 26 +++++++++++++++++-- components/spi_flash/spi_flash_chip_issi.c | 1 + components/spi_flash/spi_flash_chip_mxic.c | 9 +++++++ components/spi_flash/spi_flash_chip_winbond.c | 1 + 11 files changed, 93 insertions(+), 2 deletions(-) diff --git a/components/spi_flash/esp_flash_api.c b/components/spi_flash/esp_flash_api.c index b47b0afadd..17a9eba4f2 100644 --- a/components/spi_flash/esp_flash_api.c +++ b/components/spi_flash/esp_flash_api.c @@ -286,6 +286,31 @@ esp_err_t esp_flash_read_id(esp_flash_t* chip, uint32_t* out_id) } #endif //CONFIG_SPI_FLASH_ROM_IMPL +static esp_err_t IRAM_ATTR NOINLINE_ATTR read_unique_id(esp_flash_t* chip, uint64_t* out_uid) +{ + esp_err_t err = rom_spiflash_api_funcs->start(chip); + if (err != ESP_OK) { + return err; + } + + err = chip->chip_drv->read_unique_id(chip, out_uid); + + return rom_spiflash_api_funcs->end(chip, err); +} + +esp_err_t esp_flash_read_unique_chip_id(esp_flash_t *chip, uint64_t* out_uid) +{ + esp_err_t err = rom_spiflash_api_funcs->chip_check(&chip); + if (err != ESP_OK) { + return err; + } + if (out_uid == NULL) { + return ESP_ERR_INVALID_ARG; + }; + + return read_unique_id(chip, out_uid); +} + static esp_err_t IRAM_ATTR detect_spi_flash_chip(esp_flash_t *chip) { esp_err_t err; diff --git a/components/spi_flash/include/esp_flash.h b/components/spi_flash/include/esp_flash.h index 845d82f17c..c5adb279dc 100644 --- a/components/spi_flash/include/esp_flash.h +++ b/components/spi_flash/include/esp_flash.h @@ -156,6 +156,19 @@ esp_err_t esp_flash_read_id(esp_flash_t *chip, uint32_t *out_id); */ esp_err_t esp_flash_get_size(esp_flash_t *chip, uint32_t *out_size); +/** @brief Read flash unique ID via the common "RDUID" SPI flash command. + * + * @param chip Pointer to identify flash chip. Must have been successfully initialised via esp_flash_init(). + * @param[out] out_id Pointer to receive unique ID value. + * + * ID is a 64-bit value. + * + * @return + * - ESP_OK on success, or a flash error code if operation failed. + * - ESP_ERR_NOT_SUPPORTED if the chip doesn't support read id. + */ +esp_err_t esp_flash_read_unique_chip_id(esp_flash_t *chip, uint64_t *out_id); + /** @brief Erase flash chip contents * * @param chip Pointer to identify flash chip. Must have been successfully initialised via esp_flash_init() diff --git a/components/spi_flash/include/spi_flash_chip_driver.h b/components/spi_flash/include/spi_flash_chip_driver.h index 41a46ec0a4..6356291b78 100644 --- a/components/spi_flash/include/spi_flash_chip_driver.h +++ b/components/spi_flash/include/spi_flash_chip_driver.h @@ -188,6 +188,11 @@ struct spi_flash_chip_t { /** Setup flash suspend configuration. */ esp_err_t (*sus_setup)(esp_flash_t *chip); + + /** + * Read the chip unique ID. + */ + esp_err_t (*read_unique_id)(esp_flash_t *chip, uint64_t* flash_unique_id); }; /* Pointer to an array of pointers to all known drivers for flash chips. This array is used diff --git a/components/spi_flash/include/spi_flash_chip_generic.h b/components/spi_flash/include/spi_flash_chip_generic.h index de99c02d5e..90bfcf7deb 100644 --- a/components/spi_flash/include/spi_flash_chip_generic.h +++ b/components/spi_flash/include/spi_flash_chip_generic.h @@ -244,6 +244,18 @@ esp_err_t spi_flash_chip_generic_set_io_mode(esp_flash_t *chip); */ esp_err_t spi_flash_chip_generic_get_io_mode(esp_flash_t *chip, esp_flash_io_mode_t* out_quad_mode); +/** + * @brief Read the chip unique ID. + * + * @param chip Pointer to SPI flash chip to use. If NULL, esp_flash_default_chip is substituted. + * @param flash_unique_id Pointer to store output unique id. + * + * @return + * - ESP_OK if success + * - ESP_ERR_NOT_SUPPORTED if the chip doesn't support read id. + */ +esp_err_t spi_flash_chip_generic_read_unique_id(esp_flash_t *chip, uint64_t* flash_unique_id); + /** * Generic SPI flash chip_drv, uses all the above functions for its operations. * In default autodetection, this is used as a catchall if a more specific diff --git a/components/spi_flash/private_include/spi_flash_defs.h b/components/spi_flash/private_include/spi_flash_defs.h index 79e06669f3..cf26fda148 100644 --- a/components/spi_flash/private_include/spi_flash_defs.h +++ b/components/spi_flash/private_include/spi_flash_defs.h @@ -18,6 +18,7 @@ Suitable for use with spi_flash_hal_common_command static function. */ #define CMD_RDID 0x9F +#define CMD_RDUID 0x4B /* Read the flash unique ID*/ #define CMD_WRSR 0x01 #define SR_WIP (1<<0) /* Status register write-in-progress bit */ #define SR_WREN (1<<1) /* Status register write enable bit */ diff --git a/components/spi_flash/spi_flash_chip_boya.c b/components/spi_flash/spi_flash_chip_boya.c index 57e20e7b83..f55d346b06 100644 --- a/components/spi_flash/spi_flash_chip_boya.c +++ b/components/spi_flash/spi_flash_chip_boya.c @@ -77,4 +77,5 @@ const spi_flash_chip_t esp_flash_chip_boya = { .read_reg = spi_flash_chip_generic_read_reg, .yield = spi_flash_chip_generic_yield, .sus_setup = spi_flash_chip_boya_suspend_cmd_conf, + .read_unique_id = spi_flash_chip_generic_read_unique_id, }; diff --git a/components/spi_flash/spi_flash_chip_gd.c b/components/spi_flash/spi_flash_chip_gd.c index 54a2255566..36ded9aa6a 100644 --- a/components/spi_flash/spi_flash_chip_gd.c +++ b/components/spi_flash/spi_flash_chip_gd.c @@ -124,4 +124,5 @@ const spi_flash_chip_t esp_flash_chip_gd = { .read_reg = spi_flash_chip_generic_read_reg, .yield = spi_flash_chip_generic_yield, .sus_setup = spi_flash_chip_gd_suspend_cmd_conf, + .read_unique_id = spi_flash_chip_generic_read_unique_id, }; diff --git a/components/spi_flash/spi_flash_chip_generic.c b/components/spi_flash/spi_flash_chip_generic.c index e4011ff67b..9e1a78c0fe 100644 --- a/components/spi_flash/spi_flash_chip_generic.c +++ b/components/spi_flash/spi_flash_chip_generic.c @@ -58,10 +58,10 @@ const DRAM_ATTR flash_chip_op_timeout_t spi_flash_chip_generic_timeout = { .page_program_timeout = SPI_FLASH_GENERIC_PAGE_PROGRAM_TIMEOUT_MS * 1000, }; -#ifndef CONFIG_SPI_FLASH_ROM_IMPL - static const char TAG[] = "chip_generic"; +#ifndef CONFIG_SPI_FLASH_ROM_IMPL + esp_err_t spi_flash_chip_generic_probe(esp_flash_t *chip, uint32_t flash_id) { // This is the catch-all probe function, claim the chip always if nothing @@ -463,6 +463,27 @@ esp_err_t spi_flash_chip_generic_set_io_mode(esp_flash_t *chip) } #endif // CONFIG_SPI_FLASH_ROM_IMPL +esp_err_t spi_flash_chip_generic_read_unique_id(esp_flash_t *chip, uint64_t* flash_unique_id) +{ + uint64_t unique_id_buf = 0; + spi_flash_trans_t transfer = { + .command = CMD_RDUID, + .miso_len = 8, + .miso_data = ((uint8_t *)&unique_id_buf), + .dummy_bitlen = 32, //RDUID command followed by 4 bytes (32 bits) of dummy clocks. + }; + esp_err_t err = chip->host->driver->common_command(chip->host, &transfer); + + if (unique_id_buf == 0 || unique_id_buf == UINT64_MAX) { + ESP_EARLY_LOGE(TAG, "No response from device when trying to retrieve Unique ID\n"); + *flash_unique_id = unique_id_buf; + return ESP_ERR_NOT_SUPPORTED; + } + + *flash_unique_id = __builtin_bswap64(unique_id_buf); + return err; +} + static const char chip_name[] = "generic"; const spi_flash_chip_t esp_flash_chip_generic = { @@ -501,6 +522,7 @@ const spi_flash_chip_t esp_flash_chip_generic = { .read_reg = spi_flash_chip_generic_read_reg, .yield = spi_flash_chip_generic_yield, .sus_setup = spi_flash_chip_generic_suspend_cmd_conf, + .read_unique_id = spi_flash_chip_generic_read_unique_id, }; #ifndef CONFIG_SPI_FLASH_ROM_IMPL diff --git a/components/spi_flash/spi_flash_chip_issi.c b/components/spi_flash/spi_flash_chip_issi.c index b5cdbcb326..5ba031e0c5 100644 --- a/components/spi_flash/spi_flash_chip_issi.c +++ b/components/spi_flash/spi_flash_chip_issi.c @@ -107,4 +107,5 @@ const spi_flash_chip_t esp_flash_chip_issi = { .read_reg = spi_flash_chip_generic_read_reg, .yield = spi_flash_chip_generic_yield, .sus_setup = spi_flash_chip_issi_suspend_cmd_conf, + .read_unique_id = spi_flash_chip_generic_read_unique_id, }; diff --git a/components/spi_flash/spi_flash_chip_mxic.c b/components/spi_flash/spi_flash_chip_mxic.c index ed19db7611..3c74bda31d 100644 --- a/components/spi_flash/spi_flash_chip_mxic.c +++ b/components/spi_flash/spi_flash_chip_mxic.c @@ -15,6 +15,7 @@ #include #include "spi_flash_chip_generic.h" #include "spi_flash_defs.h" +#include "esp_log.h" /* Driver for MXIC flash chip */ @@ -51,6 +52,13 @@ esp_err_t spi_flash_chip_mxic_suspend_cmd_conf(esp_flash_t *chip) return chip->host->driver->sus_setup(chip->host, &sus_conf); } +esp_err_t spi_flash_chip_mxic_read_unique_id(esp_flash_t *chip, uint64_t* flash_unique_id) +{ + //MXIC not support read unique id. + ESP_LOGE(chip_name, "chip %s doesn't support reading unique id", chip->chip_drv->name); + return ESP_ERR_NOT_SUPPORTED; +} + // The mxic chip can use the functions for generic chips except from set read mode and probe, // So we only replace these two functions. const spi_flash_chip_t esp_flash_chip_mxic = { @@ -86,4 +94,5 @@ const spi_flash_chip_t esp_flash_chip_mxic = { .read_reg = spi_flash_chip_mxic_read_reg, .yield = spi_flash_chip_generic_yield, .sus_setup = spi_flash_chip_mxic_suspend_cmd_conf, + .read_unique_id = spi_flash_chip_mxic_read_unique_id, }; diff --git a/components/spi_flash/spi_flash_chip_winbond.c b/components/spi_flash/spi_flash_chip_winbond.c index 74ca36735e..f7da73b4c6 100644 --- a/components/spi_flash/spi_flash_chip_winbond.c +++ b/components/spi_flash/spi_flash_chip_winbond.c @@ -177,6 +177,7 @@ const spi_flash_chip_t esp_flash_chip_winbond = { .read_reg = spi_flash_chip_generic_read_reg, .yield = spi_flash_chip_generic_yield, .sus_setup = spi_flash_chip_generic_suspend_cmd_conf, + .read_unique_id = spi_flash_chip_generic_read_unique_id, };