Mercurial > flash_v2
diff packages/io/flash/current/src/flash.c @ 1742:a668b95e5f2e
Only include the support for indirect flash reads if there are devices
which need it.
| author | bartv |
|---|---|
| date | Sat, 20 Nov 2004 23:31:59 +0000 |
| parents | 9464c6747e99 |
| children | 0d824ba900cc |
line wrap: on
line diff
--- a/packages/io/flash/current/src/flash.c +++ b/packages/io/flash/current/src/flash.c @@ -586,11 +586,10 @@ cyg_flash_read(cyg_flashaddr_t flash_bas cyg_flashaddr_t *err_address) { struct cyg_flash_dev * dev; - cyg_flashaddr_t addr, end_addr, block; + cyg_flashaddr_t addr, end_addr; unsigned char * ram = (unsigned char *)ram_base; - size_t read_count, offset; + size_t read_count; int stat = CYG_FLASH_ERR_OK; - int d_cache, i_cache; if (!init) return CYG_FLASH_ERR_NOT_INIT; @@ -611,52 +610,61 @@ cyg_flash_read(cyg_flashaddr_t flash_bas } read_count = (end_addr + 1) - flash_base; - // The first read may be in the middle of a block. Do the necessary - // adjustment here rather than inside the loop. - block = flash_block_begin(flash_base, dev); - if (addr == block) { - offset = 0; - } else { - offset = addr - block; - } - #ifdef CYGSEM_IO_FLASH_CHATTER dev->pf("... Read from %p-%p to %p: ", addr, end_addr, ram_base); #endif - - HAL_FLASH_CACHES_OFF(d_cache, i_cache); - FLASH_Enable(flash_base, end_addr); - while (read_count > 0) { - size_t block_size = flash_block_size(dev, addr); - size_t this_read; - if (read_count > (block_size - offset)) { - this_read = block_size - offset; - } else { - this_read = read_count; - } - // Only the first block may need the offset - offset = 0; + + // If the flash is directly accessible, just read it in one go. This + // still happens with the mutex locked to protect against concurrent + // programs/erases. + if (! dev->funs->flash_read) { + memcpy(ram, (void*)addr, read_count); + } else { +#ifndef CYGHWR_IO_FLASH_INDIRECT_READS + CYG_FAIL("read function supplied but indirect reads not enabled"); + stat = CYG_FLASH_ERR_PROTOCOL; +#else + // We have to indirect through the device driver. + // The first read may be in the middle of a block. Do the necessary + // adjustment here rather than inside the loop. + int d_cache, i_cache; + size_t offset; + cyg_flashaddr_t block = flash_block_begin(flash_base, dev); + if (addr == block) { + offset = 0; + } else { + offset = addr - block; + } + HAL_FLASH_CACHES_OFF(d_cache, i_cache); + FLASH_Enable(flash_base, end_addr); + while (read_count > 0) { + size_t block_size = flash_block_size(dev, addr); + size_t this_read; + if (read_count > (block_size - offset)) { + this_read = block_size - offset; + } else { + this_read = read_count; + } + // Only the first block may need the offset + offset = 0; - if (dev->funs->flash_read) { - stat = dev->funs->flash_read(dev, addr, ram, this_read); - stat = dev->funs->flash_hwr_map_error(dev,stat); - } else { - memcpy(ram, (void *)addr, this_read); - stat = CYG_FLASH_ERR_OK; - } - if (CYG_FLASH_ERR_OK != stat && err_address) { - *err_address = addr; - break; - } + stat = dev->funs->flash_read(dev, addr, ram, this_read); + stat = dev->funs->flash_hwr_map_error(dev,stat); + if (CYG_FLASH_ERR_OK != stat && err_address) { + *err_address = addr; + break; + } #ifdef CYGSEM_IO_FLASH_CHATTER - dev->pf("."); + dev->pf("."); #endif - read_count -= this_read; - addr += this_read; - ram += this_read; + read_count -= this_read; + addr += this_read; + ram += this_read; + } + FLASH_Disable(flash_base, end_addr); + HAL_FLASH_CACHES_ON(d_cache, i_cache); +#endif } - FLASH_Disable(flash_base, end_addr); - HAL_FLASH_CACHES_ON(d_cache, i_cache); #ifdef CYGSEM_IO_FLASH_CHATTER dev->pf("\n"); #endif
