]> granicus.if.org Git - esp-idf/blobdiff - components/esp32/spiram.c
Merge branch 'feature/esp-wrover-kit-v4_1' into 'master'
[esp-idf] / components / esp32 / spiram.c
index 21fade5be64198ee72da600f0e1cce429e05078b..98effb1279d5008be8fa35413144868b2e98352f 100644 (file)
@@ -19,6 +19,7 @@ we add more types of external RAM memory, this can be made into a more intellige
 
 #include <stdint.h>
 #include <string.h>
+#include <sys/param.h>
 
 #include "sdkconfig.h"
 #include "esp_attr.h"
@@ -172,12 +173,26 @@ esp_err_t esp_spiram_add_to_heapalloc()
 static uint8_t *dma_heap;
 
 esp_err_t esp_spiram_reserve_dma_pool(size_t size) {
-    if (size==0) return ESP_OK; //no-op
     ESP_EARLY_LOGI(TAG, "Reserving pool of %dK of internal memory for DMA/internal allocations", size/1024);
-    dma_heap=heap_caps_malloc(size, MALLOC_CAP_DMA|MALLOC_CAP_INTERNAL);
-    if (!dma_heap) return ESP_ERR_NO_MEM;
-    uint32_t caps[]={MALLOC_CAP_DMA|MALLOC_CAP_INTERNAL, 0, MALLOC_CAP_8BIT|MALLOC_CAP_32BIT};
-    return heap_caps_add_region_with_caps(caps, (intptr_t) dma_heap, (intptr_t) dma_heap+size-1);
+    /* Pool may be allocated in multiple non-contiguous chunks, depending on available RAM */
+    while (size > 0) {
+        size_t next_size = heap_caps_get_largest_free_block(MALLOC_CAP_DMA|MALLOC_CAP_INTERNAL);
+        next_size = MIN(next_size, size);
+
+        ESP_EARLY_LOGD(TAG, "Allocating block of size %d bytes", next_size);
+        dma_heap = heap_caps_malloc(next_size, MALLOC_CAP_DMA|MALLOC_CAP_INTERNAL);
+        if (!dma_heap || next_size == 0) {
+            return ESP_ERR_NO_MEM;
+        }
+
+        uint32_t caps[] = { 0, MALLOC_CAP_DMA|MALLOC_CAP_INTERNAL, MALLOC_CAP_8BIT|MALLOC_CAP_32BIT };
+        esp_err_t e = heap_caps_add_region_with_caps(caps, (intptr_t) dma_heap, (intptr_t) dma_heap+next_size-1);
+        if (e != ESP_OK) {
+            return e;
+        }
+        size -= next_size;
+    }
+    return ESP_OK;
 }
 
 size_t esp_spiram_get_size()