Skip to content

Commit 89ec6f6

Browse files
Glauber Maroto Ferreiranashif
authored andcommitted
soc: esp32s2: add SPI RAM support
brings support to external esp32s2 RAM memory. Signed-off-by: Glauber Maroto Ferreira <[email protected]>
1 parent 661b5cf commit 89ec6f6

File tree

4 files changed

+139
-2
lines changed

4 files changed

+139
-2
lines changed

soc/xtensa/esp32s2/Kconfig.soc

Lines changed: 93 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ endchoice
4545

4646
choice
4747
prompt "Data cache size"
48-
default ESP32S2_DATA_CACHE_0KB
48+
default ESP32S2_DATA_CACHE_0KB if !ESP_SPIRAM
49+
default ESP32S2_DATA_CACHE_8KB if ESP_SPIRAM
4950

5051
config ESP32S2_DATA_CACHE_0KB
5152
bool "0KB data cache size"
@@ -81,6 +82,97 @@ config ESP32S2_DATA_CACHE_SIZE
8182
default 0x4000 if ESP32S2_DATA_CACHE_16KB
8283
default 0x0000
8384

85+
config ESP_SPIRAM
86+
bool "Support for external, SPI-connected RAM"
87+
help
88+
This enables support for an external SPI RAM chip, connected in
89+
parallel with the main SPI flash chip.
90+
91+
config ESP_HEAP_MIN_EXTRAM_THRESHOLD
92+
int "Minimum threshold for external RAM allocation"
93+
default 8192
94+
range 1024 131072
95+
depends on ESP_SPIRAM
96+
help
97+
Threshold to decide if memory will be allocated from DRAM
98+
or SPIRAM. If value of allocation size is less than this value,
99+
memory will be allocated from internal RAM.
100+
101+
menu "SPI RAM config"
102+
depends on ESP_SPIRAM
103+
104+
choice SPIRAM_TYPE
105+
prompt "Type of SPI RAM chip in use"
106+
default SPIRAM_TYPE_ESPPSRAM16
107+
108+
config SPIRAM_TYPE_ESPPSRAM16
109+
bool "ESP-PSRAM16 or APS1604"
110+
111+
config SPIRAM_TYPE_ESPPSRAM32
112+
bool "ESP-PSRAM32 or IS25WP032"
113+
114+
config SPIRAM_TYPE_ESPPSRAM64
115+
bool "ESP-PSRAM64 or LY68L6400"
116+
117+
endchoice # SPIRAM_TYPE
118+
119+
config ESP_SPIRAM_SIZE
120+
int "Size of SPIRAM part"
121+
default 2097152 if SPIRAM_TYPE_ESPPSRAM16
122+
default 4194304 if SPIRAM_TYPE_ESPPSRAM32
123+
default 8388608 if SPIRAM_TYPE_ESPPSRAM64
124+
help
125+
Specify size of SPIRAM part.
126+
NOTE: If SPIRAM size is greater than 4MB, only
127+
lower 4MB can be allocated using k_malloc().
128+
129+
menu "PSRAM clock and cs IO for ESP32S2"
130+
depends on ESP_SPIRAM
131+
132+
config DEFAULT_PSRAM_CLK_IO
133+
int "PSRAM CLK IO number"
134+
range 0 33
135+
default 30
136+
help
137+
The PSRAM CLOCK IO can be any unused GPIO, user can config
138+
it based on hardware design.
139+
140+
config DEFAULT_PSRAM_CS_IO
141+
int "PSRAM CS IO number"
142+
range 0 33
143+
default 26
144+
help
145+
The PSRAM CS IO can be any unused GPIO, user can config it
146+
based on hardware design.
147+
148+
endmenu # PSRAM clock and cs IO for ESP32S2
149+
150+
choice SPIRAM_SPEED
151+
prompt "Set RAM clock speed"
152+
default SPIRAM_SPEED_40M
153+
help
154+
Select the speed for the SPI RAM chip.
155+
156+
config SPIRAM_SPEED_80M
157+
bool "80MHz clock speed"
158+
159+
config SPIRAM_SPEED_40M
160+
bool "40MHz clock speed"
161+
162+
config SPIRAM_SPEED_26M
163+
bool "26MHz clock speed"
164+
165+
config SPIRAM_SPEED_20M
166+
bool "20MHz clock speed"
167+
168+
endchoice # SPIRAM_SPEED
169+
170+
config SPIRAM
171+
bool
172+
default y
173+
174+
endmenu # SPI RAM config
175+
84176
choice ESP32S2_UNIVERSAL_MAC_ADDRESSES
85177
bool "Number of universally administered (by IEEE) MAC address"
86178
default ESP32S2_UNIVERSAL_MAC_ADDRESSES_TWO

