@@ -234,7 +234,7 @@ void supervisor_flash_flush(void) {
234234 }
235235}
236236
237- static int32_t convert_block_to_flash_addr (uint32_t block ) {
237+ static uint32_t convert_block_to_flash_addr (uint32_t block ) {
238238 if (0 <= block && block < INTERNAL_FLASH_FILESYSTEM_NUM_BLOCKS ) {
239239 // a block in partition 1
240240 return INTERNAL_FLASH_FILESYSTEM_START_ADDR + block * FILESYSTEM_BLOCK_SIZE ;
@@ -244,15 +244,30 @@ static int32_t convert_block_to_flash_addr(uint32_t block) {
244244}
245245
246246mp_uint_t supervisor_flash_read_blocks (uint8_t * dest , uint32_t block , uint32_t num_blocks ) {
247- // Must write out anything in cache before trying to read.
248- supervisor_flash_flush ();
249-
250247 int32_t src = convert_block_to_flash_addr (block );
251248 if (src == -1 ) {
252249 // bad block number
253250 return false;
254251 }
255- memcpy (dest , (uint8_t * ) src , FILESYSTEM_BLOCK_SIZE * num_blocks );
252+
253+ // Determine whether the read is contained within the sector
254+ uint32_t sector_size ;
255+ uint32_t sector_start_addr ;
256+ flash_get_sector_info (src , & sector_start_addr , & sector_size );
257+ // Count how many blocks are left in the sector
258+ uint32_t count = (sector_size - (src - sector_start_addr ))/FILESYSTEM_BLOCK_SIZE ;
259+ count = MIN (num_blocks , count );
260+
261+ if (count < num_blocks && _cache_flash_addr == sector_start_addr ) {
262+ // Read is contained in the cache, so just read cache
263+ memcpy (dest , (_flash_cache + (src - sector_start_addr )), FILESYSTEM_BLOCK_SIZE * num_blocks );
264+ } else {
265+ // The read spans multiple sectors or is in another sector
266+ // Must write out anything in cache before trying to read.
267+ supervisor_flash_flush ();
268+ memcpy (dest , (uint8_t * ) src , FILESYSTEM_BLOCK_SIZE * num_blocks );
269+ }
270+
256271 return 0 ; // success
257272}
258273
@@ -271,7 +286,7 @@ mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t block_num,
271286 uint32_t sector_start_addr ;
272287 flash_get_sector_info (dest , & sector_start_addr , & sector_size );
273288
274- // Fail for any sector outside the 16k ones for now
289+ // Fail for any sector outside what's supported by the cache
275290 if (sector_size > sizeof (_flash_cache )) {
276291 reset_into_safe_mode (FLASH_WRITE_FAIL );
277292 }
0 commit comments