Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
henrygab opened this issue Jun 4, 2022 · 15 comments
Open

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

henrygab opened this issue Jun 4, 2022 · 15 comments
Assignees
Labels
Status: Selected for Development Issue is selected for development Type: Feature Request Feature request for IDF

Comments

@henrygab
Copy link

henrygab commented Jun 4, 2022

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.

@henrygab henrygab added the Type: Feature Request Feature request for IDF label Jun 4, 2022
@espressif-bot espressif-bot added the Status: Opened Issue is new label Jun 4, 2022
@github-actions github-actions bot changed the title REQ: ESP32-S3: Assign efuse bits for PSRAM bus type REQ: ESP32-S3: Assign efuse bits for PSRAM bus type (IDFGH-7538) Jun 4, 2022
@Jason2866
Copy link

+1

@ginkgm
Copy link
Collaborator

ginkgm commented Jun 6, 2022

Hi @henrygab ,

Thanks for your proposal. We will consider this (runtime detection of OPI flash/psram). But since it's a major change (all changes to efuses are not simple), we need a lot more time to discuss about it.

@henrygab
Copy link
Author

henrygab commented Jun 8, 2022

@ginkgm -- This issue is NOT asking for runtime detection of OPI. After all, as you have said, that would be a major change.

Rather, this issue is limited to asking that some e-fuse bits be allocated officially by Espressif (and meaning defined). This will NOT require automatic detection, is 100% backwards-compatible / safe, and enables a smooth(*) transition time.

Please do consider this, in view of understanding the much more limited scope of this request!

(*) Smooth is defined as, "no worse than exists today".

P.S. -- Moved a section in original issue to clarify scope.

@Jason2866
Copy link

Any news?

@henrygab
Copy link
Author

@ginkgm ... Any update?

I ask because it seems there was some confusion about my request. You wrote that I was requesting, "runtime detection of OPI flash/psram" ... although my request was only for the EFUSE bits be allocated from the reserved block of Espressif-controlled bits.

Until the bits are allocated, all attempts to fix the issues are essentially blocked (or require hacks that will cause other problems).

Again ... this is NOT requesting runtime detection to exist(*) ... it's only requesting that three bits be allocated to this purpose (one bit to indicate this information exists / is valid, two bits to indicate the values).

(*) Runtime detection is NOT part if this request ... it's understood that automatic detection may be technically impossible in some scenarios; Rather, this just allows STORING a (manually-supplied) value.

@ginkgm
Copy link
Collaborator

ginkgm commented Sep 21, 2022

Hi @henrygab , @Jason2866 ,

But you still need to use them at runtime, don't you?

From the point of view of maintaining the SDK (ESP-IDF), we almost can't add any logic that rely on this efuse bit, because not all products can correctly get this efuse field burnt. There are:

  • SiP chips with embedded Octal/QPI PSRAM (We used the PKG_VERSION efuse to indicate the embedded devices)

  • Modules with chips + Octal/QPI PSRAM (and we used to not burning package efuses for this kind of products)

  • Standalone chips without any external devices, but customers may design their own PCB and mount PSRAM on it.

    For this case, even if we add a new field, we cannot ensure all the devices have the correct efuse burnt, the official SDK can't build effective logic on it, unless the user themselves make sure the efuses are burnt (or they have to do it).

But if the user have to do it, why it has to be in the efuse rather than the flash, which is possible to overwrite? And the simplest way to record some information in the flash is a simple Kconfig option.

@Jason2866
Copy link

Still a reservation of a efuse would be nice. I do understand that you can not burn the fuses by default. So board manufacturers can do for there boards. At the moment it is a mess, since boards with the same name are sold with all kind of flash/Psram types and sizes. Many users do not manage to get the boards going. If this is not possible a detection utility (esptool.py?) is needed which prints out the size and type of flash and psram. I opened a feature request.

@henrygab
Copy link
Author

Jason2866 responded, and I agree with his statements.

If I understood you, because not all products will have the efuse burnt at factory, you are wondering why it's worthwhile to have in efuses vs. flash.

I will try to simplify to two reasons:

  1. Users cannot rely on the flash, especially when fully erasing / updating bootloader. See, for example, bootloader issues (and other issues linked above).

  2. While it enables a solution for X% at factory (opt-in, backwards-compatible), it also provides a solution for another Y% at board manufacters, and provides a solution for another Z% (any end user / IT department can rely on the information regardless of if the flash was erased).

  3. It provides the foundation for single-bootloader for all "ESP32-S3" devices that have the efuse set. (If I understood correctly, this is currently not possible... but would be after reservation of the bits occurs.)

