Mercurial > flash_v2
changeset 1199:e8111345b655
* include/flash_at49xxxx.inl: the program/erase completion had a
race condtion. Changes algorithms to one that does not suffer
from potential race conditions.
| author | asl |
|---|---|
| date | Sat, 06 Sep 2003 15:01:30 +0000 |
| parents | 593695e176a8 |
| children | 0e41ddaf36fe |
| files | packages/devs/flash/atmel/at49xxxx/current/ChangeLog packages/devs/flash/atmel/at49xxxx/current/include/flash_at49xxxx.inl |
| diffstat | 2 files changed, 27 insertions(+), 16 deletions(-) [+] |
line wrap: on
line diff
--- a/packages/devs/flash/atmel/at49xxxx/current/ChangeLog +++ b/packages/devs/flash/atmel/at49xxxx/current/ChangeLog @@ -1,3 +1,9 @@ +2003-08-08 Oyvind Harboe <oyvind.harboe@zylin.com> + + * include/flash_at49xxxx.inl: the program/erase completion had a + race condtion. Changes algorithms to one that does not suffer + from potential race conditions. + 2003-07-15 Jonathan Larmour <jifl@eCosCentric.com> * include/flash_at49xxxx.inl: Reorganise to support boot blocks,
--- a/packages/devs/flash/atmel/at49xxxx/current/include/flash_at49xxxx.inl +++ b/packages/devs/flash/atmel/at49xxxx/current/include/flash_at49xxxx.inl @@ -57,6 +57,7 @@ #include <pkgconf/hal.h> #include <cyg/hal/hal_arch.h> #include <cyg/hal/hal_cache.h> +#include <cyg/hal/hal_diag.h> #include CYGHWR_MEMORY_LAYOUT_H #define _FLASH_PRIVATE_ @@ -70,7 +71,8 @@ #define FLASH_Program FLASHWORD( 0xA0 ) #define FLASH_Sector_Erase FLASHWORD( 0x30 ) -#define FLASH_Busy FLASHWORD( 0x40 ) // "Toggle" bit +#define FLASH_Busy FLASHWORD( 0x40 ) // "Toggle" bit, I/O 6 +#define FLASH_InverseData FLASHWORD( 0x80 ) // I/O 7, Inverse data #define FLASH_Setup_Addr1 (0x5555) #define FLASH_Setup_Addr2 (0x2AAA) @@ -126,7 +128,7 @@ int flash_erase_block(void* block, unsi __attribute__ ((section (".2ram.flash_erase_block"))); int flash_program_buf(void* addr, void* data, int len) __attribute__ ((section (".2ram.flash_program_buf"))); -static int wait_while_busy(int timeout, volatile flash_data_t* addr_ptr) +static int wait_while_busy(int timeout, volatile flash_data_t* addr_ptr, flash_data_t value) __attribute__ ((section (".2ram.text"))); //---------------------------------------------------------------------------- @@ -237,21 +239,25 @@ flash_query(void* data) // FIXME: 10ms delay? } -// Wait for completion (bit 6 stops toggling) -static int wait_while_busy(int timeout, volatile flash_data_t* addr_ptr) +// Wait for completion. While programming/erasing check +// that i/o 7 is inverse of data as described in Atmels examples. + +static int wait_while_busy(int timeout, volatile flash_data_t* addr_ptr, flash_data_t expected) { - flash_data_t state, prev_state; - prev_state = *addr_ptr & FLASH_Busy; + int val; + flash_data_t state; while (true) { - state = *addr_ptr & FLASH_Busy; - if (prev_state == state) { - return FLASH_ERR_OK; + state = *addr_ptr & FLASH_InverseData; + if (state==(expected&FLASH_InverseData)) { + val=FLASH_ERR_OK; + break; } if (--timeout == 0) { - return FLASH_ERR_DRV_TIMEOUT; + val=FLASH_ERR_DRV_TIMEOUT; + break; } - prev_state = state; } + return val; } //---------------------------------------------------------------------------- @@ -303,16 +309,15 @@ flash_erase_block(void* block, unsigned ROM[FLASH_Setup_Addr2] = FLASH_Setup_Code2; *b_p = FLASH_Sector_Erase; - res = wait_while_busy(5000000,b_p); + size -= len; // This much has been erased - size -= len; // This much has been erased + res = wait_while_busy(66000000, b_p, FLASH_BlankValue); // Verify erase operation if (FLASH_ERR_OK == res) { while (len > 0) { if (*b_p != FLASH_BlankValue) { - // Only update return value if erase operation was OK - res = FLASH_ERR_DRV_VERIFY; + break; } len -= sizeof(*b_p); b_p++; @@ -354,7 +359,7 @@ flash_program_buf(void* addr, void* data ROM[FLASH_Setup_Addr1] = FLASH_Program; addr_ptr[0] = data_ptr[0]; - res = wait_while_busy(5000000,addr_ptr); + res = wait_while_busy(5000000,addr_ptr, data_ptr[0]); if (*addr_ptr++ != *data_ptr++) { // Only update return value if operation was OK
