Low level flash programming and erase API. More...
Functions | |
| void | flash_start_xip (void) |
| Initialise QSPI interface and external QSPI devices for execute-in-place. | |
| void | flash_range_erase (uint32_t flash_offs, size_t count) |
| Erase areas of flash. | |
| void | flash_range_program (uint32_t flash_offs, const uint8_t *data, size_t count) |
| Program flash. | |
| void | flash_get_unique_id (uint8_t *id_out) |
| Get flash unique 64 bit identifier. | |
| void | flash_do_cmd_cs (const uint8_t *txbuf, uint8_t *rxbuf, size_t count, uint cs) |
| Execute bidirectional QSPI command. | |
| static void | flash_do_cmd (const uint8_t *txbuf, uint8_t *rxbuf, size_t count) |
| Execute bidirectional flash command on chip select 0. | |
| bool | flash_set_qmi_cs1_setup_function (qmi_setup_function_t function) |
| Set the function to be called to setup the QMI CS1 configuration. | |
| static uint32_t | flash_devinfo_size_to_bytes (flash_devinfo_size_t size) |
| Convert a flash/PSRAM size enum to an integer size in bytes. | |
| static flash_devinfo_size_t | flash_devinfo_bytes_to_size (uint32_t bytes) |
| Convert an integer flash/PSRAM size in bytes to a size enum, as stored in OTP and used by the ROM. | |
| flash_devinfo_size_t | flash_devinfo_get_cs_size (uint cs) |
| Get the size of the QSPI device attached to chip select cs, according to FLASH_DEVINFO. | |
| void | flash_devinfo_set_cs_size (uint cs, flash_devinfo_size_t size) |
| Update the size of the QSPI device attached to chip select cs in the runtime copy of FLASH_DEVINFO. | |
| bool | flash_devinfo_get_d8h_erase_supported (void) |
| Check whether all attached devices support D8h block erase with 64k size, according to FLASH_DEVINFO. | |
| void | flash_devinfo_set_d8h_erase_supported (bool supported) |
| Specify whether all attached devices support D8h block erase with 64k size, in the runtime copy of FLASH_DEVINFO. | |
| uint | flash_devinfo_get_cs_gpio (uint cs) |
| Check the GPIO allocated for each chip select, according to FLASH_DEVINFO. | |
| void | flash_devinfo_set_cs_gpio (uint cs, uint gpio) |
| Update the GPIO allocated for each chip select in the runtime copy of FLASH_DEVINFO. | |
Low level flash programming and erase API.
Note these functions are unsafe if you are using both cores, and the other is executing from flash concurrently with the operation. In this case, you must perform your own synchronisation to make sure that no XIP accesses take place during flash programming. One option is to use the lockout functions.
Likewise they are unsafe if you have interrupt handlers or an interrupt vector table in flash, so you must disable interrupts before calling in this case.
If PICO_NO_FLASH=1 is not defined (i.e. if the program is built to run from flash) then these functions will make a static copy of the second stage bootloader in SRAM, and use this to reenter execute-in-place mode after programming or erasing flash, so that they can safely be called from flash-resident code.
| uint flash_devinfo_get_cs_gpio | ( | uint | cs | ) |
Check the GPIO allocated for each chip select, according to FLASH_DEVINFO.
| cs | Chip select index (only the value 1 is supported on RP2350) |
| flash_devinfo_size_t flash_devinfo_get_cs_size | ( | uint | cs | ) |
Get the size of the QSPI device attached to chip select cs, according to FLASH_DEVINFO.
| cs | Chip select index: 0 is QMI chip select 0 (QSPI CS pin), 1 is QMI chip select 1. |
The bootrom reads the FLASH_DEVINFO OTP data entry from OTP into boot RAM during startup. This contains basic information about the flash device which can be queried without communicating with the external device.(There are several methods to determine the size of a QSPI device over QSPI, but none are universally supported.)
Since the FLASH_DEVINFO information is stored in boot RAM at runtime, it can be updated. Updates made in this way persist until the next reboot. The ROM uses this device information to control some low-level flash API behaviour, such as issuing an XIP exit sequence to CS 1 if its size is nonzero.
If the macro PICO_FLASH_SIZE_BYTES is specified, this overrides the value for chip select 0. This can be specified in a board header if a board is always equipped with the same size of flash.
| bool flash_devinfo_get_d8h_erase_supported | ( | void | ) |
Check whether all attached devices support D8h block erase with 64k size, according to FLASH_DEVINFO.
This controls whether checked_flash_op() ROM API uses D8h 64k block erase where possible, for faster erase times. If not, this ROM API always uses 20h 4k sector erase.
The bootrom loads this flag from the OTP FLASH_DEVINFO data entry during startup, and stores it in boot RAM. You can update the boot RAM copy based on runtime knowledge of the attached QSPI devices.
| void flash_devinfo_set_cs_gpio | ( | uint | cs, |
| uint | gpio | ||
| ) |
Update the GPIO allocated for each chip select in the runtime copy of FLASH_DEVINFO.
| cs | Chip select index (only the value 1 is supported on RP2350) |
| gpio | GPIO index (must be less than NUM_BANK0_GPIOS) |
| void flash_devinfo_set_cs_size | ( | uint | cs, |
| flash_devinfo_size_t | size | ||
| ) |
Update the size of the QSPI device attached to chip select cs in the runtime copy of FLASH_DEVINFO.
| cs | Chip select index: 0 is QMI chip select 0 (QSPI CS pin), 1 is QMI chip select 1. |
| size | The size of the attached device, or FLASH_DEVINFO_SIZE_NONE if there is none on this chip select. |
The bootrom maintains a copy in boot RAM of the FLASH_DEVINFO information read from OTP during startup. This function updates that copy to reflect runtime information about the sizes of attached QSPI devices.
This controls the behaviour of some ROM flash APIs, such as bounds checking addresses for erase/programming in the checked_flash_op() API, or issuing an XIP exit sequence to CS 1 in flash_exit_xip() if the size is nonzero.
| void flash_devinfo_set_d8h_erase_supported | ( | bool | supported | ) |
Specify whether all attached devices support D8h block erase with 64k size, in the runtime copy of FLASH_DEVINFO.
This function updates the boot RAM copy of OTP FLASH_DEVINFO. The flag passed here is visible to ROM APIs, and is also returned in the next call to flash_devinfo_get_d8h_erase_supported()
|
inlinestatic |
Execute bidirectional flash command on chip select 0.
See flash_do_cmd_cs for more details.
| txbuf | Pointer to a byte buffer which will be transmitted to the flash |
| rxbuf | Pointer to a byte buffer where data received from the flash will be written. txbuf and rxbuf may be the same buffer. |
| count | Length in bytes of txbuf and of rxbuf |
| void flash_do_cmd_cs | ( | const uint8_t * | txbuf, |
| uint8_t * | rxbuf, | ||
| size_t | count, | ||
| uint | cs | ||
| ) |
Execute bidirectional QSPI command.
Low-level function to execute a serial command on a device attached to the QSPI interface. Bytes are simultaneously transmitted and received from txbuf and to rxbuf. Therefore, both buffers must be the same length, count, which is the length of the overall transaction. This is useful for reading metadata from the chip, such as device ID or SFDP parameters.
The XIP cache is flushed following each command, in case flash state has been modified. Like other hardware_flash functions, the flash is not accessible for execute-in-place transfers whilst the command is in progress, so entering a flash-resident interrupt handler or executing flash code on the second core concurrently will be fatal. To avoid these pitfalls it is recommended that this function only be used to extract flash metadata during startup, before the main application begins to run: see the implementation of pico_get_unique_id() for an example of this.
| txbuf | Pointer to a byte buffer which will be transmitted |
| rxbuf | Pointer to a byte buffer where received data will be written. txbuf and rxbuf may be the same buffer. |
| count | Length in bytes of txbuf and of rxbuf |
| cs | Chip select index |
| void flash_get_unique_id | ( | uint8_t * | id_out | ) |
Get flash unique 64 bit identifier.
Use a standard 4Bh RUID instruction to retrieve the 64 bit unique identifier from a flash device attached to the QSPI interface. Since there is a 1:1 association between the MCU and this flash, this also serves as a unique identifier for the board.
| id_out | Pointer to an 8-byte buffer to which the ID will be written |
| void flash_range_erase | ( | uint32_t | flash_offs, |
| size_t | count | ||
| ) |
Erase areas of flash.
| flash_offs | Offset into flash, in bytes, to start the erase. Must be aligned to a 4096-byte flash sector. |
| count | Number of bytes to be erased. Must be a multiple of 4096 bytes (one sector). |
| void flash_range_program | ( | uint32_t | flash_offs, |
| const uint8_t * | data, | ||
| size_t | count | ||
| ) |
Program flash.
| flash_offs | Flash address of the first byte to be programmed. Must be aligned to a 256-byte flash page. |
| data | Pointer to the data to program into flash |
| count | Number of bytes to program. Must be a multiple of 256 bytes (one page). |
| bool flash_set_qmi_cs1_setup_function | ( | qmi_setup_function_t | function | ) |
Set the function to be called to setup the QMI CS1 configuration.
| function | The function to be called to setup the QMI CS1 configuration |
| void flash_start_xip | ( | void | ) |
Initialise QSPI interface and external QSPI devices for execute-in-place.
This function performs the same first-time flash setup that would normally occur over the course of the bootrom locating a flash binary and booting it, and that flash binary executing the SDK crt0. Specifically:
This is mostly useful for initialising flash on a PICO_NO_FLASH=1 binary. (In spite of the name, this binary type really means "preloaded to RAM" and there may still be a flash device.)
This function does not preserve the QSPI interface state or pad state. This is in contrast to most other functions in this library, which preserve at least the QSPI pad state. However, on RP2350 it does preserve the QMI window 1 configuration if you have not opted into bootrom CS1 support via FLASH_DEVINFO.