Skip to content

Commit 74e841d

Browse files
committed
Read fuses to know what flash and ram pins to never reset
1 parent f0c6a8c commit 74e841d

File tree

4 files changed

+101
-12
lines changed

4 files changed

+101
-12
lines changed

ports/espressif/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ INC += \
9898
-isystem esp-idf/components/bt/host/nimble/port/include \
9999
-isystem esp-idf/components/driver/include \
100100
-isystem esp-idf/components/driver/$(IDF_TARGET)/include \
101+
-isystem esp-idf/components/efuse/include \
102+
-isystem esp-idf/components/efuse/$(IDF_TARGET)/include \
101103
-isystem esp-idf/components/$(IDF_TARGET)/include \
102104
-isystem esp-idf/components/esp_adc_cal/include \
103105
-isystem esp-idf/components/esp_common/include \

ports/espressif/boards/adafruit_qtpy_esp32_pico/mpconfigboard.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
CIRCUITPY_CREATOR_ID = 0x0000239A
2-
CIRCUITPY_CREATION_ID = 0x00320002
2+
CIRCUITPY_CREATION_ID = 0x00320003
33

44
IDF_TARGET = esp32
55

ports/espressif/common-hal/microcontroller/Pin.c

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -46,17 +46,7 @@ static const uint64_t pin_mask_reset_forbidden =
4646
// Never ever reset serial pins for bootloader and possibly USB-serial converter.
4747
GPIO_SEL_1 | // TXD0
4848
GPIO_SEL_3 | // RXD0
49-
// Never ever reset pins used to communicate with SPI flash and PSRAM.
50-
GPIO_SEL_6 | // CLK
51-
GPIO_SEL_7 |
52-
GPIO_SEL_8 |
53-
GPIO_SEL_9 | // (PSRAM) SD2
54-
GPIO_SEL_10 | // (PSRAM) SD3
55-
GPIO_SEL_11 | // CMD
56-
GPIO_SEL_16 | // SPIHD
57-
GPIO_SEL_17 | // SPIDO
58-
GPIO_SEL_18 | // SPIWP
59-
GPIO_SEL_23 | // SPIDI
49+
// SPI flash and PSRAM pins are protected at runtime in supervisor/port.c.
6050
#endif // ESP32
6151

6252
#if defined(CONFIG_IDF_TARGET_ESP32C3)

ports/espressif/supervisor/port.c

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,19 @@
8181
#include "soc/cache_memory.h"
8282
#endif
8383

84+
#include "soc/efuse_reg.h"
8485
#include "soc/rtc_cntl_reg.h"
8586

8687
#include "esp_debug_helpers.h"
8788

89+
#include "bootloader_flash_config.h"
90+
#include "esp_efuse.h"
8891
#include "esp_ipc.h"
92+
#include "esp_rom_efuse.h"
93+
94+
#ifdef CONFIG_IDF_TARGET_ESP32
95+
#include "esp32/rom/efuse.h"
96+
#endif
8997

