esp-hal icon indicating copy to clipboard operation
esp-hal copied to clipboard

ESP32 PSRAM behaves erratically if flashed using 80Mhz flash mode

Open daagaak opened this issue 1 year ago • 3 comments

I've been experiencing some erratic behaviour in my ESP32 trying to enable PSRAM on my WROOM-E module (confirmed to have an 8MB PSRAM module).

Attempting to synthesize this down to a broken test case, I generated a new esp-template project, and replaced the heap section with:

fn init_heap(p: PSRAM) {
    esp_hal::psram::init_psram(p);
    unsafe {
        ALLOCATOR.init(
            esp_hal::psram::psram_vaddr_start() as *mut u8,
            esp_hal::psram::PSRAM_BYTES,
        );
    }
}

And changed the init_heap call to be:

    init_heap(peripherals.PSRAM);

This actually works as expected when you espflash with the default settings. However, if you bump up the flash speed to 80mhz with -f 80mhz then I've seen it either:

  • Hang during PSRAM init
  • Throw a LoadProhibited during PSRAM init
  • Throw a IllegalInstruction during PSRAM init.

I think this is because the esp32 HAL PSRAM code assumes that you're running in 40mhz Flash/40mhz PSRAM mode:

 345⋮    │        let mode = PsramCacheSpeed::PsramCacheF40mS40m; // How to make this configurable

daagaak avatar May 19 '24 22:05 daagaak

I think this is because the esp32 HAL PSRAM code assumes that you're running in 40mhz Flash/40mhz PSRAM mode:

Could you try changing this locally in esp-hal and seeing if with the correct mode it works?

MabezDev avatar May 20 '24 09:05 MabezDev

Yes is does. I've been running with it set (unconditionally) to PsramCacheF80S80 since yesterday and it seems to work reliably.

daagaak avatar May 20 '24 14:05 daagaak

I think the comment // How to make this configurable is the key thing - we could use (another) cargo-feature for it but ideally, we should have #1111

bjoernQ avatar May 21 '24 08:05 bjoernQ

I poked around at this a little bit. I think that the features can be removed completely, and instead we can pass this to psram::init as a configuration.

MabezDev avatar Sep 16 '24 15:09 MabezDev

I poked around at this a little bit. I think that the features can be removed completely, and instead we can pass this to psram::init as a configuration.

Oh!

https://github.com/esp-rs/esp-hal/blob/45806dfba02056a14dd11775a8fdd23879c06212/esp-hal/build.rs#L215-L235 makes completely removing the features not a great option - we could always reserve the full amount of cache like we do on S3 but especially on S2 8k less RAM (when not having access to PSRAM) is not ideal

We can of course make the RAM size and the flash-frequency a run-time config - but I think we should keep a psram and a octal-psram feature

bjoernQ avatar Sep 17 '24 08:09 bjoernQ

I think that should be fine, we will probably need at least one feature because at some point we'll need to resolve https://github.com/esp-rs/esp-hal/issues/2027 by adding or changing the way we compile some things. Funnily enough that issue doesn't actually affect the s2 :D.

I think we just need a single psram feature though, right? S2 doesn't support octal, and we already use all the available cache for s3 - I did a quick look and I don't think the opsram features are used anywhere else (other than where we will replace them).

MabezDev avatar Sep 17 '24 10:09 MabezDev

I guess we need to keep both features - also ESP-IDF does this

    if(CONFIG_SPIRAM_MODE_QUAD)
        list(APPEND srcs "${target}/esp_psram_impl_quad.c")
    elseif(CONFIG_SPIRAM_MODE_OCT)
        list(APPEND srcs "${target}/esp_psram_impl_octal.c")
    endif()

We could just include both implementations and decide at runtime but a lot of that code needs to live in IRAM so I'm not sure that is the best option

bjoernQ avatar Sep 17 '24 10:09 bjoernQ

Closed via #2178

MabezDev avatar Sep 23 '24 13:09 MabezDev

Hello, I've been trying out the example psram_octal in the latest master on a ESP32-S3. The example works perfectly, but if I change the speed of the PSRAM to 80 mhz in the following way, the execution gets past the PSRAM initialization but gets stuck inside init_psram_heap

let peripherals = esp_hal::init(esp_hal::Config::default());

let (start, size) = psram::init_psram(
    peripherals.PSRAM,
    psram::PsramConfig {
        ram_frequency: esp_hal::psram::SpiRamFreq::Freq80m,
        ..Default::default()
    },
);
// gets here
init_psram_heap(start, size);
// but not here

Should I change anything else and/or is this feature supported on all S3 or it also requires some support in the chip/board? I'm using a ESP32-S3-WROOM-1-N16R8 if that matters

william-spinelli-one avatar Sep 26 '24 06:09 william-spinelli-one