Skip to content

Commit

Permalink
soc: xtensa: esp32s3: add support for SPIRAM
Browse files Browse the repository at this point in the history
Add support for external PSRAM for esp32s3.

Signed-off-by: Lucas Tamborrino <[email protected]>
  • Loading branch information
LucasTambor committed Jul 25, 2023
1 parent 5b432ec commit 2dfaa09
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 1 deletion.
13 changes: 13 additions & 0 deletions soc/xtensa/espressif_esp32/common/Kconfig.soc
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,15 @@ config ESP_HEAP_SEARCH_ALL_REGIONS
menu "SPI RAM config"
depends on ESP_SPIRAM

choice SPIRAM_MODE
prompt "Mode (QUAD/OCT) of SPI RAM chip in use"
default SPIRAM_MODE_QUAD

config SPIRAM_MODE_QUAD
bool "Quad Mode PSRAM"

endchoice # SPIRAM_MODE

choice SPIRAM_TYPE
prompt "Type of SPI RAM chip in use"
depends on ESP_SPIRAM
Expand Down Expand Up @@ -98,6 +107,10 @@ config SPIRAM_SPEED_80M
depends on ESPTOOLPY_FLASHFREQ_80M
bool "80MHz clock speed"

config SPIRAM_SPEED_120M
depends on SPIRAM_MODE_QUAD && SOC_SERIES_ESP32S3
bool "120MHz clock speed"

endchoice # SPIRAM_SPEED

menu "PSRAM clock and cs IO for ESP32-DOWD"
Expand Down
19 changes: 19 additions & 0 deletions soc/xtensa/espressif_esp32/esp32s3/Kconfig.soc
Original file line number Diff line number Diff line change
Expand Up @@ -293,4 +293,23 @@ config MAC_BB_PD

endmenu # Cache config

menu "PSRAM Clock and CS IO for ESP32S3"
depends on ESP_SPIRAM

config DEFAULT_PSRAM_CLK_IO
int "PSRAM CLK IO number"
range 0 33
default 30
help
The PSRAM Clock IO can be any unused GPIO, please refer to your hardware design.

config DEFAULT_PSRAM_CS_IO
int "PSRAM CS IO number"
range 0 33
default 26
help
The PSRAM CS IO can be any unused GPIO, please refer to your hardware design.

endmenu # PSRAM clock and cs IO for ESP32S3

endif # SOC_SERIES_ESP32S3
29 changes: 28 additions & 1 deletion soc/xtensa/espressif_esp32/esp32s3/default.ld
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
#define RAMABLE_REGION dram0_0_seg
#define ROMABLE_REGION ROM

#define EXT_RAM_ORG (0x3E000000 - CONFIG_ESP_SPIRAM_SIZE)

#ifdef CONFIG_FLASH_SIZE
#define FLASH_SIZE CONFIG_FLASH_SIZE
#else
Expand Down Expand Up @@ -70,7 +72,13 @@ MEMORY
* Hence, an offset of 0x40 is added to DROM segment origin.
*/
drom0_0_seg(R): org = 0x3C000040, len = FLASH_SIZE - 0x40

/**
* `extern_ram_seg` and `drom0_0_seg` share the same bus and the address region.
* so we allocate `extern_ram_seg` at the end of the address region.
*/
#if defined(CONFIG_ESP_SPIRAM)
ext_ram_seg(RWX): org = EXT_RAM_ORG, len = CONFIG_ESP_SPIRAM_SIZE
#endif
/* RTC fast memory (executable). Persists over deep sleep.
*/
rtc_iram_seg(RWX): org = 0x600fe000, len = 0x2000
Expand Down Expand Up @@ -219,6 +227,17 @@ SECTIONS
_image_rodata_end = ABSOLUTE(.);
} GROUP_DATA_LINK_IN(RODATA_REGION, ROMABLE_REGION)

#if defined(CONFIG_ESP_SPIRAM)
/* This section holds .ext_ram.bss data, and will be put in PSRAM */
.ext_ram.bss (NOLOAD) :
{
_ext_ram_bss_start = ABSOLUTE(.);
*(.ext_ram.bss*)
. = ALIGN(0x10000);
_ext_ram_bss_end = ABSOLUTE(.);
} > ext_ram_seg
#endif

/* Send .iram0 code to iram */
.iram0.vectors : ALIGN(4)
{
Expand Down Expand Up @@ -272,6 +291,9 @@ SECTIONS
*libsoc.a:rtc_*.*(.literal .text .literal.* .text.*)
*libsoc.a:cpu_util.*(.literal .text .literal.* .text.*)
*libgcc.a:lib2funcs.*(.literal .text .literal.* .text.*)
*libzephyr.a:spiram*.*(.literal .text .literal.* .text.*)
*libzephyr.a:spi_timing*.*(.literal .text .literal.* .text.*)
*libzephyr.a:spi_flash*.*(.literal .text .literal.* .text.*)
*libdrivers__flash.a:flash_esp32.*(.literal .text .literal.* .text.*)
*libzephyr.a:windowspill_asm.*(.literal .text .literal.* .text.*)
*libzephyr.a:log_noos.*(.literal .text .literal.* .text.*)
Expand Down Expand Up @@ -642,3 +664,8 @@ SECTIONS

ASSERT(((_iram_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)),
"IRAM0 segment data does not fit.")

#if defined(CONFIG_ESP_SPIRAM)
ASSERT(((ORIGIN(ext_ram_seg)) > _image_rodata_end),
"External RAM segment does not fit.")
#endif
32 changes: 32 additions & 0 deletions soc/xtensa/espressif_esp32/esp32s3/soc.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,18 @@
#include "esp_app_format.h"
#include "esp_clk_internal.h"

#include "esp32s3/spiram.h"

#ifdef CONFIG_MCUBOOT
#include "bootloader_init.h"
#endif /* CONFIG_MCUBOOT */
#include <zephyr/sys/printk.h>

#if CONFIG_ESP_SPIRAM
extern int _ext_ram_bss_start;
extern int _ext_ram_bss_end;
#endif

extern void z_cstart(void);

#ifndef CONFIG_MCUBOOT
Expand Down Expand Up @@ -104,6 +111,31 @@ void IRAM_ATTR __esp_platform_start(void)
/* Apply SoC patches */
esp_errata();


#if CONFIG_ESP_SPIRAM
esp_err_t err = esp_spiram_init();

if (err != ESP_OK) {
printk("Failed to Initialize external RAM, aborting.\n");
abort();
}

esp_spiram_init_cache();
if (esp_spiram_get_size() < CONFIG_ESP_SPIRAM_SIZE) {
printk("External RAM size is less than configured, aborting.\n");
abort();
}

if (!esp_spiram_test()) {
printk("External RAM failed memory test!\n");
abort();
}

memset(&_ext_ram_bss_start, 0,
(&_ext_ram_bss_end - &_ext_ram_bss_start) * sizeof(_ext_ram_bss_start));

#endif /* CONFIG_ESP_SPIRAM */

/* ESP-IDF/MCUboot 2nd stage bootloader enables RTC WDT to check on startup sequence
* related issues in application. Hence disable that as we are about to start
* Zephyr environment.
Expand Down

0 comments on commit 2dfaa09

Please sign in to comment.