mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-08 04:02:27 +00:00
esp_flash: support high capacity flash chips (32-bit address)
This commit is contained in:
@@ -149,6 +149,11 @@ bool esp_flash_chip_driver_initialized(const esp_flash_t *chip)
|
||||
|
||||
esp_err_t IRAM_ATTR esp_flash_init(esp_flash_t *chip)
|
||||
{
|
||||
// Chip init flow
|
||||
// 1. Read chip id
|
||||
// 2. (optional) Detect chip vendor
|
||||
// 3. Get basic parameters of the chip (size, dummy count, etc.)
|
||||
// 4. Init chip into desired mode (without breaking the cache!)
|
||||
esp_err_t err = ESP_OK;
|
||||
if (chip == NULL || chip->host == NULL || chip->host->driver == NULL ||
|
||||
((memspi_host_inst_t*)chip->host)->spi == NULL) {
|
||||
@@ -201,22 +206,33 @@ esp_err_t IRAM_ATTR esp_flash_init(esp_flash_t *chip)
|
||||
return rom_spiflash_api_funcs->end(chip, err);
|
||||
}
|
||||
|
||||
//this is not public, but useful in unit tests
|
||||
esp_err_t IRAM_ATTR esp_flash_read_chip_id(esp_flash_t* chip, uint32_t* flash_id)
|
||||
static esp_err_t IRAM_ATTR read_id_core(esp_flash_t* chip, uint32_t* out_id, bool sanity_check)
|
||||
{
|
||||
bool installed = esp_flash_chip_driver_initialized(chip);
|
||||
esp_err_t err = rom_spiflash_api_funcs->start(chip);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// Send generic RDID command twice, check for a matching result and retry in case we just powered on (inner
|
||||
// function fails if it sees all-ones or all-zeroes.)
|
||||
err = chip->host->driver->read_id(chip->host, flash_id);
|
||||
esp_err_t (*read_id_func)(void*, uint32_t*);
|
||||
void* read_id_arg;
|
||||
if (installed && chip->chip_drv->read_id) {
|
||||
read_id_func = (void*)chip->chip_drv->read_id;
|
||||
read_id_arg = (void*)chip;
|
||||
} else {
|
||||
//default option if the chip is not detected/chosen yet.
|
||||
read_id_func = (void*)chip->host->driver->read_id;
|
||||
read_id_arg = (void*)chip->host;
|
||||
}
|
||||
|
||||
if (err == ESP_OK) { // check we see the same ID twice, in case of transient power-on errors
|
||||
// Inner function fails if it sees all-ones or all-zeroes.
|
||||
err = read_id_func(read_id_arg, out_id);
|
||||
|
||||
if (sanity_check && err == ESP_OK) {
|
||||
// Send RDID command twice, check for a matching result and retry in case we just powered on
|
||||
uint32_t new_id;
|
||||
err = chip->host->driver->read_id(chip->host, &new_id);
|
||||
if (err == ESP_OK && (new_id != *flash_id)) {
|
||||
err = read_id_func(read_id_arg, &new_id);
|
||||
if (err == ESP_OK && (new_id != *out_id)) {
|
||||
err = ESP_ERR_FLASH_NOT_INITIALISED;
|
||||
}
|
||||
}
|
||||
@@ -224,6 +240,23 @@ esp_err_t IRAM_ATTR esp_flash_read_chip_id(esp_flash_t* chip, uint32_t* flash_id
|
||||
return rom_spiflash_api_funcs->end(chip, err);
|
||||
}
|
||||
|
||||
// Faster version with sanity check.
|
||||
// Called in esp_flash_init and unit test (though not public)
|
||||
esp_err_t esp_flash_read_chip_id(esp_flash_t* chip, uint32_t* out_id)
|
||||
{
|
||||
return read_id_core(chip, out_id, true);
|
||||
}
|
||||
|
||||
esp_err_t esp_flash_read_id(esp_flash_t* chip, uint32_t* out_id)
|
||||
{
|
||||
esp_err_t err = rom_spiflash_api_funcs->chip_check(&chip);
|
||||
//Accept uninitialized chip when reading chip id
|
||||
if (err != ESP_OK && !(err == ESP_ERR_FLASH_NOT_INITIALISED && chip != NULL)) return err;
|
||||
if (out_id == NULL) return ESP_ERR_INVALID_ARG;
|
||||
|
||||
return read_id_core(chip, out_id, false);
|
||||
}
|
||||
|
||||
static esp_err_t IRAM_ATTR detect_spi_flash_chip(esp_flash_t *chip)
|
||||
{
|
||||
esp_err_t err;
|
||||
@@ -271,23 +304,6 @@ static esp_err_t IRAM_ATTR detect_spi_flash_chip(esp_flash_t *chip)
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
esp_err_t IRAM_ATTR esp_flash_read_id(esp_flash_t *chip, uint32_t *out_id)
|
||||
{
|
||||
esp_err_t err = rom_spiflash_api_funcs->chip_check(&chip);
|
||||
//Accept uninitialized chip when reading chip id
|
||||
if (err != ESP_OK && !(err == ESP_ERR_FLASH_NOT_INITIALISED && chip != NULL)) return err;
|
||||
if (out_id == NULL) return ESP_ERR_INVALID_ARG;
|
||||
|
||||
err = rom_spiflash_api_funcs->start(chip);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
err = chip->host->driver->read_id(chip->host, out_id);
|
||||
|
||||
return rom_spiflash_api_funcs->end(chip, err);
|
||||
}
|
||||
|
||||
esp_err_t IRAM_ATTR esp_flash_get_size(esp_flash_t *chip, uint32_t *out_size)
|
||||
{
|
||||
esp_err_t err = rom_spiflash_api_funcs->chip_check(&chip);
|
||||
|
Reference in New Issue
Block a user