Skip to content

any plan for SDK support for initializing & using a second flash chip on rp2350? #2205

Open

Description

@mmalex

the datasheet and design guide both provide guidance on attaching a second flash chip and using eg GPIO0 in GPIO_FUNC_XIP_CS1 mode to provide a second window of flash ram. however grepping for 'GPIO_FUNC_XIP_CS1' in this repo, the examples repo, and the issues yields no hits other than its numerical define value. I assume to actually make use of a flash chip sitting on the second chipselect line, we'd need to initialize it (sending whatever commands the flash chip needs to 'come alive') and enable it in XIP.
my vague impression from the board options you can set is that configuring flash chips reliably is... difficult (boot stage 2 does this normally I think?) so my question is basically - are there any plans for the SDK to provide functions to 'bring up' a second flash chip? if not, are there any plans to add an example showing how to do this 'raw'?

I have found some code in the wild that configures PSRAM chips, but I am unsure if the timing etc is appropriate for flash chips. any pointers on either the SDK plans or example code or documentation appreciated! thankyou.

Activity

  1. lurch commented on Jan 22, 2025

    @lurch
    Contributor

    however grepping for 'GPIO_FUNC_XIP_CS1' in this repo, the examples repo, and the issues yields no hits other than its numerical define value.

    Looks like https://github.com/raspberrypi/pico-sdk/blob/master/src/rp2350/hardware_structs/include/hardware/structs/io_bank0.h#L41 corresponds to the "QMI CS1n" in table 644 in https://datasheets.raspberrypi.com/rp2350/rp2350-datasheet.pdf (in case that provides you with additional leads).

    I'm afraid I don't know the answers to your questions, but I suspect it might fall into the same "not currently" category as #1815 ?
    (EDIT: I don't work directly on pico-sdk myself, which is why I can't provide concrete answers. but I help with triaging GitHub issues)

  2. mmalex commented on Jan 22, 2025

    @mmalex
    Author

    thanks for the quick response! yeah it seems that at least as far as I can tell, there is some 'copy pasted' code that originated with sparkfun for using PSRAM chips, which shows up on github in 30 or so repos, copy pasted. eg
    https://github.com/earlephilhower/arduino-pico/blob/9480c2a55d7cc9ceebd0f4f6c3f67a65dcdaf5d5/cores/rp2040/psram.cpp

    my current plan is to take some variation of that code, read the sdk's / bootrom's flash initialization code, perhaps the timing registers from M0 to M1, and try to muddle through.

    i guess then this issue turns into a feature request: I do realise you can't write SDK code for every possible peripheral, but on the other hand (1) there's code getting blindly copy pasted out there to configure PSRAM on the QMI peripheral, a sign there's a possible gap in the official documentation or samples, (2) the stage 2 bootloader already has all the code for configuring flash chips, so the sdk could perhaps make available that 'knowledge' for the second chip select (3) the other peripherals have SDK functions and samples to configure 'common use cases', and I'd argue that 'putting a second flash chip' (as suggested by the rp2350 hardware design guide) is a fairly common use case of the XIP / QMI hardware, to the point that it would be awesome if the sdk had some function like bring_up_a_second_flash_chip_like_the_main_one_please(int gpio_for_chipselect).

    all of which was by way of pitching for my feature request, as opposed to complaining :)

    lastly, the flash library of the sdk seems to have some support for the second flash chip, making some reference to FLASH_DEVINFO - so I will go down that rabbithole in case that yields some extra info. if anyone happens to know if this is all doable via FLASH_DEVINFO, or similar, let me know :) thanks!

    thanks again

  3. mmalex commented on Jan 22, 2025

    @mmalex
    Author

    (update: the SDK docs say, for example:
    ...FLASH_DEVINFO, stored in bootram. This is initialised by the bootrom to the OTP value OTP_DATA_FLASH_DEVINFO, if OTP_DATA_BOOT_FLAGS0_FLASH_DEVINFO_ENABLE is set; otherwise it is initialised to 16 MiB for chip select 0 and 0 bytes for chip select 1. FLASH_DEVINFO can be updated at runtime by writing to its location in bootram, the pointer to which can be looked up in the ROM table.
    but I can't find a great deal of information about this

  4. lurch commented on Jan 22, 2025

    @lurch
    Contributor

    I think @will-v-pi might have some knowledge about bootram? (as I think picotool might have some interactions with it?)

    bring_up_a_second_flash_chip_like_the_main_one_please(int gpio_for_chipselect)

    😂 Brilliant function name!

  5. will-v-pi commented on Jan 22, 2025

    @will-v-pi
    Contributor

    See OTP_DATA_FLASH_DEVINFO in otp_data.h for all the info on how flash_devinfo works. If you don't want to change the OTP bits on your chip, then you can use the flash functions flash_devinfo_set_cs_size, flash_devinfo_set_d8h_erase_supported and flash_devinfo_set_cs_gpio to configure flash_devinfo at runtime, and then use a flash programming operation or call rom_connect_internal_flash to get the bootrom to apply those changes.

    Note that there is a bootrom bug (errata E14) which means the bootrom won't configure the pads correctly if you're using CS1 on any GPIO other than 0, so you'll need to configure pads yourself. Also, it's not possible to boot from CS1, you can only boot from CS0.

    The bootrom should configure all the timings to work with everything (see rom_flash_exit_xip), but if you want faster timings for your seconf then you'll need to do that yourself - if using the same flash chips on CS0 and CS1 you can just copy the timings etc across from M0 to M1, as the bootrom configures good timings for CS0 at boot.

  6. mmalex commented on Jan 22, 2025

    @mmalex
    Author

    hah I hope that you go for exactly that function name. I found a commit from @Wren6991 where he was improving the support of the flash library for programming the second flash chip - great that that exists - but the commit message makes oblique reference to perhaps needing to initialize such a second chip in the stage 2 bootloader, perhaps maybe -
    7b07b0b

    • see the end of that commit message - ...the device on chip select 1 will continue to function correctly, but full performance won't be restored until it is reinitialised. The best way to handle this is initialising both chip select devices in your XIP setup function (your boot2).
      I am using the sdk provided boot2, via #define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1 as it happens, as I am using W25Q128JVZP . perhaps what's needed is an example or a variation of the boot stage 2 W25Q080.s that can handle two chips? flailing around at this point :)
  7. mmalex commented on Jan 22, 2025

    @mmalex
    Author

    @will-v-pi thanks for the reply! I do happen to be using the same type of chip for both CS0 and CS1, and its fine to only boot from the chip on CS0. I'm not sure Im ready to add a OTP flashing step to my build process, so assuming that I use the default WS25Q080 boot2 thing, then what I should do if I understand correctly is:

    • boot as usual
    • set GPIO0 function to CSn
    • call flash_devinfo_set_cs_size to set the second chip to 16mb
    • call rom_connect_internal_flash (I havent looked at this yet)
    • ?? send some commands to the second flash chip to reset it, switch it to quad spi mode, and so on? ie replicate all the steps that the boot2 loader did for the main flash chip ??
    • copy the timing registers from QMI registers for m0 to QMI registers for m1 for more speed
    • ?? configure the QMI to use the right commands? or maybe this was done in the previous ?? step

    am I on the right path here?
    or teleport into the future when y'all have made bring_up_a_second_flash_chip_like_the_main_one_please :)

  8. mmalex commented on Jan 22, 2025

    @mmalex
    Author

    Note that there is a bootrom bug (errata E14) which means the bootrom won't configure the pads correctly if you're using CS1 on any GPIO other than 0, so you'll need to configure pads yourself. Also, it's not possible to boot from CS1, you can only boot from CS0.

    is this documented anywhere? the public datasheet doesn't list an E14 that I can see.
    as it happens, i'm using GPIO 0 so... it probably doesnt affect me.

  9. will-v-pi commented on Jan 22, 2025

    @will-v-pi
    Contributor

    Note that there is a bootrom bug (errata E14) which means the bootrom won't configure the pads correctly if you're using CS1 on any GPIO other than 0, so you'll need to configure pads yourself. Also, it's not possible to boot from CS1, you can only boot from CS0.

    is this documented anywhere? the public datasheet doesn't list an E14 that I can see. as it happens, i'm using GPIO 0 so... it probably doesnt affect me.

    It should be in the next RP2350 datasheet release whenever that is, along with all the security errata

  10. lurch commented on Jan 22, 2025

    @lurch
    Contributor
  11. will-v-pi commented on Jan 22, 2025

    @will-v-pi
    Contributor

    am I on the right path here?

    You're on the right path - note that if you copy all the qmi_hw->m[0] stuff to qmi_hw->m[1] that does the commands and the timings together.

  12. added this to the 2.2.0 milestone on Jan 22, 2025
  13. kilograham commented on Jan 22, 2025

    @kilograham
    Contributor

    Adding the feature request to 2.2.0 though i think to follow naming convention it should be flash_bring_up_a_second_chip_like_the_main_one_please()!

  14. mmalex commented on Jan 22, 2025

    @mmalex
    Author

    You're on the right path - note that if you copy all the qmi_hw->m[0] stuff to qmi_hw->m[1] that does the commands and the timings together.

    cool! can i avoid manually sending reset / quad enable commands by doing the connect_pads call perhaps followed by a xip_leave and xip_enter? the psram code i see around manually sends resets but id love to avoid that if i can just call bootrom/sdk routines.

  15. mrdudz commented on Jan 26, 2026

    @mrdudz

    I'd like to second this request - struggling to set this up, a working example would be really nice to have

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions