Skip to content

REQ: ESP32-S3: Assign efuse bits for PSRAM bus type (IDFGH-7538) #9101

Description

@henrygab

Is your feature request related to a problem? Please describe.

Currently, ESP32-S3 does not have appear to support storing manually selected PSRAM settings. This prevents having a single binary for the ESP32-S3 chip variant (which was possible for ESP32 and ESP32-S2). Currently, there is no programmatic way to detect the PSRAM, and having a mismatch between bootloader and binary will cause boot loop. These are causing confusion and frustration. See, for example, bootloop and bootloader issues.

Describe the solution you'd like

I request that Espressif allocate at least three efuse bits on ESP32-S3 for the purpose of storing manually selected type of PSRAM attached to the processor.

As an example, one solution, similar to the flash's voltage(*) requirement, would be:

  • A first bit (anywhere) that indicates the PSRAM bus type setting is valid.
  • Two bits for storing the configured PSRAM bus type:
    2-Bit Meaning
    11b Undefined / Invalid
    01b QSPI
    10b OPI
    00b No PSRAM

This provides a backwards-compatible method of using the efuses to detect the stored setting, and allows existing modules to have their efuses be updated in-the-field, or at any point in supply chain, as needed.

Out-of-scope for this issue, but enables...

For clarity, I've pushed this section into a collapsible node. These are NOT part of this issue, but rather show how this will enable transitioning to a better experience in a smooth manner....

As soon as it's official which bits are allocated, the following can then occur in parallel, without any bottlenecks or cross-dependencies:

  1. Update of espefuse.py to interpret, display, and allow setting of these bits
  2. Update of 3rd party bootloaders to query and use (if set) these bits
  3. Update of esptool.py (and 3rd party uploading tools) to avoid mismatch between bootloader and application binary

Describe alternatives you've considered

Verbose, so moved to collapsible node...

  1. Not assigning efuse bits. Without an official location to store this critical information, it becomes necessary to keep (and continually update) a list of modules, and what connection type is used. The updating adds perpetual costs to the maintenance of multiple projects, where the preferred goal (for many reasons) is a single binary per platform.

  2. Using customer-defined EFUSE bits. However, this would not resolve issues in hobbyist community, and would not allow tools to be updated to interpret this setting.

  3. Using only two bits. The use of only two bits was considered. However, three bits were used to more closely align with existing similar efuse bits defined by espressif (e.g., flash voltage).

  4. Not defining bit pattern 11b as invalid. However, 11b reflects un-set efuses. Defining this as "not set" reduces the number of user errors. This also makes an explicit choice for the board mandatory.

  5. Not defining a bit patter as No PSRAM. However, an explicit setting for No PSRAM is preferred, so bootloaders could then avoid fallback / autodetection techniques when explicitly indicates no PSRAM is available.

  6. Alternate bit patterns. Specifically, the bit pattern of 00b to indicate No PSRAM was selected to allow a safety fall-back, in case the EFUSE is accidentally programmed with the wrong PSRAM type. That is, it is possible to transition from either QSPI or OPI PSRAM settings (01b or 10b) to disabling PSRAM (00b), because EFUSE may transition only from 1 to 0.


Additional context

See also: espressif/arduino-esp32#6426 (reply in thread)
See also: espressif/arduino-esp32#6646

Example of how a bootloader could use the information

Pseudo-code

...
if (SetupAndValidateKnownPSRAM()) {
    // boot the app
} else {
    // No valid settings in eFuse ...
    // Once efuses are defined, might be possible to define list of all shipped modules
    // and act accordingly.
    // Otherwise, try to boot anyways (backwards compatibility)
}


bool SetupAndValidateKnownPSRAM(void) {
    if (!isAvailable) { return false; }
    // Read the expected PSRAM type from the active app's header
    enum PSRAM_BUS_TYPE appExpectedBusType = ReadActiveAppSettings();

    bool isAvailable = read_efuse( efuse::PSRAM_BUS_TYPE_AVAILABLE );
    enum PSRAM_BUS_TYPE busType = read_efuse( efuse::EFUSE_PSRAM_BUS_TYPE );

    switch (busType) {
        default:
        case PSRAM_BUS_TYPE:Invalid:
            WarnAboutInvalidEFuseSetting();
            return false;
        case PSRAM_BUS_TYPE::QSPI:
            SetupForQspiBasedSPRAM();
            break;
        case PSRAM_BUS_TYPE::OPI:
            SetupForOpiBasedSPRAM();
            break;
        case PSRAM_BUS_TYPE::NoPSRAM:
            break;
    }

    if (appExpectedBusType == PSRAM_BUS_TYPE::NoPSRAM) {
        return true; // OK to boot app that does not use PSRAM
    }
    if (appExpectedBusType != busType) {
        // attempting to boot mismatched APP causes bootloop
        WarnAboutMismatchedApplicationPSRAMBusTypeSetting();
        InfiniteLoop__OR__EnterProgrammingMode();
    }
}

P.S. -- THANK YOU for shipping ESP32-S3 modules with efuses indicating flash voltage settings! This solved large pain points from hobbyists attaching IO12 to various electronics, and having difficult-to-track boot failures.

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions