esp-idf: Using PSRAM with ESP32-PICO-KIT V4.1 - memory test failed (IDFGH-4526)

Environment

  • Development Kit: ESP32-PICO-Kit
  • Kit version V4.1
  • Module or chip used: ESP32-PICO-D4
  • IDF version (run git describe --tags to find it): v4.3-dev-2136-gb0150615d
  • Build System: idf.py
  • Compiler version (run xtensa-esp32-elf-gcc --version to find it): xtensa-esp32-elf-gcc (crosstool-NG esp-2020r3) 8.4.0
  • Operating System: Windows
  • (Windows only) environment type: ESP Command Prompt
  • Using an IDE?: No
  • Power Supply: USB

Problem Description

I am trying to wire an PSRAM (ESP-PSRAM64H) to the ESP32-PICO-KIT V4.1 and have difficulties to find out the I/O pins to wire it to.

In https://www.esp32.com/viewtopic.php?f=2&t=2713&start=100#p33336 it is suggested to wire SIO 0-3 of the SPRAM Chip to the FSD 0-3 (not populated with pin headers), which means GPIO17, GPIO8, GPIO7, and GPIO11. SCLK is GPIO10, and #CS is GPIO9.

ESP32-PICO-KIT V4.1 has an integrated SPI Flash and it is connected to the 6 pins not populated with pin headers. So wiring the PSRAM to the same pins (except #CS) makes sense.

This also somehow matches the defines in spiram_psram.c from commit bd8733f74f98d95aec04d610426df92cb39c92e6 “feature(psram): add psram support for esp32-pico chip”:

// IO-pins of ESP32-PICO-D4 for PSRAM. PSRAM share clock with flash.
// The CS IO can be overwrite via menuconfig.
#define PICO_FLASH_CLK_IO                6
#define PICO_FLASH_CS_IO                16
#define PICO_FLASH_SPIQ_SD0_IO          17
#define PICO_FLASH_SPID_SD1_IO           8
#define PICO_FLASH_SPIWP_SD3_IO          7
#define PICO_FLASH_SPIHD_SD2_IO         11

#define PICO_PSRAM_CLK_IO                6
#define PICO_PSRAM_CS_IO                CONFIG_PICO_PSRAM_CS_IO
#define PICO_PSRAM_SPIQ_SD0_IO          17
#define PICO_PSRAM_SPID_SD1_IO           8
#define PICO_PSRAM_SPIWP_SD3_IO          7
#define PICO_PSRAM_SPIHD_SD2_IO         11

The only difference is that with the suggestion from above link SCLK is using GPIO10, instead of GPIO6 (shared with SPI flash) as in the defines.

So far, so good, but when I look at a current version of the defines in spiram_psram.c, the defines have changed to:

// IO-pins for PSRAM.
// WARNING: PSRAM shares all but the CS and CLK pins with the flash, so these defines
// hardcode the flash pins as well, making this code incompatible with either a setup
// that has the flash on non-standard pins or ESP32s with built-in flash.
#define PSRAM_SPIQ_SD0_IO          7
#define PSRAM_SPID_SD1_IO          8
#define PSRAM_SPIWP_SD3_IO         10
#define PSRAM_SPIHD_SD2_IO         9

#define FLASH_HSPI_CLK_IO          14
#define FLASH_HSPI_CS_IO           15
#define PSRAM_HSPI_SPIQ_SD0_IO     12
#define PSRAM_HSPI_SPID_SD1_IO     13
#define PSRAM_HSPI_SPIWP_SD3_IO    2
#define PSRAM_HSPI_SPIHD_SD2_IO    4

// PSRAM clock and cs IO should be configured based on hardware design.
// For ESP32-WROVER or ESP32-WROVER-B module, the clock IO is IO17, the cs IO is IO16,
// they are the default value for these two configs.
#define D0WD_PSRAM_CLK_IO          CONFIG_D0WD_PSRAM_CLK_IO  // Default value is 17
#define D0WD_PSRAM_CS_IO           CONFIG_D0WD_PSRAM_CS_IO   // Default value is 16

#define D2WD_PSRAM_CLK_IO          CONFIG_D2WD_PSRAM_CLK_IO  // Default value is 9
#define D2WD_PSRAM_CS_IO           CONFIG_D2WD_PSRAM_CS_IO   // Default value is 10

// For ESP32-PICO chip, the psram share clock with flash. The flash clock pin is fixed, which is IO6.
#define PICO_PSRAM_CLK_IO          6
#define PICO_PSRAM_CS_IO           CONFIG_PICO_PSRAM_CS_IO   // Default value is 10

#define PICO_V3_02_PSRAM_CLK_IO    10
#define PICO_V3_02_PSRAM_CS_IO     9

With this, the 4 data lines are now GPIO7, GPIO8, GPIO10, GPIO9. SCLK remains on GPIO6, and #CS is still on GPIO10 (default of CONFIG_PICO_PSRAM_CS_IO). But GPIO10 is already used as a data line??? Certainly, this can be adjusted in menuconfig to use a different one than 10. However, It would make sense to also change the default here.

However, these pins do not seem to match those used by ESP32-PICO-KIT for SPI-Flash.

These changes have been introduced with commit db138ae19b2778f254a88d041b48dc391cc6a554 “feat(psram): config SPI psram pins based on efuse value”. Could it be that since then PSRAM no longer works with ESP32-PICO-KIT? I guess this is what the comment making this code incompatible with either a setup that has the flash on non-standard pins or ESP32s with built-in flash is supposed to say, right?

I would assume that the following should be used for ESP32-PICO-KIT, as it was in the original commit:

#define PICO_PSRAM_CLK_IO 6 #define PICO_PSRAM_CS_IO CONFIG_PICO_PSRAM_CS_IO (i.e. 10, SPI-Flash uses 16) #define PICO_PSRAM_SPIQ_SD0_IO 17 #define PICO_PSRAM_SPID_SD1_IO 8 #define PICO_PSRAM_SPIWP_SD3_IO 7 #define PICO_PSRAM_SPIHD_SD2_IO 11

Besides the defines, the code in function psram_enable() must also be adjusted for ESP32-PICO-KIT.

Any thoughts, comments?

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 3
  • Comments: 21 (7 by maintainers)

Most upvoted comments

OK, seems that it gets the correct settings from eFuse (I have added some debug messages to psram_enable()):

I (263) psram: This chip is ESP32-PICO
I (263) psram: spiconfig: 0xb408446
I (263) psram: spiconfig: eFuse
I (266) psram: flash_clk_io: 6
I (269) psram: flash_cs_io: 16
I (273) psram: psram_clk_io: 6
I (277) psram: psram_cs_io: 10
I (281) psram: psram_spiq_sd0_io: 17
I (285) psram: psram_spid_sd1_io: 8
I (289) psram: psram_spiwp_sd3_io: 7
I (293) psram: psram_spihd_sd2_io: 11

No luck using a different SPI RAM clock pin (i.e. IO9). It does find the PSRAM chip, but the SPI clock signal is also just 1.8 volts… Just if it would duplicate the flash SPI clock to the RAM SPI clock, since I also see the clock pulses for the flash access on the RAM SPI clock pin…

I also checked the strapping pins, especially IO12/MTDI, since it control the flash voltage. I have added some debug messages in rtc_vddsdio_get_config() in rtc_init.c, and the strapping pin MTDI is low at reset, thus the flash voltage is set to 3.3V (as expected).

I (314) INIT: strap_reg: 0x13
I (317) INIT: tieh: 1 (1=3.3V, 0=1.8V)

I tried exchanging spiwp and spihd, but then it won’t detect the SPIRAM chip at all, so looks like the initial wiring is correct. I also exchanged the ESP-PSRAM64H chip with another one (from the same real), just in case the chip would be defective. No luck either, shows the same error.

Looking at the signals with an oscilloscope, all signals look good, except the FCLK signal (IO6 - flash_clk_io). Its high level only goes up to 1.8 volts, where all the other signals go up to 3.3 volts, as expected. FCLK is shared with the integrated SPI Flash chip. Obviously the flash chip is OK with the 1.8 volts only, it boots up all fine.

Could it be that the SPI RAM chip does not detect all clock pulses because of its level only going up to 1.8 volts? Looking at the datasheet of the ESP-PSRAM64H chips as provided by Espressif, the minimum high level is VCC - 0,4 volts, thus would be 2.9 volts. 1.8 is way to less of course.

So the question is: why is the FCLK line using only 1.8 volts, while the other signals use 3.3 volts?

I could certainly try to use another pin for the CLK for the SPI RAM, but I guess that would be a private hack in spiram_psram.c because the PSRAM CLK signal is not configurable by default.

I added some debug messages into the memory test function:

This somehow looks like a repeating pattern, see below.

Always addresses xxxxxx50 and xxxxxx58 are wrong, and it seems as if one byte of the 32 bit word is somehow switched. The first byte appears at the 4th byte, but with the first 4 bits and second 4 its swapped…

Could this point to some wiring problem, like spiwp and spihd swapped? Or is this a timing problem?

E (888) spiram: p: 0x00000050 - spiram[p]=0xafaaaaaa expected aaaaaafa
E (888) spiram: p: 0x00000058 - spiram[p]=0xacaaaaea expected aaaaaaf2
E (891) spiram: p: 0x00000150 - spiram[p]=0xafaabaaa expected aaaaabfa
E (898) spiram: p: 0x00000158 - spiram[p]=0xacaabaea expected aaaaabf2
E (906) spiram: p: 0x00000250 - spiram[p]=0xafaa8aaa expected aaaaa8fa
E (913) spiram: p: 0x00000258 - spiram[p]=0xacaa8aea expected aaaaa8f2
E (920) spiram: p: 0x00000350 - spiram[p]=0xafaa9aaa expected aaaaa9fa
E (927) spiram: p: 0x00000358 - spiram[p]=0xacaa9afa expected aaaaa9f2
E (934) spiram: p: 0x00000450 - spiram[p]=0xafaaeaaa expected aaaaaefa
E (941) spiram: p: 0x00000458 - spiram[p]=0xacaaeaea expected aaaaaef2
E (949) spiram: p: 0x00000550 - spiram[p]=0xafaafaaa expected aaaaaffa
E (956) spiram: p: 0x00000558 - spiram[p]=0xacaafafa expected aaaaaff2
E (963) spiram: p: 0x00000650 - spiram[p]=0xafaacaaa expected aaaaacfa
E (970) spiram: p: 0x00000658 - spiram[p]=0xacaacaea expected aaaaacf2
E (978) spiram: p: 0x00000750 - spiram[p]=0xafaadaaa expected aaaaadfa
E (985) spiram: p: 0x00000758 - spiram[p]=0xacaadafa expected aaaaadf2
E (992) spiram: p: 0x00000850 - spiram[p]=0xafaa2aaa expected aaaaa2fa
...

I finally got the ESP-PSRAM64H chips and wired them according to above.

It does detect the PSRAM, but the memtest fails:

E (1208) spiram: SPI SRAM memory test fail. 8672/131072 writes failed, first @ 3F800140

It always fails at the same address (3F800140) and the same amount of failures (8672/131072).

I tried with different SPRAM configs, but no difference. When I disable memory test in the config, it starts up fine, but I fear that it will fail later on when the defective memory addresses are used…

Full boot log:

I (31) boot: ESP-IDF v4.3-dev-2398-g2bfdd036b2-dirty 2nd stage bootloader
I (31) boot: compile time 19:13:12
I (33) boot: chip revision: 1
I (37) boot_comm: chip revision: 1, min. bootloader chip revision: 0
I (44) boot.esp32: SPI Speed      : 40MHz
I (48) boot.esp32: SPI Mode       : DIO
I (53) boot.esp32: SPI Flash Size : 2MB
I (57) boot: Enabling RNG early entropy source...
I (63) boot: Partition Table:
I (66) boot: ## Label            Usage          Type ST Offset   Length
I (74) boot:  0 nvs              WiFi data        01 02 00009000 00006000
I (81) boot:  1 phy_init         RF data          01 01 0000f000 00001000
I (89) boot:  2 factory          factory app      00 00 00010000 00100000
I (96) boot: End of partition table
I (100) boot_comm: chip revision: 1, min. application chip revision: 0
I (107) esp_image: segment 0: paddr=00010020 vaddr=3f400020 size=0c448h ( 50248) map
I (137) esp_image: segment 1: paddr=0001c470 vaddr=3ffb0000 size=02e6ch ( 11884) load
I (143) esp_image: segment 2: paddr=0001f2e4 vaddr=40080000 size=00404h (  1028) load
I (144) esp_image: segment 3: paddr=0001f6f0 vaddr=40080404 size=00928h (  2344) load
I (153) esp_image: segment 4: paddr=00020020 vaddr=400d0020 size=1c888h (116872) map
I (209) esp_image: segment 5: paddr=0003c8b0 vaddr=40080d2c size=107fch ( 67580) load
I (251) boot: Loaded app from partition at offset 0x10000
I (251) boot: Disabling RNG early entropy source...
I (263) psram: This chip is ESP32-PICO
I (263) psram: spiconfig: b408446
I (263) psram: spiconfig: eFuse
I (266) psram: flash_clk_io: 6
I (270) psram: flash_cs_io: 16
I (273) psram: psram_clk_io: 6
I (277) psram: psram_cs_io: 10
I (281) psram: psram_spiq_sd0_io: 17
I (285) psram: psram_spid_sd1_io: 8
I (289) psram: psram_spiwp_sd3_io: 7
I (294) psram: psram_spihd_sd2_io: 11
I (299) spiram: Found 64MBit SPI RAM device
I (303) spiram: SPI RAM mode: flash 40m sram 40m
I (308) spiram: PSRAM initialized, cache is in low/high (2-core) mode.
I (315) cpu_start: Pro cpu up.
I (319) cpu_start: Starting app cpu, entry point is 0x400812ec
0x400812ec: call_start_cpu1 at C:/ESP/esp-idf/components/esp_system/port/cpu_start.c:133

I (310) cpu_start: App cpu up.
E (1208) spiram: SPI SRAM memory test fail. 8672/131072 writes failed, first @ 3F800140

E (1208) cpu_start: External RAM failed memory test!

abort() was called at PC 0x4008144f on core 0
0x4008144f: call_start_cpu0 at C:/ESP/esp-idf/components/esp_system/port/cpu_start.c:382 (discriminator 1)


Backtrace:0x4008a8aa:0x3ffe3ba0 0x4008b031:0x3ffe3bc0 0x40090522:0x3ffe3be0 0x4008144f:0x3ffe3c50 0x4007922d:0x3ffe3c80 |<-CORRUPTED
0x4008a8aa: panic_abort at C:/ESP/esp-idf/components/esp_system/panic.c:356

0x4008b031: esp_system_abort at C:/ESP/esp-idf/components/esp_system/system_api.c:108

0x40090522: abort at C:/ESP/esp-idf/components/newlib/abort.c:46

0x4008144f: call_start_cpu0 at C:/ESP/esp-idf/components/esp_system/port/cpu_start.c:382 (discriminator 1)



ELF file SHA256: 8af5787f6c78a355

Rebooting...

That’s an interesting thought… So are the efuse settings set up right automatically? Or do I have to program it somehow?