]> 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 55e97859fc1587ef71da2e29976564ad1e87c799..98effb1279d5008be8fa35413144868b2e98352f 100644 (file)
@@ -19,10 +19,12 @@ 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"
 #include "esp_err.h"
+#include "esp_spiram.h"
 #include "spiram_psram.h"
 #include "esp_log.h"
 #include "freertos/FreeRTOS.h"
@@ -102,13 +104,48 @@ void IRAM_ATTR esp_spiram_init_cache()
 #endif
 }
 
+esp_spiram_volt_t esp_spiram_get_chip_volt()
+{
+    if (!spiram_inited) {
+        ESP_LOGE(TAG, "SPI RAM not initialized");
+        return ESP_SPIRAM_VOLT_INVALID;
+    }
+    psram_volt_t volt = psram_get_volt();
+    switch (volt) {
+        case PSRAM_VOLT_1V8:
+            return ESP_SPIRAM_VOLT_1V8;
+        case PSRAM_VOLT_3V3:
+            return ESP_SPIRAM_VOLT_3V3;
+        default:
+            return ESP_SPIRAM_VOLT_INVALID;
+    }
+}
+
+esp_spiram_size_t esp_spiram_get_chip_size()
+{
+    if (!spiram_inited) {
+        ESP_LOGE(TAG, "SPI RAM not initialized");
+        return ESP_SPIRAM_SIZE_INVALID;
+    }
+    psram_size_t psram_size = psram_get_size();
+    switch (psram_size) {
+        case PSRAM_SIZE_32MBITS:
+            return ESP_SPIRAM_SIZE_32MBITS;
+        case PSRAM_SIZE_64MBITS:
+            return ESP_SPIRAM_SIZE_64MBITS;
+        default:
+            return ESP_SPIRAM_SIZE_INVALID;
+    }
+}
 
 esp_err_t esp_spiram_init()
 {
     esp_err_t r;
     r = psram_enable(PSRAM_SPEED, PSRAM_MODE);
     if (r != ESP_OK) {
+#if CONFIG_SPIRAM_IGNORE_NOTFOUND
         ESP_EARLY_LOGE(TAG, "SPI RAM enabled but initialization failed. Bailing out.");
+#endif
         return r;
     }
 
@@ -136,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, dma_heap, 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()