You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
any plan for SDK support for initializing & using a second flash chip on rp2350? #2205
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.
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)
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!
(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
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.
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 :)
@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 :)
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.
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
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.
Activity
lurch commentedon Jan 22, 2025
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-sdkmyself, which is why I can't provide concrete answers. but I help with triaging GitHub issues)mmalex commentedon Jan 22, 2025
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
mmalex commentedon Jan 22, 2025
(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
lurch commentedon Jan 22, 2025
I think @will-v-pi might have some knowledge about bootram? (as I think
picotoolmight have some interactions with it?)😂 Brilliant function name!
will-v-pi commentedon Jan 22, 2025
See
OTP_DATA_FLASH_DEVINFOinotp_data.hfor 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 functionsflash_devinfo_set_cs_size,flash_devinfo_set_d8h_erase_supportedandflash_devinfo_set_cs_gpioto configure flash_devinfo at runtime, and then use a flash programming operation or callrom_connect_internal_flashto 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.mmalex commentedon Jan 22, 2025
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
...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 1as 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 :)mmalex commentedon Jan 22, 2025
@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:
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:)mmalex commentedon Jan 22, 2025
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.
will-v-pi commentedon Jan 22, 2025
It should be in the next RP2350 datasheet release whenever that is, along with all the security errata
lurch commentedon Jan 22, 2025
ICYMI: https://www.raspberrypi.com/news/security-through-transparency-rp2350-hacking-challenge-results-are-in/
will-v-pi commentedon Jan 22, 2025
You're on the right path - note that if you copy all the
qmi_hw->m[0]stuff toqmi_hw->m[1]that does the commands and the timings together.kilograham commentedon Jan 22, 2025
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()!mmalex commentedon Jan 22, 2025
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.
mrdudz commentedon Jan 26, 2026
I'd like to second this request - struggling to set this up, a working example would be really nice to have