This is a solution that enables progress towards fewer error conditions. Defining the bits and their meaning is the first step. After this is done, all the following are possible without any synchronization (fully backwards compatible ... unset bits == no information on PSRAM):

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

These are not in scope for this issue ... but they are gated by / blocked by this issue.

@TD-er
Copy link
Contributor

TD-er commented May 7, 2023

Another reason why it would be really useful to check at runtime how the flash/PSRAM is wired is to allow for some pins to be used or not.
For example if the pins for OPI are wired to PSRAM (and/or flash) then this could affect how usable these pins are for other uses.
In my firmware (ESPEasy), I can then disable those GPIO pins for a user to select, while extra pins could be very useful for others to have if they are safe to use.

And the other way around, if the bootloader can also act on these fuse bits, perhaps issues like I had today with the Lilygo T-dongle S3 (16M) could have been prevented.
With QIO_OPI set as memory type, this board completely froze even when flashing or erasing the flash. Esptool.py reported even typical Windows USB errors.
With QIO_QSPI set the board works fine.

@henrygab
Copy link
Author

henrygab commented Jun 23, 2023

Hi @henrygab ,

Thanks for your proposal. We will consider this (runtime detection of OPI flash/psram). But since it's a major change (all changes to efuses are not simple), we need a lot more time to discuss about it.

PLEASE consider just officially MARKING three efuse bits from the reserved pool (reserved == future use by espressif) for this purpose, and defining them as noted above. The sheer number of bootloader variants that must be supported otherwise is geometrically increasing, and is a constant source of friction to the use of these modules.

  • Doing this would NOT require change in or by the factory (shipped modules remain unchanged)
  • Doing this would NOT require change to customer use (no customer impact)
  • Doing this would NOT require change to boards / solutions already deployed (no customer impact)
  • Doing this would NOT require espressif to support or use the efuse bits themselves (really!)

What this does do is provide an OPTION for those who desire to move forward with a solution ... it provides a BACKWARDS COMPATIBLE way forward, without impact on any existing items.

Please?

@blazoncek
Copy link

+1

@softhack007
Copy link

👍 +1

@henrygab
Copy link
Author

henrygab commented Aug 4, 2023

Community Ask: Please set aside some bits in efuse for explicit use of indicating different flash and PSRAM configurations.

Espressif response: Store settings in flash.

But ... flash isn't accessible if the board is fully erased, so it leaves the community confused.

Community Ask: Just reserve three efuse bits ... nothing else!

Espressif response: Any change we make to efuse tooling requires lots of work.

Community Ask: No tooling... Just reserve three efuse bits ... nothing else!

Espressif response: We cannot use this ourselves in manufacturing on all product lines. Therefore, this is not useful.

Community is left confused, since simple zero-overhead solution was rejected.

@Jason2866
Copy link

It seems there is activity. espressif/esptool@b70ead2

@henrygab
Copy link
Author

henrygab commented Aug 4, 2023

It seems there is activity. espressif/esptool@b70ead2

I'm not so sure... From the commit:

Item 0b000 0b001 0b010 0b011 0b100 0b101 0b110 0b111
FLASH_CAP None 8MB 4MB resv'd resv'd resv'd resv'd resv'd
PSRAM_CAP None 8MB 2MB resv'd n/a n/a n/a n/a
FLASH_TEMP ? ? ? ? n/a n/a n/a n/a
FLASH_VENDOR ? ? ? ? ? ? ? ?
PSRAM_TEMP ? ? ? ? n/a n/a n/a n/a
PSRAM_VENDOR ? ? ? ? n/a n/a n/a n/a

On the positive side, it's possible to go from any FLASH_CAP or PSRAM_CAP efuse settings to indicate None, so that's great for when you let the magic smoke out of a chip (or in manu., detect a non-usable chip).

However, unless either:

  • the FLASH_VENDOR and PSRAM_VENDOR represent bus type, or
  • the capacity always corresponds to bus type

Then I think those changes may be tangential....

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Selected for Development Issue is selected for development Type: Feature Request Feature request for IDF
Projects
None yet
Development

No branches or pull requests

7 participants