soc/xtensa/esp32s2/linker.ld

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ MEMORY
4242
drom0_0_seg(R): org = 0x3f000020, len = 0x3f0000-0x20
4343
rtc_iram_seg(RWX): org = 0x40070000, len = 0x2000
4444
rtc_slow_seg(RW): org = 0x50000000, len = 0x2000
45+
#if defined(CONFIG_ESP_SPIRAM)
46+
ext_ram_seg(RW): org = 0x3f500000, len = CONFIG_ESP_SPIRAM_SIZE
47+
#endif
4548
#ifdef CONFIG_GEN_ISR_TABLES
4649
IDT_LIST(RW): org = 0x3ebfe010, len = 0x2000
4750
#endif
@@ -238,6 +241,16 @@ _net_buf_pool_list = _esp_net_buf_pool_list;
238241
. = ALIGN(4);
239242
} GROUP_LINK_IN(RAMABLE_REGION)
240243

244+
#if defined(CONFIG_ESP_SPIRAM)
245+
.ext_ram.bss (NOLOAD):
246+
{
247+
_ext_ram_bss_start = ABSOLUTE(.);
248+
*(.ext_ram.bss*)
249+
. = ALIGN(4);
250+
_ext_ram_bss_end = ABSOLUTE(.) + CONFIG_ESP_SPIRAM_SIZE;
251+
} > ext_ram_seg
252+
#endif
253+
241254
SECTION_PROLOGUE(_RODATA_SECTION_NAME,,ALIGN(20))
242255
{
243256
_rodata_start = ABSOLUTE(.);

soc/xtensa/esp32s2/soc.c

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,18 @@
2323
#include "esp_spi_flash.h"
2424
#include "hal/cpu_ll.h"
2525
#include "esp_err.h"
26+
#include "esp32s2/spiram.h"
2627
#include "sys/printk.h"
2728

2829
extern void z_cstart(void);
2930
extern void z_bss_zero(void);
3031
extern void rtc_clk_cpu_freq_set_xtal(void);
3132

33+
#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
34+
extern int _ext_ram_bss_start;
35+
extern int _ext_ram_bss_end;
36+
#endif
37+
3238
/*
3339
* This is written in C rather than assembly since, during the port bring up,
3440
* Zephyr is being booted by the Espressif bootloader. With it, the C stack
@@ -158,7 +164,32 @@ void __attribute__((section(".iram1"))) __start(void)
158164
*wdt_rtc_protect = 0;
159165
#endif
160166

161-
#if CONFIG_SOC_FLASH_ESP32
167+
#if CONFIG_ESP_SPIRAM
168+
esp_err_t err = esp_spiram_init();
169+
170+
if (err != ESP_OK) {
171+
printk("Failed to Initialize SPIRAM, aborting.\n");
172+
abort();
173+
}
174+
esp_spiram_init_cache();
175+
if (esp_spiram_get_size() < CONFIG_ESP_SPIRAM_SIZE) {
176+
printk("SPIRAM size is less than configured size, aborting.\n");
177+
abort();
178+
}
179+
#endif
180+
181+
#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
182+
memset(&_ext_ram_bss_start,
183+
0,
184+
(&_ext_ram_bss_end - &_ext_ram_bss_start) * sizeof(_ext_ram_bss_start));
185+
#endif
186+
187+
/* Scheduler is not started at this point. Hence, guard functions
188+
* must be initialized after esp_spiram_init_cache which internally
189+
* uses guard functions. Setting guard functions before SPIRAM
190+
* cache initialization will result in a crash.
191+
*/
192+
#if CONFIG_SOC_FLASH_ESP32 || CONFIG_ESP_SPIRAM
162193
spi_flash_guard_set(&g_flash_guard_default_ops);
163194
#endif
164195
esp_intr_initialize();

soc/xtensa/esp32s2/soc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <zephyr/types.h>
2020
#include <stdbool.h>
2121
#include <arch/xtensa/arch.h>
22+
#include <stdlib.h>
2223

2324
extern void esp_rom_uart_attach(void);
2425
extern void esp_rom_uart_tx_wait_idle(uint8_t uart_no);

0 commit comments

Comments
 (0)