mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
spi_flash: partially move API functions out of IRAM
This commit is contained in:
parent
c5dfaec6b3
commit
61989e0fbb
@ -503,7 +503,27 @@ esp_err_t IRAM_ATTR esp_flash_set_protected_region(esp_flash_t *chip, const esp_
|
|||||||
return spiflash_end(chip, err);
|
return spiflash_end(chip, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t IRAM_ATTR esp_flash_read(esp_flash_t *chip, void *buffer, uint32_t address, uint32_t length)
|
static esp_err_t NOINLINE_ATTR IRAM_ATTR flash_read_core(esp_flash_t *chip, void* buffer_to_read, uint32_t address, uint32_t length_to_read, bool *out_read_success)
|
||||||
|
{
|
||||||
|
esp_err_t err = ESP_OK;
|
||||||
|
bool read_success = false;
|
||||||
|
|
||||||
|
read_success = false;
|
||||||
|
err = spiflash_start(chip);
|
||||||
|
|
||||||
|
if (err == ESP_OK) {
|
||||||
|
err = chip->chip_drv->read(chip, buffer_to_read, address, length_to_read);
|
||||||
|
}
|
||||||
|
if (err == ESP_OK) {
|
||||||
|
read_success = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = spiflash_end(chip, err);
|
||||||
|
*out_read_success = read_success;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_flash_read(esp_flash_t *chip, void *buffer, uint32_t address, uint32_t length)
|
||||||
{
|
{
|
||||||
if (length == 0) {
|
if (length == 0) {
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
@ -544,28 +564,17 @@ esp_err_t IRAM_ATTR esp_flash_read(esp_flash_t *chip, void *buffer, uint32_t add
|
|||||||
esp_err_t err = ESP_OK;
|
esp_err_t err = ESP_OK;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
err = spiflash_start(chip);
|
|
||||||
if (err != ESP_OK) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
//if required (dma buffer allocated), read to the buffer instead of the original buffer
|
//if required (dma buffer allocated), read to the buffer instead of the original buffer
|
||||||
uint8_t* buffer_to_read = (temp_buffer)? temp_buffer : buffer;
|
uint8_t* buffer_to_read = (temp_buffer)? temp_buffer : buffer;
|
||||||
|
|
||||||
// Length we will read this iteration is either the chunk size or the remaining length, whichever is smaller
|
// Length we will read this iteration is either the chunk size or the remaining length, whichever is smaller
|
||||||
size_t length_to_read = MIN(read_chunk_size, length);
|
size_t length_to_read = MIN(read_chunk_size, length);
|
||||||
|
|
||||||
if (err == ESP_OK) {
|
bool read_success;
|
||||||
err = chip->chip_drv->read(chip, buffer_to_read, address, length_to_read);
|
err = flash_read_core(chip, buffer_to_read, address, length_to_read, &read_success);
|
||||||
}
|
|
||||||
if (err != ESP_OK) {
|
|
||||||
spiflash_end(chip, err);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
//even if this is failed, the data is still valid, copy before quit
|
|
||||||
err = spiflash_end(chip, err);
|
|
||||||
|
|
||||||
//copy back to the original buffer
|
//copy back to the original buffer
|
||||||
if (temp_buffer) {
|
if (read_success && temp_buffer) {
|
||||||
memcpy(buffer, temp_buffer, length_to_read);
|
memcpy(buffer, temp_buffer, length_to_read);
|
||||||
}
|
}
|
||||||
address += length_to_read;
|
address += length_to_read;
|
||||||
@ -577,7 +586,28 @@ esp_err_t IRAM_ATTR esp_flash_read(esp_flash_t *chip, void *buffer, uint32_t add
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t IRAM_ATTR esp_flash_write(esp_flash_t *chip, const void *buffer, uint32_t address, uint32_t length)
|
// This function disable the cache, but when returning from this function, the cache should be enabled.
|
||||||
|
static esp_err_t IRAM_ATTR NOINLINE_ATTR flash_write_core(esp_flash_t *chip,
|
||||||
|
const void* write_buf, uint32_t write_addr, uint32_t write_len,
|
||||||
|
uint32_t address, uint32_t length, bool final)
|
||||||
|
{
|
||||||
|
bool bus_acquire = false; //controls whether the flash_end_flush_cache() needs to disable the cache again.
|
||||||
|
|
||||||
|
esp_err_t err = spiflash_start(chip);
|
||||||
|
|
||||||
|
if (err == ESP_OK) {
|
||||||
|
bus_acquire = true;
|
||||||
|
err = chip->chip_drv->write(chip, write_buf, write_addr, write_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bus_acquire) {
|
||||||
|
//on IDF v4.1, the flush is done in chip driver layer. Call spiflash_end() here.
|
||||||
|
err = spiflash_end(chip, err);
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_flash_write(esp_flash_t *chip, const void *buffer, uint32_t address, uint32_t length)
|
||||||
{
|
{
|
||||||
if (length == 0) {
|
if (length == 0) {
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
@ -596,31 +626,32 @@ esp_err_t IRAM_ATTR esp_flash_write(esp_flash_t *chip, const void *buffer, uint3
|
|||||||
by artificially cutting into MAX_WRITE_CHUNK parts (in an OS
|
by artificially cutting into MAX_WRITE_CHUNK parts (in an OS
|
||||||
environment, this prevents writing from causing interrupt or higher priority task
|
environment, this prevents writing from causing interrupt or higher priority task
|
||||||
starvation.) */
|
starvation.) */
|
||||||
|
uint32_t write_addr = address;
|
||||||
|
uint32_t len_remain = length;
|
||||||
do {
|
do {
|
||||||
uint32_t write_len;
|
uint32_t write_len;
|
||||||
const void *write_buf;
|
const void *write_buf;
|
||||||
uint32_t temp_buf[8];
|
uint32_t temp_buf[8];
|
||||||
if (direct_write) {
|
if (direct_write) {
|
||||||
write_len = MIN(length, MAX_WRITE_CHUNK);
|
write_len = MIN(len_remain, MAX_WRITE_CHUNK);
|
||||||
write_buf = buffer;
|
write_buf = buffer;
|
||||||
} else {
|
} else {
|
||||||
write_len = MIN(length, sizeof(temp_buf));
|
write_len = MIN(len_remain, sizeof(temp_buf));
|
||||||
memcpy(temp_buf, buffer, write_len);
|
memcpy(temp_buf, buffer, write_len);
|
||||||
write_buf = temp_buf;
|
write_buf = temp_buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = spiflash_start(chip);
|
bool final = (len_remain == write_len);
|
||||||
if (err != ESP_OK) {
|
//This function ensures cache enabled when returned
|
||||||
return err;
|
err = flash_write_core(chip, write_buf, write_addr, write_len, address, length, final);
|
||||||
|
if (err != ESP_OK || final) {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = chip->chip_drv->write(chip, write_buf, address, write_len);
|
len_remain -= write_len;
|
||||||
|
assert(len_remain < length);
|
||||||
address += write_len;
|
write_addr += write_len;
|
||||||
buffer = (void *)((intptr_t)buffer + write_len);
|
buffer = (void *)((intptr_t)buffer + write_len);
|
||||||
length -= write_len;
|
|
||||||
|
|
||||||
err = spiflash_end(chip, err);
|
|
||||||
} while (err == ESP_OK && length > 0);
|
} while (err == ESP_OK && length > 0);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user