From 5f6a68a03b3b41b104b4e29efdcb7e7a1e87df44 Mon Sep 17 00:00:00 2001 From: Lukas Gehreke Date: Tue, 13 Feb 2024 17:17:18 +0100 Subject: [PATCH] drivers: flash: Added buffered write for addresses in flash on rp2040 It is impossible to perform flash reads during a flash write. When the data to write to flash lies in the flash itself, it is buffered in ram before writing. Signed-off-by: Lukas Gehreke --- drivers/flash/flash_rpi_pico.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/flash/flash_rpi_pico.c b/drivers/flash/flash_rpi_pico.c index e9a386b06a0..01ace5f68b5 100644 --- a/drivers/flash/flash_rpi_pico.c +++ b/drivers/flash/flash_rpi_pico.c @@ -61,6 +61,7 @@ enum outover { static ssi_hw_t *const ssi = (ssi_hw_t *)SSI_BASE_ADDRESS; static uint32_t boot2_copyout[BOOT2_SIZE_WORDS]; static bool boot2_copyout_valid; +static uint8_t flash_ram_buffer[PAGE_SIZE]; static void __no_inline_not_in_flash_func(flash_init_boot2_copyout)(void) { @@ -223,22 +224,25 @@ static int flash_rpi_write(const struct device *dev, off_t offset, const void *d if ((offset & (PAGE_SIZE - 1)) > 0) { bytes_to_write = MIN(PAGE_SIZE - (offset & (PAGE_SIZE - 1)), size); - flash_write_partial(offset, data_pointer, bytes_to_write); + memcpy(flash_ram_buffer, data_pointer, bytes_to_write); + flash_write_partial(offset, flash_ram_buffer, bytes_to_write); data_pointer += bytes_to_write; size -= bytes_to_write; offset += bytes_to_write; } - if (size >= PAGE_SIZE) { - bytes_to_write = size & ~(PAGE_SIZE - 1); - flash_range_program(offset, data_pointer, bytes_to_write); + while (size >= PAGE_SIZE) { + bytes_to_write = PAGE_SIZE; + memcpy(flash_ram_buffer, data_pointer, bytes_to_write); + flash_range_program(offset, flash_ram_buffer, bytes_to_write); data_pointer += bytes_to_write; size -= bytes_to_write; offset += bytes_to_write; } if (size > 0) { - flash_write_partial(offset, data_pointer, size); + memcpy(flash_ram_buffer, data_pointer, size); + flash_write_partial(offset, flash_ram_buffer, size); } irq_unlock(key);