esp32: SPIRAM Support

Adds SPIRAM support for ESP32

Configures k_heap for SPIRAM memory range

Signed-off-by: Shubham Kulkarni <shubham.kulkarni@espressif.com>
This commit is contained in:
Shubham Kulkarni 2020-12-03 18:44:56 +05:30 committed by Anas Nashif
commit 67d2368398
3 changed files with 182 additions and 2 deletions

View file

@ -22,4 +22,150 @@ config ESP32_BT_RESERVE_DRAM
default 0xdb5c if BT
default 0
endif # SOC_ESP32
config ESP_SPIRAM
bool "Support for external, SPI-connected RAM"
help
This enables support for an external SPI RAM chip, connected in
parallel with the main SPI flash chip.
menu "SPI RAM config"
depends on ESP_SPIRAM
choice SPIRAM_TYPE
prompt "Type of SPI RAM chip in use"
default SPIRAM_TYPE_ESPPSRAM16
config SPIRAM_TYPE_ESPPSRAM16
bool "ESP-PSRAM16 or APS1604"
config SPIRAM_TYPE_ESPPSRAM32
bool "ESP-PSRAM32 or IS25WP032"
config SPIRAM_TYPE_ESPPSRAM64
bool "ESP-PSRAM64 or LY68L6400"
endchoice
config ESP_SPIRAM_SIZE
int "Size of SPIRAM part"
default 2097152 if SPIRAM_TYPE_ESPPSRAM16
default 4194304 if SPIRAM_TYPE_ESPPSRAM32
default 8388608 if SPIRAM_TYPE_ESPPSRAM64
help
Specify size of SPIRAM part.
NOTE: If SPIRAM size is greater than 4MB, only
lower 4MB can be allocated using k_malloc().
choice SPIRAM_SPEED
prompt "Set RAM clock speed"
default SPIRAM_SPEED_40M
help
Select the speed for the SPI RAM chip.
If SPI RAM is enabled, we only support three combinations of SPI speed mode we supported now:
1. Flash SPI running at 40Mhz and RAM SPI running at 40Mhz
2. Flash SPI running at 80Mhz and RAM SPI running at 40Mhz
3. Flash SPI running at 80Mhz and RAM SPI running at 80Mhz
Note: If the third mode(80Mhz+80Mhz) is enabled for SPI RAM of type 32MBit, one of the HSPI/VSPI host
will be occupied by the system. Which SPI host to use can be selected by the config item
SPIRAM_OCCUPY_SPI_HOST. Application code should never touch HSPI/VSPI hardware in this case. The
option to select 80MHz will only be visible if the flash SPI speed is also 80MHz.
(ESPTOOLPY_FLASHFREQ_79M is true)
config SPIRAM_SPEED_40M
bool "40MHz clock speed"
config SPIRAM_SPEED_80M
depends on ESPTOOLPY_FLASHFREQ_80M
bool "80MHz clock speed"
endchoice
menu "PSRAM clock and cs IO for ESP32-DOWD"
config D0WD_PSRAM_CLK_IO
int "PSRAM CLK IO number"
range 0 33
default 17
help
The PSRAM CLOCK IO can be any unused GPIO, user can config it based on hardware design. If user use
1.8V flash and 1.8V psram, this value can only be one of 6, 7, 8, 9, 10, 11, 16, 17.
config D0WD_PSRAM_CS_IO
int "PSRAM CS IO number"
range 0 33
default 16
help
The PSRAM CS IO can be any unused GPIO, user can config it based on hardware design. If user use
1.8V flash and 1.8V psram, this value can only be one of 6, 7, 8, 9, 10, 11, 16, 17.
endmenu
menu "PSRAM clock and cs IO for ESP32-D2WD"
config D2WD_PSRAM_CLK_IO
int "PSRAM CLK IO number"
range 0 33
default 9
help
User can config it based on hardware design. For ESP32-D2WD chip, the psram can only be 1.8V psram,
so this value can only be one of 6, 7, 8, 9, 10, 11, 16, 17.
config D2WD_PSRAM_CS_IO
int "PSRAM CS IO number"
range 0 33
default 10
help
User can config it based on hardware design. For ESP32-D2WD chip, the psram can only be 1.8V psram,
so this value can only be one of 6, 7, 8, 9, 10, 11, 16, 17.
endmenu
menu "PSRAM clock and cs IO for ESP32-PICO"
config PICO_PSRAM_CS_IO
int "PSRAM CS IO number"
range 0 33
default 10
help
The PSRAM CS IO can be any unused GPIO, user can config it based on hardware design.
For ESP32-PICO chip, the psram share clock with flash, so user do not need to configure the clock
IO.
For the reference hardware design, please refer to
https://www.espressif.com/sites/default/files/documentation/esp32-pico-d4_datasheet_en.pdf
endmenu
config SPIRAM_CUSTOM_SPIWP_SD3_PIN
bool "Use custom SPI PSRAM WP(SD3) Pin when flash pins set in eFuse (read help)"
default y if SPIRAM_SPIWP_SD3_PIN != 7 # backwards compatibility, can remove in IDF 5
default n
help
This setting is only used if the SPI flash pins have been overridden by setting the eFuses
SPI_PAD_CONFIG_xxx, and the SPI flash mode is DIO or DOUT.
When this is the case, the eFuse config only defines 3 of the 4 Quad I/O data pins. The WP pin (aka
ESP32 pin "SD_DATA_3" or SPI flash pin "IO2") is not specified in eFuse. The psram only has QPI
mode, so a WP pin setting is necessary.
If this config item is set to N (default), the correct WP pin will be automatically used for any
Espressif chip or module with integrated flash. If a custom setting is needed, set this config item
to Y and specify the GPIO number connected to the WP pin.
When flash mode is set to QIO or QOUT, the PSRAM WP pin will be set the same as the SPI Flash WP pin
configured in the bootloader.
config SPIRAM_SPIWP_SD3_PIN
int "Custom SPI PSRAM WP(SD3) Pin"
range 0 33
default 7
help
The option "Use custom SPI PSRAM WP(SD3) pin" must be set or this value is ignored
If burning a customized set of SPI flash pins in eFuse and using DIO or DOUT mode for flash, set this
value to the GPIO number of the SPIRAM WP pin.
config SPIRAM
bool
default y
endmenu
endif # SOC_ESP32

