espressif / esp-idf

Espressif IoT Development Framework. Official development framework for Espressif SoCs.
Apache License 2.0
13.73k stars 7.3k forks source link

Using PSRAM with ESP32-PICO-KIT V4.1 - memory test failed (IDFGH-4526) #6350

Closed i-franzki closed 3 years ago

i-franzki commented 3 years ago

Environment

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?

negativekelvin commented 3 years ago

Commit message says config SPI psram pins based on efuse value meaning the pins can be determined by reading efuse instead of hardcoded so it should still work.

i-franzki commented 3 years ago

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

i-franzki commented 3 years ago

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
i-franzki commented 3 years ago

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...
i-franzki commented 3 years ago

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-franzki commented 3 years ago

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-franzki commented 3 years ago

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-franzki commented 3 years ago

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....

ESP32DE commented 3 years ago

@i-franzki

i have seen your BBS post - you saw my posting in ESP32 BBS ? let us solve the problem in the BBS first then you can write the solution here perhabs or like you want to do the solution info.

app-z commented 3 years ago

I have exactly the same issue My guess we can use 1.8V supply PSRAM only I have the one ESPRESSIF 3,3 В, SOP8, 64 Мбит

Maybe it can be useful https://www.esp32.com/viewtopic.php?f=2&t=2713&start=100#p33336

app-z commented 3 years ago

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....

What the level of MTDI (IO12) at the boot? if you pull it up then all circuit will supply with 1.8V. I just leave it pin free and I see 3V3 levels of signals

To change the strapping bit values, users can apply the external pull-down/pull-up resistances, or use the host
MCU’s GPIOs to control the voltage level of these pins when powering on ESP32.
After reset release, the strapping pins work as normal-function pins.

The operating voltage of ESP32-PICO-D4’s integrated external SPI flash is 3.3 V. Therefore, the strapping pin MTDI should hold bit ”0” during the module power-on reset. 
i-franzki commented 3 years ago

What the level of MTDI (IO12) at the boot? if you pull it up then all circuit will supply with 1.8V. I just leave it pin free and I see 3V3 levels of signals

I leave it free, so its 3.3V. As you already mentioned, ESP32-PICO-D4’s integrated external SPI flash is 3.3 V, so I can't change that. Nevertheless, I tried with IO12 pulled up, but as expected, it won't boot anymore because it won't be able to read from flash with 1.8V. So I need to leave IO12 free to use 3.3V.

My guess we can use 1.8V supply PSRAM only

Quite possible. But this won't work with a ESP32-PICO-D4 because it requires 3.3V for its flash.

The really strange thing is this as mentioned in an earlier post in this issue:

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.

In the meantime, I bought a TTGO T8 V1.7.1 board, and it has 4MB PSRAM (ESP-PSRAM64H chip) on the board. And it works fine, passes the RAM test during boot just fine. If I read the schematics of the TTGO T8 V1.7.1 board correctly, then it operates both, the flash and SPIRAM on 1.8 volts. Which is strange because ESP-PSRAM64H is supposed to work with 3.3 volts, where ESP-PSRAM64 (without H) operates on 1.8 volts. However, the board has a ESP-PSRAM64H ....

app-z commented 3 years ago

https://www.tinypico.com/gettingstarted

https://github.com/tinypico/tinypico-hardware/tree/master/TinyPICO%20V2%20Schematics

Do u think board use 3V3 psram? I not sure

https://datasheet.lcsc.com/szlcsc/Lyontek-Inc-LY68L6400SLIT_C261881.pdf

U board base on esp32-pico-d4 ?

ESP32DE commented 3 years ago

https://www.tinypico.com/gettingstarted

https://github.com/tinypico/tinypico-hardware/tree/master/TinyPICO%20V2%20Schematics

Do u think board use 3V3 psram? I not sure

https://datasheet.lcsc.com/szlcsc/Lyontek-Inc-LY68L6400SLIT_C261881.pdf

U board base on esp32-pico-d4 ?

"L" vs. "S" 3V3 vs. 1V8

http://www.lyontek.com.tw/sc/ddropiram.html

LY68L6400 3v3 LY68S6400 1v8

image

i-franzki commented 3 years ago

My TTGO T8 V1.7.1 is this: https://github.com/LilyGO/TTGO-T8-ESP32/blob/master/t8_v1.7.1.pdf And it says: "ESP32 Module with 1.8V Flash and SRAM. The operating voltage for signals marked in blue is 1.8V". And the signals related to Flash and PSRAM are blue.

It uses a ESP32-D0WDQ6 chip (i.e. not a ESP32­-PICO­-D4 chip).

negativekelvin commented 3 years ago

@i-franzki have you checked the actual part number of the flash chip? The schematic shows it is possible for them to ship either a 1.8v or 3.3v version.

app-z commented 3 years ago

for ESP32-D0WDQ6 u can resoldering FLASH chip to 3V3. Its cost couple of dollars for bunch of chip

projectgus commented 3 years ago

Hi @i-franzki,

Do you have a photo of your PICO-KIT+PSRAM wiring setup that you can share?

The fact that some addresses test successfully and some fail makes me think that this is some kind of signal integrity, cross-talk, or power decoupling issue (triggered by some particular address or data pattern on the SPI bus). The PSRAM runs at 40MHz or 80MHz, and these are both pretty high clock speeds when using point to point wiring and 0.1" headers.

i-franzki commented 3 years ago

Hi @projectgus, please see here: https://www.esp32.com/viewtopic.php?f=2&t=2713&start=140#p70815

projectgus commented 3 years ago

Hi @i-franzki,

Did you make any progress with this? I'm not seeing any problems with your setup, except maybe a signal integrity issue due to the board layout (although it looks OK to me, piggybacking on the layout like this is suboptimal so there's always a chance it's causing some problem).

Is it possible the PSRAM chip has been damaged during soldering or otherwise?

projectgus commented 3 years ago

Closing as it doesn't seem like this is something we can fix in ESP-IDF.