rp2040: fix audio glitch at soft-reload

The internal flash cache wasn't being properly used, because
`write_blocks` unconditionally performed the flash write.

Fixing this so that the write's not done until `internal_flash_flush`
fixes the problem in my test program with i2sout & synthio.

as a future optimization, `flash_read_blocks` could learn to read out
of the cache, but that's probably not super important.
This commit is contained in:
Jeff Epler 2023-05-04 08:41:23 -05:00
parent e23e7d3b3f
commit a388a59543
No known key found for this signature in database
GPG Key ID: D5BF15AB975AB4DE
1 changed files with 4 additions and 6 deletions

View File

@ -95,14 +95,16 @@ void port_internal_flash_flush(void) {
if (_cache_lba == NO_CACHE) {
return;
}
// Make sure we don't have an interrupt while we do flash operations.
common_hal_mcu_disable_interrupts();
flash_range_erase(CIRCUITPY_CIRCUITPY_DRIVE_START_ADDR + _cache_lba, SECTOR_SIZE);
flash_range_program(CIRCUITPY_CIRCUITPY_DRIVE_START_ADDR + _cache_lba, _cache, SECTOR_SIZE);
common_hal_mcu_enable_interrupts();
_cache_lba = NO_CACHE;
common_hal_mcu_enable_interrupts();
}
mp_uint_t supervisor_flash_read_blocks(uint8_t *dest, uint32_t block, uint32_t num_blocks) {
port_internal_flash_flush(); // we never read out of the cache, so we have to write it if dirty
memcpy(dest,
(void *)(XIP_BASE + CIRCUITPY_CIRCUITPY_DRIVE_START_ADDR + block * FILESYSTEM_BLOCK_SIZE),
num_blocks * FILESYSTEM_BLOCK_SIZE);
@ -118,6 +120,7 @@ mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t lba, uint32
uint8_t block_offset = block_address % blocks_per_sector;
if (_cache_lba != block_address) {
port_internal_flash_flush();
memcpy(_cache,
(void *)(XIP_BASE + CIRCUITPY_CIRCUITPY_DRIVE_START_ADDR + sector_offset),
SECTOR_SIZE);
@ -133,11 +136,6 @@ mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t lba, uint32
FILESYSTEM_BLOCK_SIZE);
block++;
}
// Make sure we don't have an interrupt while we do flash operations.
common_hal_mcu_disable_interrupts();
flash_range_erase(CIRCUITPY_CIRCUITPY_DRIVE_START_ADDR + sector_offset, SECTOR_SIZE);
flash_range_program(CIRCUITPY_CIRCUITPY_DRIVE_START_ADDR + sector_offset, _cache, SECTOR_SIZE);
common_hal_mcu_enable_interrupts();
}
return 0; // success