From 875ae6a134038bfcba8cb497ddbbef97b7a421d1 Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Tue, 5 Sep 2017 17:29:57 +0800 Subject: [PATCH 1/2] Add option to allocate external RAM using heap_alloc_caps --- components/esp32/Kconfig | 3 +- components/esp32/cpu_start.c | 9 ++++ components/esp32/include/esp_spiram.h | 6 +++ components/esp32/spiram.c | 8 ++++ .../esp32/test/test_spiram_cache_flush.c | 44 +++++++++++++++++-- components/heap/heap_caps.c | 18 ++++++++ components/heap/heap_caps_init.c | 2 +- components/heap/heap_private.h | 10 +++++ components/heap/heap_trace.c | 37 ++++++++++++---- components/heap/include/esp_heap_caps.h | 4 +- components/newlib/syscalls.c | 15 +++++-- components/soc/esp32/soc_memory_layout.c | 38 ++++++++-------- 12 files changed, 154 insertions(+), 40 deletions(-) diff --git a/components/esp32/Kconfig b/components/esp32/Kconfig index 837a73afa..65f88dd91 100644 --- a/components/esp32/Kconfig +++ b/components/esp32/Kconfig @@ -57,8 +57,7 @@ choice SPIRAM_USE config SPIRAM_USE_MEMMAP bool "Integrate RAM into ESP32 memory map" config SPIRAM_USE_CAPS_ALLOC - bool "Make RAM allocatable using heap_caps_malloc(..., MALLOC_CAP_SPISRAM)" - depends on TO_BE_DONE + bool "Make RAM allocatable using heap_caps_malloc(..., MALLOC_CAP_SPIRAM)" config SPIRAM_USE_MALLOC bool "Make RAM allocatable using malloc as well" depends on TO_BE_DONE diff --git a/components/esp32/cpu_start.c b/components/esp32/cpu_start.c index 33139b4f1..506c9638d 100644 --- a/components/esp32/cpu_start.c +++ b/components/esp32/cpu_start.c @@ -255,6 +255,15 @@ void start_cpu0_default(void) { esp_err_t err; esp_setup_syscall_table(); + +#if CONFIG_SPIRAM_BOOT_INIT && (CONFIG_SPIRAM_USE_CAPS_ALLOC || CONFIG_SPIRAM_USE_MALLOC) + esp_err_t r=esp_spiram_add_to_heapalloc(); + if (r != ESP_OK) { + ESP_EARLY_LOGE(TAG, "External RAM could not be added to heap!"); + abort(); + } +#endif + //Enable trace memory and immediately start trace. #if CONFIG_ESP32_TRAX #if CONFIG_ESP32_TRAX_TWOBANKS diff --git a/components/esp32/include/esp_spiram.h b/components/esp32/include/esp_spiram.h index 2eb9c08e5..985403529 100644 --- a/components/esp32/include/esp_spiram.h +++ b/components/esp32/include/esp_spiram.h @@ -39,6 +39,12 @@ esp_err_t esp_spiram_init(); bool esp_spiram_test(); +/** + * @brief Add the initialized SPI RAM to the heap allocator. + */ +esp_err_t esp_spiram_add_to_heapalloc(); + + /** * @brief Get the size of the attached SPI RAM chip selected in menuconfig * diff --git a/components/esp32/spiram.c b/components/esp32/spiram.c index 2cd5d52fc..aff3b9ce8 100644 --- a/components/esp32/spiram.c +++ b/components/esp32/spiram.c @@ -28,6 +28,8 @@ we add more types of external RAM memory, this can be made into a more intellige #include "freertos/FreeRTOS.h" #include "freertos/xtensa_api.h" #include "soc/soc.h" +#include "esp_heap_caps_init.h" +#include "soc/soc_memory_layout.h" #include "soc/dport_reg.h" #include "rom/cache.h" @@ -120,6 +122,12 @@ esp_err_t esp_spiram_init() } +esp_err_t esp_spiram_add_to_heapalloc() +{ + //Add entire external RAM region to heap allocator. Heap allocator knows the capabilities of this type of memory, so there's + //no need to explicitly specify them. + return heap_caps_add_region((intptr_t)SOC_EXTRAM_DATA_LOW, (intptr_t)SOC_EXTRAM_DATA_LOW + CONFIG_SPIRAM_SIZE-1); +} size_t esp_spiram_get_size() { diff --git a/components/esp32/test/test_spiram_cache_flush.c b/components/esp32/test/test_spiram_cache_flush.c index 8fdf8f527..3d6f75f1f 100644 --- a/components/esp32/test/test_spiram_cache_flush.c +++ b/components/esp32/test/test_spiram_cache_flush.c @@ -56,12 +56,14 @@ TEST_CASE("Spiram cache flush on mmap", "[spiram][ignore]") void *mem[2]; res[0]=0; res[1]=0; #if CONFIG_SPIRAM_USE_CAPS_ALLOC - mem[0]=pvPortMallocCaps(TSTSZ, MALLOC_CAP_SPIRAM); - mem[1]=pvPortMallocCaps(TSTSZ, MALLOC_CAP_SPIRAM); + mem[0]=heap_caps_malloc(TSTSZ, MALLOC_CAP_SPIRAM); + mem[1]=heap_caps_malloc(TSTSZ, MALLOC_CAP_SPIRAM); #else mem[0]=(void*)0x3f800000; mem[1]=(void*)0x3f800000+TSTSZ; #endif + assert(mem[0]); + assert(mem[1]); TaskHandle_t th[2]; err[0]=0; err[1]=0; printf("Creating tasks\n"); @@ -99,12 +101,14 @@ TEST_CASE("Spiram cache flush on write/read", "[spiram][ignore]") void *mem[2]; res[0]=0; res[1]=0; #if CONFIG_SPIRAM_USE_CAPS_ALLOC - mem[0]=pvPortMallocCaps(TSTSZ, MALLOC_CAP_SPIRAM); - mem[1]=pvPortMallocCaps(TSTSZ, MALLOC_CAP_SPIRAM); + mem[0]=heap_caps_malloc(TSTSZ, MALLOC_CAP_SPIRAM); + mem[1]=heap_caps_malloc(TSTSZ, MALLOC_CAP_SPIRAM); #else mem[0]=(void*)0x3f800000; mem[1]=(void*)0x3f800000+TSTSZ; #endif + assert(mem[0]); + assert(mem[1]); TaskHandle_t th[2]; const esp_partition_t* part = get_test_data_partition(); assert(part!=NULL); @@ -138,4 +142,36 @@ TEST_CASE("Spiram cache flush on write/read", "[spiram][ignore]") #endif } +IRAM_ATTR TEST_CASE("Spiram memcmp weirdness at 80MHz", "[spiram][ignore]") { + char *mem1=malloc(0x10000); +#if CONFIG_SPIRAM_USE_CAPS_ALLOC + char *mem2=heap_caps_malloc(0x10000, MALLOC_CAP_SPIRAM); +#else + char *mem2=(void*)0x3f800000; +#endif + +#if !CONFIG_SPIRAM_SPEED_80M + printf("**** WARNING **** Spi memory isn't running at 80MHz, so this test is somewhat meaningless.\n"); +#endif + + printf("RAM: Got %p and %p\n", mem1, mem2); + assert(mem1); + assert(mem2); + for (int i=0; i<0x10000; i++) mem1[i]=i^0xAAAAAAAA; + + for (int cycle=1; cycle<100; cycle++) { + memcpy(mem2, mem1, 0x10000); + if (memcmp(mem1, mem2, 0x10000)!=0) { + printf("Memcmp failed! Cycle %d\n", cycle); + for (int i=0; i<0x10000; i++) { + if (mem1[i]!=mem2[i]) { + printf("Found real difference at index %d: 0x%x vs 0x%x\n", i, mem1[i], mem2[i]); + break; + } + } + } + } +} + + #endif //CONFIG_SPIRAM_USE_CAPS_ALLOC || CONFIG_SPIRAM_USE_MEMMAP diff --git a/components/heap/heap_caps.c b/components/heap/heap_caps.c index 1c7620292..2edf1dbc4 100644 --- a/components/heap/heap_caps.c +++ b/components/heap/heap_caps.c @@ -133,6 +133,24 @@ IRAM_ATTR void *heap_caps_malloc( size_t size, uint32_t caps ) return NULL; } +/* + Default memory allocation implementation. Should return standard 8-bit memory. malloc() essentially resolves to this function. +*/ +IRAM_ATTR void *heap_caps_malloc_default( size_t size ) +{ + return heap_caps_malloc( size, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL ); +} + +/* + Same for realloc() + Note: keep the logic in here the same as in heap_caps_malloc_default (or merge the two as soon as this gets more complex...) + */ +IRAM_ATTR void *heap_caps_realloc_default( void *ptr, size_t size ) +{ + return heap_caps_realloc( ptr, size, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL ); +} + + /* Find the heap which belongs to ptr, or return NULL if it's not in any heap. diff --git a/components/heap/heap_caps_init.c b/components/heap/heap_caps_init.c index 36d75674d..9f88c87d5 100644 --- a/components/heap/heap_caps_init.c +++ b/components/heap/heap_caps_init.c @@ -180,7 +180,7 @@ void heap_caps_init() heap_t *heaps_array = NULL; for (int i = 0; i < num_heaps; i++) { - if (heap_caps_match(&temp_heaps[i], MALLOC_CAP_8BIT)) { + if (heap_caps_match(&temp_heaps[i], MALLOC_CAP_8BIT|MALLOC_CAP_INTERNAL)) { /* use the first DRAM heap which can fit the data */ heaps_array = multi_heap_malloc(temp_heaps[i].heap, sizeof(heap_t) * num_heaps); if (heaps_array != NULL) { diff --git a/components/heap/heap_private.h b/components/heap/heap_private.h index 58ce307f6..47d8cc55f 100644 --- a/components/heap/heap_private.h +++ b/components/heap/heap_private.h @@ -48,6 +48,16 @@ extern SLIST_HEAD(registered_heap_ll, heap_t_) registered_heaps; bool heap_caps_match(const heap_t *heap, uint32_t caps); + +/* + Because we don't want to add _another_ known allocation method to the stack of functions to trace wrt memory tracing, + these are declared private. The newlib malloc()/realloc() implementation also calls these, so they are declared + separately in newlib/syscalls.c. +*/ +void *heap_caps_realloc_default(void *p, size_t size); +void *heap_caps_malloc_default(size_t size); + + #ifdef __cplusplus } #endif diff --git a/components/heap/heap_trace.c b/components/heap/heap_trace.c index 8e9a898ca..b1da4415e 100644 --- a/components/heap/heap_trace.c +++ b/components/heap/heap_trace.c @@ -25,6 +25,8 @@ #include "freertos/task.h" #include "soc/soc_memory_layout.h" +#include "heap_private.h" + #define STACK_DEPTH CONFIG_HEAP_TRACING_STACK_DEPTH static portMUX_TYPE trace_mux = portMUX_INITIALIZER_UNLOCKED; @@ -303,13 +305,25 @@ static IRAM_ATTR __attribute__((noinline)) void get_call_stack(void **callers) _Static_assert(STACK_DEPTH >= 0 && STACK_DEPTH <= 10, "CONFIG_HEAP_TRACING_STACK_DEPTH must be in range 0-10"); +typedef enum { + TRACE_MALLOC_CAPS, + TRACE_MALLOC_DEFAULT +} trace_malloc_mode_t; + + void *__real_heap_caps_malloc(size_t size, uint32_t caps); /* trace any 'malloc' event */ -static IRAM_ATTR __attribute__((noinline)) void *trace_malloc(size_t size, uint32_t caps) +static IRAM_ATTR __attribute__((noinline)) void *trace_malloc(size_t size, uint32_t caps, trace_malloc_mode_t mode) { uint32_t ccount = get_ccount(); - void *p = __real_heap_caps_malloc(size, caps); + void *p; + if ( mode == TRACE_MALLOC_CAPS ) { + p = __real_heap_caps_malloc(size, caps); + } else { //TRACE_MALLOC_DEFAULT + p = heap_caps_malloc_default(size); + } + if (tracing && p != NULL) { heap_trace_record_t rec = { .address = p, @@ -338,7 +352,7 @@ static IRAM_ATTR __attribute__((noinline)) void trace_free(void *p) void * __real_heap_caps_realloc(void *p, size_t size, uint32_t caps); /* trace any 'realloc' event */ -static IRAM_ATTR __attribute__((noinline)) void *trace_realloc(void *p, size_t size, uint32_t caps) +static IRAM_ATTR __attribute__((noinline)) void *trace_realloc(void *p, size_t size, uint32_t caps, trace_malloc_mode_t mode) { void *callers[STACK_DEPTH]; uint32_t ccount = get_ccount(); @@ -346,7 +360,12 @@ static IRAM_ATTR __attribute__((noinline)) void *trace_realloc(void *p, size_t s get_call_stack(callers); record_free(p, callers); } - void *r = __real_heap_caps_realloc(p, size, caps); + void *r; + if (mode == TRACE_MALLOC_CAPS ) { + r = __real_heap_caps_realloc(p, size, caps); + } else { //TRACE_MALLOC_DEFAULT + r = heap_caps_realloc_default(p, size); + } if (tracing && r != NULL) { get_call_stack(callers); if (p != NULL) { @@ -370,7 +389,7 @@ static IRAM_ATTR __attribute__((noinline)) void *trace_realloc(void *p, size_t s IRAM_ATTR void *__wrap_malloc(size_t size) { - return trace_malloc(size, MALLOC_CAP_8BIT); + return trace_malloc(size, 0, TRACE_MALLOC_DEFAULT); } IRAM_ATTR void __wrap_free(void *p) @@ -380,13 +399,13 @@ IRAM_ATTR void __wrap_free(void *p) IRAM_ATTR void *__wrap_realloc(void *p, size_t size) { - return trace_realloc(p, size, MALLOC_CAP_8BIT); + return trace_realloc(p, size, 0, TRACE_MALLOC_DEFAULT); } IRAM_ATTR void *__wrap_calloc(size_t nmemb, size_t size) { size = size * nmemb; - void *result = trace_malloc(size, MALLOC_CAP_8BIT); + void *result = trace_malloc(size, 0, TRACE_MALLOC_DEFAULT); if (result != NULL) { memset(result, 0, size); } @@ -395,12 +414,12 @@ IRAM_ATTR void *__wrap_calloc(size_t nmemb, size_t size) IRAM_ATTR void *__wrap_heap_caps_malloc(size_t size, uint32_t caps) { - return trace_malloc(size, caps); + return trace_malloc(size, caps, TRACE_MALLOC_CAPS); } IRAM_ATTR void __wrap_heap_caps_free(void *p) __attribute__((alias("__wrap_free"))); IRAM_ATTR void *__wrap_heap_caps_realloc(void *p, size_t size, uint32_t caps) { - return trace_realloc(p, size, caps); + return trace_realloc(p, size, caps, TRACE_MALLOC_CAPS); } diff --git a/components/heap/include/esp_heap_caps.h b/components/heap/include/esp_heap_caps.h index 2b2eb579e..022ae669a 100644 --- a/components/heap/include/esp_heap_caps.h +++ b/components/heap/include/esp_heap_caps.h @@ -30,7 +30,8 @@ #define MALLOC_CAP_PID5 (1<<7) ///< Memory must be mapped to PID5 memory space (PIDs are not currently used) #define MALLOC_CAP_PID6 (1<<8) ///< Memory must be mapped to PID6 memory space (PIDs are not currently used) #define MALLOC_CAP_PID7 (1<<9) ///< Memory must be mapped to PID7 memory space (PIDs are not currently used) -#define MALLOC_CAP_SPISRAM (1<<10) ///< Memory must be in SPI SRAM +#define MALLOC_CAP_SPIRAM (1<<10) ///< Memory must be in SPI RAM +#define MALLOC_CAP_INTERNAL (1<<11) ///< Memory must be internal; specifically it should not disappear when flash/spiram cache is switched off #define MALLOC_CAP_INVALID (1<<31) ///< Memory can't be used / list end marker /** @@ -48,6 +49,7 @@ */ void *heap_caps_malloc(size_t size, uint32_t caps); + /** * @brief Free memory previously allocated via heap_caps_malloc() or heap_caps_realloc(). * diff --git a/components/newlib/syscalls.c b/components/newlib/syscalls.c index f32e910b7..f4528f6ea 100644 --- a/components/newlib/syscalls.c +++ b/components/newlib/syscalls.c @@ -23,9 +23,18 @@ #include "freertos/FreeRTOS.h" #include "esp_heap_caps.h" + +/* + These contain the business logic for the malloc() and realloc() implementation. Because of heap tracing + wrapping reasons, we do not want these to be a public api, however, so they're not defined publicly. +*/ +extern void *heap_caps_malloc_default( size_t size ); +extern void *heap_caps_realloc_default( void *ptr, size_t size ); + + void* IRAM_ATTR _malloc_r(struct _reent *r, size_t size) { - return heap_caps_malloc( size, MALLOC_CAP_8BIT ); + return heap_caps_malloc_default( size ); } void IRAM_ATTR _free_r(struct _reent *r, void* ptr) @@ -35,12 +44,12 @@ void IRAM_ATTR _free_r(struct _reent *r, void* ptr) void* IRAM_ATTR _realloc_r(struct _reent *r, void* ptr, size_t size) { - return heap_caps_realloc( ptr, size, MALLOC_CAP_8BIT ); + return heap_caps_realloc_default( ptr, size ); } void* IRAM_ATTR _calloc_r(struct _reent *r, size_t count, size_t size) { - void* result = heap_caps_malloc(count * size, MALLOC_CAP_8BIT); + void* result = heap_caps_malloc_default(count * size); if (result) { bzero(result, count * size); } diff --git a/components/soc/esp32/soc_memory_layout.c b/components/soc/esp32/soc_memory_layout.c index 19d2b8a95..dce4ff8b4 100644 --- a/components/soc/esp32/soc_memory_layout.c +++ b/components/soc/esp32/soc_memory_layout.c @@ -40,28 +40,28 @@ The prioritised capabilities work roughly like this: */ const soc_memory_type_desc_t soc_memory_types[] = { //Type 0: Plain ole D-port RAM - { "DRAM", { MALLOC_CAP_DMA|MALLOC_CAP_8BIT, MALLOC_CAP_32BIT, 0 }, false, false}, + { "DRAM", { MALLOC_CAP_DMA|MALLOC_CAP_8BIT|MALLOC_CAP_INTERNAL, MALLOC_CAP_32BIT, 0 }, false, false}, //Type 1: Plain ole D-port RAM which has an alias on the I-port //(This DRAM is also the region used by ROM during startup) - { "D/IRAM", { 0, MALLOC_CAP_DMA|MALLOC_CAP_8BIT, MALLOC_CAP_32BIT|MALLOC_CAP_EXEC }, true, true}, + { "D/IRAM", { 0, MALLOC_CAP_DMA|MALLOC_CAP_8BIT|MALLOC_CAP_INTERNAL, MALLOC_CAP_32BIT|MALLOC_CAP_EXEC }, true, true}, //Type 2: IRAM - { "IRAM", { MALLOC_CAP_EXEC|MALLOC_CAP_32BIT, 0, 0 }, false, false}, + { "IRAM", { MALLOC_CAP_EXEC|MALLOC_CAP_32BIT|MALLOC_CAP_INTERNAL, 0, 0 }, false, false}, //Type 3-8: PID 2-7 IRAM - { "PID2IRAM", { MALLOC_CAP_PID2, 0, MALLOC_CAP_EXEC|MALLOC_CAP_32BIT }, false, false}, - { "PID3IRAM", { MALLOC_CAP_PID3, 0, MALLOC_CAP_EXEC|MALLOC_CAP_32BIT }, false, false}, - { "PID4IRAM", { MALLOC_CAP_PID4, 0, MALLOC_CAP_EXEC|MALLOC_CAP_32BIT }, false, false}, - { "PID5IRAM", { MALLOC_CAP_PID5, 0, MALLOC_CAP_EXEC|MALLOC_CAP_32BIT }, false, false}, - { "PID6IRAM", { MALLOC_CAP_PID6, 0, MALLOC_CAP_EXEC|MALLOC_CAP_32BIT }, false, false}, - { "PID7IRAM", { MALLOC_CAP_PID7, 0, MALLOC_CAP_EXEC|MALLOC_CAP_32BIT }, false, false}, + { "PID2IRAM", { MALLOC_CAP_PID2|MALLOC_CAP_INTERNAL, 0, MALLOC_CAP_EXEC|MALLOC_CAP_32BIT }, false, false}, + { "PID3IRAM", { MALLOC_CAP_PID3|MALLOC_CAP_INTERNAL, 0, MALLOC_CAP_EXEC|MALLOC_CAP_32BIT }, false, false}, + { "PID4IRAM", { MALLOC_CAP_PID4|MALLOC_CAP_INTERNAL, 0, MALLOC_CAP_EXEC|MALLOC_CAP_32BIT }, false, false}, + { "PID5IRAM", { MALLOC_CAP_PID5|MALLOC_CAP_INTERNAL, 0, MALLOC_CAP_EXEC|MALLOC_CAP_32BIT }, false, false}, + { "PID6IRAM", { MALLOC_CAP_PID6|MALLOC_CAP_INTERNAL, 0, MALLOC_CAP_EXEC|MALLOC_CAP_32BIT }, false, false}, + { "PID7IRAM", { MALLOC_CAP_PID7|MALLOC_CAP_INTERNAL, 0, MALLOC_CAP_EXEC|MALLOC_CAP_32BIT }, false, false}, //Type 9-14: PID 2-7 DRAM - { "PID2DRAM", { MALLOC_CAP_PID2, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT }, false, false}, - { "PID3DRAM", { MALLOC_CAP_PID3, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT }, false, false}, - { "PID4DRAM", { MALLOC_CAP_PID4, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT }, false, false}, - { "PID5DRAM", { MALLOC_CAP_PID5, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT }, false, false}, - { "PID6DRAM", { MALLOC_CAP_PID6, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT }, false, false}, - { "PID7DRAM", { MALLOC_CAP_PID7, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT }, false, false}, + { "PID2DRAM", { MALLOC_CAP_PID2|MALLOC_CAP_INTERNAL, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT }, false, false}, + { "PID3DRAM", { MALLOC_CAP_PID3|MALLOC_CAP_INTERNAL, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT }, false, false}, + { "PID4DRAM", { MALLOC_CAP_PID4|MALLOC_CAP_INTERNAL, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT }, false, false}, + { "PID5DRAM", { MALLOC_CAP_PID5|MALLOC_CAP_INTERNAL, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT }, false, false}, + { "PID6DRAM", { MALLOC_CAP_PID6|MALLOC_CAP_INTERNAL, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT }, false, false}, + { "PID7DRAM", { MALLOC_CAP_PID7|MALLOC_CAP_INTERNAL, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT }, false, false}, //Type 15: SPI SRAM data - { "SPISRAM", { MALLOC_CAP_SPISRAM, 0, MALLOC_CAP_DMA|MALLOC_CAP_8BIT|MALLOC_CAP_32BIT}, false, false}, + { "SPIRAM", { MALLOC_CAP_SPIRAM, 0, MALLOC_CAP_DMA|MALLOC_CAP_8BIT|MALLOC_CAP_32BIT}, false, false}, }; const size_t soc_memory_type_count = sizeof(soc_memory_types)/sizeof(soc_memory_type_desc_t); @@ -73,7 +73,7 @@ Because of requirements in the coalescing code which merges adjacent regions, th from low to high start address. */ const soc_memory_region_t soc_memory_regions[] = { - { 0x3F800000, 0x20000, 15, 0}, //SPI SRAM, if available + { 0x3F800000, 0x400000, 15, 0}, //SPI SRAM, if available { 0x3FFAE000, 0x2000, 0, 0}, //pool 16 <- used for rom code { 0x3FFB0000, 0x8000, 0, 0}, //pool 15 <- if BT is enabled, used as BT HW shared memory { 0x3FFB8000, 0x8000, 0, 0}, //pool 14 <- if BT is enabled, used data memory for BT ROM functions. @@ -170,9 +170,7 @@ const soc_reserved_region_t soc_reserved_regions[] = { #endif #endif -#if 1 // SPI ram not supported yet - { 0x3f800000, 0x3f820000 }, //SPI SRAM not installed -#endif + { 0x3f800000, 0x3fC00000 }, //SPI RAM gets added later if needed, in spiram.c; reserve it for now }; const size_t soc_reserved_region_count = sizeof(soc_reserved_regions)/sizeof(soc_reserved_region_t); From 6d95934a3c3a547a512ae516e4d104687e9c9bb7 Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Wed, 6 Sep 2017 16:13:40 +0800 Subject: [PATCH 2/2] Make 80MHz PSRAM work as well, add testcase for weirdness reported on esp32 forums, clean up unused define in psram code --- components/esp32/clk.c | 4 ++++ components/esp32/spiram_psram.c | 5 ----- components/esp32/test/test_spiram_cache_flush.c | 6 ++++++ 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/components/esp32/clk.c b/components/esp32/clk.c index f9be8dac5..4472629e8 100644 --- a/components/esp32/clk.c +++ b/components/esp32/clk.c @@ -174,7 +174,10 @@ void esp_perip_clk_init(void) DPORT_LEDC_CLK_EN | DPORT_UHCI1_CLK_EN | DPORT_TIMERGROUP1_CLK_EN | +//80MHz SPIRAM uses SPI2 as well; it's initialized before this is called. Do not disable the clock for that if this is enabled. +#if !CONFIG_SPIRAM_SPEED_80M DPORT_SPI_CLK_EN_2 | +#endif DPORT_PWM0_CLK_EN | DPORT_I2C_EXT1_CLK_EN | DPORT_CAN_CLK_EN | @@ -196,6 +199,7 @@ void esp_perip_clk_init(void) DPORT_WIFI_CLK_SDIO_HOST_EN | DPORT_WIFI_CLK_EMAC_EN; } + /* Change I2S clock to audio PLL first. Because if I2S uses 160MHz clock, * the current is not reduced when disable I2S clock. */ diff --git a/components/esp32/spiram_psram.c b/components/esp32/spiram_psram.c index d6653d116..6be905d14 100644 --- a/components/esp32/spiram_psram.c +++ b/components/esp32/spiram_psram.c @@ -94,9 +94,6 @@ typedef enum { static psram_cache_mode_t s_psram_mode = PSRAM_CACHE_MAX; -//For now, we only use F40M + S40M, and we don't have to go through gpio matrix -#define ENABLE_GPIO_MATRIX_SPI 1 - /* dummy_len_plus values defined in ROM for SPI flash configuration */ extern uint8_t g_rom_spiflash_dummy_len_plus[]; @@ -528,9 +525,7 @@ esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vad } CLEAR_PERI_REG_MASK(SPI_USER_REG(PSRAM_SPI_1), SPI_CS_SETUP_M); -#if ENABLE_GPIO_MATRIX_SPI psram_gpio_config(mode); -#endif WRITE_PERI_REG(GPIO_ENABLE_W1TS_REG, BIT(PSRAM_CS_IO)| BIT(PSRAM_CLK_IO)); PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[PSRAM_CS_IO], 2); PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[PSRAM_CLK_IO], 2); diff --git a/components/esp32/test/test_spiram_cache_flush.c b/components/esp32/test/test_spiram_cache_flush.c index 3d6f75f1f..a99f7226d 100644 --- a/components/esp32/test/test_spiram_cache_flush.c +++ b/components/esp32/test/test_spiram_cache_flush.c @@ -56,6 +56,7 @@ TEST_CASE("Spiram cache flush on mmap", "[spiram][ignore]") void *mem[2]; res[0]=0; res[1]=0; #if CONFIG_SPIRAM_USE_CAPS_ALLOC + printf("Allocating SPI RAM chunk...\n"); mem[0]=heap_caps_malloc(TSTSZ, MALLOC_CAP_SPIRAM); mem[1]=heap_caps_malloc(TSTSZ, MALLOC_CAP_SPIRAM); #else @@ -101,6 +102,7 @@ TEST_CASE("Spiram cache flush on write/read", "[spiram][ignore]") void *mem[2]; res[0]=0; res[1]=0; #if CONFIG_SPIRAM_USE_CAPS_ALLOC + printf("Allocating SPI RAM chunk...\n"); mem[0]=heap_caps_malloc(TSTSZ, MALLOC_CAP_SPIRAM); mem[1]=heap_caps_malloc(TSTSZ, MALLOC_CAP_SPIRAM); #else @@ -175,3 +177,7 @@ IRAM_ATTR TEST_CASE("Spiram memcmp weirdness at 80MHz", "[spiram][ignore]") { #endif //CONFIG_SPIRAM_USE_CAPS_ALLOC || CONFIG_SPIRAM_USE_MEMMAP + + + +