mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
spi_flash: fix spi_flash_read into buffer in external RAM, add test
This commit is contained in:
parent
099565635b
commit
8990549e89
@ -230,9 +230,9 @@ esp_err_t IRAM_ATTR spi_flash_write(size_t dst, const void *srcv, size_t size)
|
||||
/* If src buffer is 4-byte aligned as well and is not in a region that requires cache access to be enabled, we
|
||||
* can write directly without buffering in RAM. */
|
||||
#ifdef ESP_PLATFORM
|
||||
bool direct_write = ( (uintptr_t) srcc >= 0x3FFAE000
|
||||
&& (uintptr_t) srcc < 0x40000000
|
||||
&& ((uintptr_t) srcc + mid_off) % 4 == 0 );
|
||||
bool direct_write = esp_ptr_internal(srcc)
|
||||
&& esp_ptr_byte_accessible(srcc)
|
||||
&& ((uintptr_t) srcc + mid_off) % 4 == 0;
|
||||
#else
|
||||
bool direct_write = true;
|
||||
#endif
|
||||
@ -395,18 +395,38 @@ esp_err_t IRAM_ATTR spi_flash_read(size_t src, void *dstv, size_t size)
|
||||
size_t pad_right_src = (src + pad_left_size + mid_size) & ~3U;
|
||||
size_t pad_right_off = (pad_right_src - src);
|
||||
size_t pad_right_size = (size - pad_right_off);
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
bool direct_read = esp_ptr_internal(dstc)
|
||||
&& esp_ptr_byte_accessible(dstc)
|
||||
&& ((uintptr_t) dstc + dst_mid_off) % 4 == 0;
|
||||
#else
|
||||
bool direct_read = true;
|
||||
#endif
|
||||
if (mid_size > 0) {
|
||||
uint32_t mid_remaining = mid_size;
|
||||
uint32_t mid_read = 0;
|
||||
while (mid_remaining > 0) {
|
||||
uint32_t read_size = MIN(mid_remaining, MAX_READ_CHUNK);
|
||||
rc = esp_rom_spiflash_read(src + src_mid_off + mid_read, (uint32_t *) (dstc + dst_mid_off + mid_read), read_size);
|
||||
uint32_t read_buf[8];
|
||||
uint8_t *read_dst_final = dstc + dst_mid_off + mid_read;
|
||||
uint8_t *read_dst = read_dst_final;
|
||||
if (!direct_read) {
|
||||
read_size = MIN(read_size, sizeof(read_buf));
|
||||
read_dst = (uint8_t *) read_buf;
|
||||
}
|
||||
rc = esp_rom_spiflash_read(src + src_mid_off + mid_read,
|
||||
(uint32_t *) read_dst, read_size);
|
||||
if (rc != ESP_ROM_SPIFLASH_RESULT_OK) {
|
||||
goto out;
|
||||
}
|
||||
mid_remaining -= read_size;
|
||||
mid_read += read_size;
|
||||
if (mid_remaining > 0) {
|
||||
if (!direct_read) {
|
||||
spi_flash_guard_end();
|
||||
memcpy(read_dst_final, read_buf, read_size);
|
||||
spi_flash_guard_start();
|
||||
} else if (mid_remaining > 0) {
|
||||
/* Drop guard momentarily, allows other tasks to preempt */
|
||||
spi_flash_guard_end();
|
||||
spi_flash_guard_start();
|
||||
@ -419,7 +439,13 @@ esp_err_t IRAM_ATTR spi_flash_read(size_t src, void *dstv, size_t size)
|
||||
* Note that the shift can be left (src_mid_off < dst_mid_off) or right.
|
||||
*/
|
||||
if (src_mid_off != dst_mid_off) {
|
||||
if (!direct_read) {
|
||||
spi_flash_guard_end();
|
||||
}
|
||||
memmove(dstc + src_mid_off, dstc + dst_mid_off, mid_size);
|
||||
if (!direct_read) {
|
||||
spi_flash_guard_start();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pad_left_size > 0) {
|
||||
@ -429,7 +455,13 @@ esp_err_t IRAM_ATTR spi_flash_read(size_t src, void *dstv, size_t size)
|
||||
goto out;
|
||||
}
|
||||
COUNTER_ADD_BYTES(read, 4);
|
||||
if (!direct_read) {
|
||||
spi_flash_guard_end();
|
||||
}
|
||||
memcpy(dstc, ((uint8_t *) &t) + (4 - pad_left_size), pad_left_size);
|
||||
if (!direct_read) {
|
||||
spi_flash_guard_start();
|
||||
}
|
||||
}
|
||||
if (pad_right_size > 0) {
|
||||
uint32_t t[2];
|
||||
@ -439,7 +471,13 @@ esp_err_t IRAM_ATTR spi_flash_read(size_t src, void *dstv, size_t size)
|
||||
goto out;
|
||||
}
|
||||
COUNTER_ADD_BYTES(read, read_size);
|
||||
if (!direct_read) {
|
||||
spi_flash_guard_end();
|
||||
}
|
||||
memcpy(dstc + pad_right_off, t, pad_right_size);
|
||||
if (!direct_read) {
|
||||
spi_flash_guard_start();
|
||||
}
|
||||
}
|
||||
out:
|
||||
spi_flash_guard_end();
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "../cache_utils.h"
|
||||
#include "soc/timer_group_struct.h"
|
||||
#include "soc/timer_group_reg.h"
|
||||
#include "esp_heap_caps.h"
|
||||
|
||||
/* Base offset in flash for tests. */
|
||||
static size_t start;
|
||||
@ -217,3 +218,51 @@ TEST_CASE("Test spi_flash_write", "[spi_flash]")
|
||||
ESP_ERROR_CHECK(spi_flash_write(start, (char *) 0x40078000, 16));
|
||||
ESP_ERROR_CHECK(spi_flash_write(start, (char *) 0x40080000, 16));
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SPIRAM_SUPPORT
|
||||
|
||||
TEST_CASE("spi_flash_read can read into buffer in external RAM", "[spi_flash]")
|
||||
{
|
||||
uint8_t* buf_ext = (uint8_t*) heap_caps_malloc(SPI_FLASH_SEC_SIZE, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
|
||||
TEST_ASSERT_NOT_NULL(buf_ext);
|
||||
|
||||
uint8_t* buf_int = (uint8_t*) heap_caps_malloc(SPI_FLASH_SEC_SIZE, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
|
||||
TEST_ASSERT_NOT_NULL(buf_int);
|
||||
|
||||
TEST_ESP_OK(spi_flash_read(0x1000, buf_int, SPI_FLASH_SEC_SIZE));
|
||||
TEST_ESP_OK(spi_flash_read(0x1000, buf_ext, SPI_FLASH_SEC_SIZE));
|
||||
|
||||
TEST_ASSERT_EQUAL(0, memcmp(buf_ext, buf_int, SPI_FLASH_SEC_SIZE));
|
||||
free(buf_ext);
|
||||
free(buf_int);
|
||||
}
|
||||
|
||||
TEST_CASE("spi_flash_write can write from external RAM buffer", "[spi_flash]")
|
||||
{
|
||||
uint32_t* buf_ext = (uint32_t*) heap_caps_malloc(SPI_FLASH_SEC_SIZE, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
|
||||
TEST_ASSERT_NOT_NULL(buf_ext);
|
||||
|
||||
srand(0);
|
||||
for (size_t i = 0; i < SPI_FLASH_SEC_SIZE / sizeof(uint32_t); i++)
|
||||
{
|
||||
uint32_t val = rand();
|
||||
buf_ext[i] = val;
|
||||
}
|
||||
|
||||
uint8_t* buf_int = (uint8_t*) heap_caps_malloc(SPI_FLASH_SEC_SIZE, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
|
||||
TEST_ASSERT_NOT_NULL(buf_int);
|
||||
|
||||
/* Write to flash from buf_ext */
|
||||
const esp_partition_t *part = get_test_data_partition();
|
||||
TEST_ESP_OK(spi_flash_erase_range(part->address, SPI_FLASH_SEC_SIZE));
|
||||
TEST_ESP_OK(spi_flash_write(part->address, buf_ext, SPI_FLASH_SEC_SIZE));
|
||||
|
||||
/* Read back to buf_int and compare */
|
||||
TEST_ESP_OK(spi_flash_read(part->address, buf_int, SPI_FLASH_SEC_SIZE));
|
||||
TEST_ASSERT_EQUAL(0, memcmp(buf_ext, buf_int, SPI_FLASH_SEC_SIZE));
|
||||
|
||||
free(buf_ext);
|
||||
free(buf_int);
|
||||
}
|
||||
|
||||
#endif // CONFIG_SPIRAM_SUPPORT
|
||||
|
Loading…
x
Reference in New Issue
Block a user