Index: io/flash/current/ChangeLog =================================================================== RCS file: /cvs/ecos/ecos/packages/io/flash/current/ChangeLog,v retrieving revision 1.38.2.6 diff -u -r1.38.2.6 ChangeLog --- io/flash/current/ChangeLog 21 Aug 2004 13:47:55 -0000 1.38.2.6 +++ io/flash/current/ChangeLog 9 Sep 2004 13:03:56 -0000 @@ -1,3 +1,8 @@ +2004-09-09 Andrew Lunn + + * src/flash.c: Support flash blocks of arbitary size. The + DataFlash devices for example have block of 528 bytes. + 2004-08-21 Andrew Lunn * removed the functions cyg_flash_get_limits and Index: io/flash/current/src/flash.c =================================================================== RCS file: /cvs/ecos/ecos/packages/io/flash/current/src/flash.c,v retrieving revision 1.26.2.3 diff -u -r1.26.2.3 flash.c --- io/flash/current/src/flash.c 21 Aug 2004 13:47:56 -0000 1.26.2.3 +++ io/flash/current/src/flash.c 9 Sep 2004 13:03:57 -0000 @@ -343,6 +343,22 @@ 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 @@ 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 @@ 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 @@ *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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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,