Mercurial > flash_v2
diff packages/io/flash/current/src/flash.c @ 1723:0cc13d07a67e
* src/flash.c: Support flash blocks of arbitary size. The
DataFlash devices for example have block of 528 bytes.
| author | asl |
|---|---|
| date | Thu, 09 Sep 2004 13:11:46 +0000 |
| parents | c4240af0fa28 |
| children | e290a0372578 |
line wrap: on
line diff
--- a/packages/io/flash/current/src/flash.c +++ b/packages/io/flash/current/src/flash.c @@ -343,6 +343,22 @@ cyg_flash_block_size(const cyg_flashaddr return flash_block_size(dev, flash_base); } +// Return the first address of a block. The flash might not be aligned +// in terms of its block size. So we have to be careful and use +// offsets. +static inline cyg_flashaddr_t +flash_block_begin(cyg_flashaddr_t addr, struct cyg_flash_dev *dev) +{ + size_t block_size; + cyg_flashaddr_t offset; + + block_size = flash_block_size(dev, addr); + + offset = addr - dev->start; + offset = (offset / block_size) * block_size; + return offset + dev->start; +} + __externC int cyg_flash_erase(const cyg_flashaddr_t flash_base, @@ -377,8 +393,7 @@ cyg_flash_erase(const cyg_flashaddr_t fl end_addr = dev->end; } - block_size = flash_block_size(dev, addr); - block = (cyg_flashaddr_t)((size_t)addr & ~(block_size - 1)); + block = flash_block_begin(addr, dev); #ifdef CYGSEM_IO_FLASH_CHATTER dev->pf("... Erase from %p-%p: ", (void*)block, (void*)end_addr); @@ -391,6 +406,8 @@ cyg_flash_erase(const cyg_flashaddr_t fl unsigned char *dp; bool erased = true; + block_size = flash_block_size(dev, addr); + // If there is a read function it probably means the flash // cannot be read directly. if (!dev->funs->flash_read) { @@ -412,7 +429,7 @@ cyg_flash_erase(const cyg_flashaddr_t fl *err_address = block; break; } - block += flash_block_size(dev, block); + block += block_size; #ifdef CYGSEM_IO_FLASH_CHATTER dev->pf("."); #endif @@ -488,7 +505,7 @@ cyg_flash_program(const cyg_flashaddr_t if (size > block_size) size = block_size; // Writing from the middle of a block? - offset = (size_t)addr & (block_size-1); + offset = (size_t)addr % block_size; if (offset) size = MIN(block_size - offset, size); stat = dev->funs->flash_program(dev, addr, ram, size); @@ -576,7 +593,7 @@ cyg_flash_read(cyg_flashaddr_t flash_bas if (size > block_size) size = block_size; // Reading from the middle of a block? - offset = (size_t)addr & (block_size-1); + offset = (size_t)addr % block_size; if (offset) size = MIN(block_size - offset, size); if (dev->funs->flash_read) { @@ -651,8 +668,7 @@ cyg_flash_lock(const cyg_flashaddr_t fla end_addr = dev->end; } - block_size = flash_block_size(dev, addr); - block = (cyg_flashaddr_t)((size_t)addr & ~(block_size - 1)); + block = flash_block_begin(addr, dev); #ifdef CYGSEM_IO_FLASH_CHATTER dev->pf("... Locking from %p-%p: ", (void*)block, (void*)end_addr); @@ -685,7 +701,7 @@ cyg_flash_lock(const cyg_flashaddr_t fla return stat; } - if (flash_base + len - 1 > dev->end) { // Off by one? + if (flash_base + len - 1 > dev->end) { // The region to erase if bigger than this driver handles. Recurse return cyg_flash_lock(dev->end+1, len - (dev->end - flash_base) - 1, @@ -728,8 +744,7 @@ cyg_flash_unlock(const cyg_flashaddr_t f end_addr = dev->end; } - block_size = flash_block_size(dev, addr); - block = (cyg_flashaddr_t)((size_t)addr & ~(block_size - 1)); + block = block = flash_block_begin(addr, dev); #ifdef CYGSEM_IO_FLASH_CHATTER dev->pf("... Unlocking from %p-%p: ", (void*)block, (void*)end_addr); @@ -762,7 +777,7 @@ cyg_flash_unlock(const cyg_flashaddr_t f return stat; } - if (flash_base + len - 1 > dev->end) { // Off by one? + if (flash_base + len - 1 > dev->end) { // The region to erase if bigger than this driver handles. Recurse return cyg_flash_lock(dev->end+1, len - (dev->end - flash_base) - 1,