View file

@ -45,6 +45,9 @@ MEMORY
drom0_0_seg(R): org = 0x3F400020, len = 0x400000-0x20
rtc_iram_seg(RWX): org = 0x400C0000, len = 0x2000
rtc_slow_seg(RW): org = 0x50000000, len = 0x1000
#if defined(CONFIG_ESP_SPIRAM)
ext_ram_seg(RW): org = 0x3F800000, len = CONFIG_ESP_SPIRAM_SIZE
#endif
#ifdef CONFIG_GEN_ISR_TABLES
IDT_LIST(RW): org = 0x3ebfe010, len = 0x2000
#endif
@ -250,6 +253,15 @@ _net_buf_pool_list = _esp_net_buf_pool_list;
. = ALIGN(4);
} GROUP_LINK_IN(RAMABLE_REGION)
#if defined(CONFIG_ESP_SPIRAM)
.ext_ram.bss (NOLOAD):
{
_ext_ram_data_start = ABSOLUTE(.);
*(.ext_ram.bss*)
_ext_ram_data_end = ABSOLUTE(.) + CONFIG_ESP_SPIRAM_SIZE;
} > ext_ram_seg
#endif
SECTION_PROLOGUE(_RODATA_SECTION_NAME,,ALIGN(20))
{
_rodata_start = ABSOLUTE(.);

View file

@ -22,6 +22,9 @@
#include "soc/cpu.h"
#include "soc/gpio_periph.h"
#include "esp_spi_flash.h"
#include "esp_err.h"
#include "esp32/spiram.h"
#include "sys/printk.h"
extern void z_cstart(void);
@ -96,7 +99,26 @@ void __attribute__((section(".iram1"))) __start(void)
*wdt_rtc_protect = 0;
#endif
#if CONFIG_SOC_FLASH_ESP32
#if CONFIG_ESP_SPIRAM
esp_err_t err = esp_spiram_init();
if (err != ESP_OK) {
printk("Failed to Initialize SPIRAM, aborting.\n");
abort();
}
esp_spiram_init_cache();
if (esp_spiram_get_size() < CONFIG_ESP_SPIRAM_SIZE) {
printk("SPIRAM size is less than configured size, aborting.\n");
abort();
}
#endif
/* Scheduler is not started at this point. Hence, guard functions
* must be initialized after esp_spiram_init_cache which internally
* uses guard functions. Setting guard functions before SPIRAM
* cache initialization will result in a crash.
*/
#if CONFIG_SOC_FLASH_ESP32 || CONFIG_ESP_SPIRAM
spi_flash_guard_set(&g_flash_guard_default_ops);
#endif
/* Start Zephyr */