9098
#ifdef CONFIG_SPIRAM
9199
#include "esp32/spiram.h"
@@ -134,6 +142,93 @@ STATIC void tick_timer_cb(void *arg) {
134142

135143
void sleep_timer_cb(void *arg);
136144

145+
// The ESP-IDF determines these pins at runtime so we do too. This code is based on:
146+
// https://github.com/espressif/esp-idf/blob/6d85d53ceec30c818a92c2fff8f5437d21c4720f/components/esp_hw_support/port/esp32/spiram_psram.c#L810
147+
// IO-pins for PSRAM.
148+
// WARNING: PSRAM shares all but the CS and CLK pins with the flash, so these defines
149+
// hardcode the flash pins as well, making this code incompatible with either a setup
150+
// that has the flash on non-standard pins or ESP32s with built-in flash.
151+
#define PSRAM_SPIQ_SD0_IO 7
152+
#define PSRAM_SPID_SD1_IO 8
153+
#define PSRAM_SPIWP_SD3_IO 10
154+
#define PSRAM_SPIHD_SD2_IO 9
155+
156+
#define FLASH_HSPI_CLK_IO 14
157+
#define FLASH_HSPI_CS_IO 15
158+
#define PSRAM_HSPI_SPIQ_SD0_IO 12
159+
#define PSRAM_HSPI_SPID_SD1_IO 13
160+
#define PSRAM_HSPI_SPIWP_SD3_IO 2
161+
#define PSRAM_HSPI_SPIHD_SD2_IO 4
162+
163+
// PSRAM clock and cs IO should be configured based on hardware design.
164+
// For ESP32-WROVER or ESP32-WROVER-B module, the clock IO is IO17, the cs IO is IO16,
165+
// they are the default value for these two configs.
166+
#define D0WD_PSRAM_CLK_IO CONFIG_D0WD_PSRAM_CLK_IO // Default value is 17
167+
#define D0WD_PSRAM_CS_IO CONFIG_D0WD_PSRAM_CS_IO // Default value is 16
168+
169+
#define D2WD_PSRAM_CLK_IO CONFIG_D2WD_PSRAM_CLK_IO // Default value is 9
170+
#define D2WD_PSRAM_CS_IO CONFIG_D2WD_PSRAM_CS_IO // Default value is 10
171+
172+
// There is no reason to change the pin of an embedded psram.
173+
// So define the number of pin directly, instead of configurable.
174+
#define D0WDR2_V3_PSRAM_CLK_IO 6
175+
#define D0WDR2_V3_PSRAM_CS_IO 16
176+
177+
// For ESP32-PICO chip, the psram share clock with flash. The flash clock pin is fixed, which is IO6.
178+
#define PICO_PSRAM_CLK_IO 6
179+
#define PICO_PSRAM_CS_IO CONFIG_PICO_PSRAM_CS_IO // Default value is 10
180+
181+
#define PICO_V3_02_PSRAM_CLK_IO 10
182+
#define PICO_V3_02_PSRAM_CS_IO 9
183+
184+
static void _never_reset_spi_ram_flash(void) {
185+
#if defined(CONFIG_IDF_TARGET_ESP32)
186+
uint32_t pkg_ver = esp_efuse_get_pkg_ver();
187+
if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32D2WDQ5) {
188+
never_reset_pin_number(D2WD_PSRAM_CLK_IO);
189+
never_reset_pin_number(D2WD_PSRAM_CS_IO);
190+
} else if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD4 && esp_efuse_get_chip_ver() >= 3) {
191+
// This chip is ESP32-PICO-V3 and doesn't have PSRAM.
192+
} else if ((pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD2) || (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD4)) {
193+
never_reset_pin_number(PICO_PSRAM_CLK_IO);
194+
never_reset_pin_number(PICO_PSRAM_CS_IO);
195+
} else if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOV302) {
196+
never_reset_pin_number(PICO_V3_02_PSRAM_CLK_IO);
197+
never_reset_pin_number(PICO_V3_02_PSRAM_CS_IO);
198+
} else if ((pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32D0WDQ6) || (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32D0WDQ5)) {
199+
never_reset_pin_number(D0WD_PSRAM_CLK_IO);
200+
never_reset_pin_number(D0WD_PSRAM_CS_IO);
201+
} else if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32D0WDR2V3) {
202+
never_reset_pin_number(D0WDR2_V3_PSRAM_CLK_IO);
203+
never_reset_pin_number(D0WDR2_V3_PSRAM_CS_IO);
204+
}
205+
206+
const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info();
207+
if (spiconfig == ESP_ROM_EFUSE_FLASH_DEFAULT_SPI) {
208+
never_reset_pin_number(SPI_IOMUX_PIN_NUM_CLK);
209+
never_reset_pin_number(SPI_IOMUX_PIN_NUM_CS);
210+
never_reset_pin_number(PSRAM_SPIQ_SD0_IO);
211+
never_reset_pin_number(PSRAM_SPID_SD1_IO);
212+
never_reset_pin_number(PSRAM_SPIWP_SD3_IO);
213+
never_reset_pin_number(PSRAM_SPIHD_SD2_IO);
214+
} else if (spiconfig == ESP_ROM_EFUSE_FLASH_DEFAULT_HSPI) {
215+
never_reset_pin_number(FLASH_HSPI_CLK_IO);
216+
never_reset_pin_number(FLASH_HSPI_CS_IO);
217+
never_reset_pin_number(PSRAM_HSPI_SPIQ_SD0_IO);
218+
never_reset_pin_number(PSRAM_HSPI_SPID_SD1_IO);
219+
never_reset_pin_number(PSRAM_HSPI_SPIWP_SD3_IO);
220+
never_reset_pin_number(PSRAM_HSPI_SPIHD_SD2_IO);
221+
} else {
222+
never_reset_pin_number(EFUSE_SPICONFIG_RET_SPICLK(spiconfig));
223+
never_reset_pin_number(EFUSE_SPICONFIG_RET_SPICS0(spiconfig));
224+
never_reset_pin_number(EFUSE_SPICONFIG_RET_SPIQ(spiconfig));
225+
never_reset_pin_number(EFUSE_SPICONFIG_RET_SPID(spiconfig));
226+
never_reset_pin_number(EFUSE_SPICONFIG_RET_SPIHD(spiconfig));
227+
never_reset_pin_number(bootloader_flash_get_wp_pin());
228+
}
229+
#endif
230+
}
231+
137232
safe_mode_t port_init(void) {
138233
esp_timer_create_args_t args;
139234
args.callback = &tick_timer_cb;
@@ -214,6 +309,8 @@ safe_mode_t port_init(void) {
214309
}
215310
#endif
216311

312+
_never_reset_spi_ram_flash();
313+
217314
if (heap == NULL) {
218315
size_t heap_total = heap_caps_get_total_size(MALLOC_CAP_8BIT);
219316
heap_size = MIN(heap_caps_get_largest_free_block(MALLOC_CAP_8BIT), heap_total / 2);

0 commit comments

Comments
 (0)