Skip to content

Allow flash programming of partial pages (<256 bytes)  #1169

@hattesen

Description

@hattesen

The current hardware_flash/flash.c implementation validates parameters to flash_range_program(uint32_t flash_offs, const uint8_t *data, size_t count) ensuring that 'flash_offs' is on a page boundary (% 256 == 0) as well as byte countis a multiple of a full page (256), which is also documented in the API documentation:

// pico-sdk/src/rp2_common/hardware_flash/include/hardware/flash.h
/*! \brief  Program flash
 *  \ingroup hardware_flash
 *
 * \param flash_offs Flash address of the first byte to be programmed. Must be aligned to a 256-byte flash page.
 * \param data Pointer to the data to program into flash
 * \param count Number of bytes to program. Must be a multiple of 256 bytes (one page).
 */
void flash_range_program(uint32_t flash_offs, const uint8_t *data, size_t count);

Implementation: /src/rp2_common/hardware_flash/flash.c:

// pico-sdk/src/rp2_common/hardware_flash/flash.c
void __no_inline_not_in_flash_func(flash_range_program)(uint32_t flash_offs, const uint8_t *data, size_t count) {
    ...
    invalid_params_if(FLASH, flash_offs & (FLASH_PAGE_SIZE - 1));
    invalid_params_if(FLASH, count & (FLASH_PAGE_SIZE - 1));
    ...

When implementing EEPROM emulation or a File System backed by the QSPI (NOR) Flash (above the XIP address range), it severely restricts the potential speed and increases SRAM requirements, as every writes to Flash will require a read-modify-write cycle:

  1. Full page (256 bytes) read
  2. Modify page
  3. Full page (256 bytes) program using flash_range_program()

The SPI connected Serial Flash IC used with the RP2040, does not have ANY restrictions regarding starting address or number of bytes written, when using the Page Program (02h) instruction (see Winbond W25Q16JV datasheet, section 9.2.13 for details):

The Page Program instruction allows from one byte to 256 bytes (a page) of data to be programmed at
previously erased (FFh) memory locations

Would it be possible to add a facility (library function) allowing partial page programming at arbitrary addresses, using an API similar to the flash_range_program(uint32_t flash_offs, const uint8_t *data, size_t count) function?
This function may likely restrict all data to be written to be located in ONE 256 byte page, and not allow wrapping (to the beginning of the page, which is the standard behavior of the underlying Serial Flash.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions