Index: ChangeLog =================================================================== RCS file: /cvs/ecos/ecos/packages/devs/flash/atmel/at49xxxx/current/ChangeLog,v retrieving revision 1.3 diff -u -r1.3 ChangeLog --- ChangeLog 15 Jul 2003 01:52:21 -0000 1.3 +++ ChangeLog 5 Aug 2003 08:40:08 -0000 @@ -1,3 +1,9 @@ +2003-08-05 Øyvind Harboe + + * There is something fishy going on with the wait_while_busy(). + This has not been fully resolved or understood to my satisfaction, + but these are the workarounds I'm using in the meantime on my system. + 2003-07-15 Jonathan Larmour * include/flash_at49xxxx.inl: Reorganise to support boot blocks, Index: include/flash_at49xxxx.inl =================================================================== RCS file: /cvs/ecos/ecos/packages/devs/flash/atmel/at49xxxx/current/include/flash_at49xxxx.inl,v retrieving revision 1.3 diff -u -r1.3 flash_at49xxxx.inl --- include/flash_at49xxxx.inl 15 Jul 2003 01:52:22 -0000 1.3 +++ include/flash_at49xxxx.inl 5 Aug 2003 08:40:08 -0000 @@ -57,6 +57,7 @@ #include #include #include +#include #include CYGHWR_MEMORY_LAYOUT_H #define _FLASH_PRIVATE_ @@ -128,6 +129,8 @@ __attribute__ ((section (".2ram.flash_program_buf"))); static int wait_while_busy(int timeout, volatile flash_data_t* addr_ptr) __attribute__ ((section (".2ram.text"))); +static int wait_while_busy_erase(int timeout, volatile flash_data_t* addr_ptr) + __attribute__ ((section (".2ram.text"))); //---------------------------------------------------------------------------- // Initialize driver details @@ -240,20 +243,50 @@ // Wait for completion (bit 6 stops toggling) static int wait_while_busy(int timeout, volatile flash_data_t* addr_ptr) { + int val; + + HAL_DELAY_US(1); + flash_data_t state, prev_state; prev_state = *addr_ptr & FLASH_Busy; + while (true) { + HAL_DELAY_US(1); state = *addr_ptr & FLASH_Busy; if (prev_state == state) { - return FLASH_ERR_OK; + val=FLASH_ERR_OK; + break; } if (--timeout == 0) { - return FLASH_ERR_DRV_TIMEOUT; + val=FLASH_ERR_DRV_TIMEOUT; + break; } prev_state = state; } + return val; } +// In the erase mode, we can't rely on the toggle mode. +static int wait_while_busy_erase(int timeout, volatile flash_data_t* addr_ptr) +{ + int val=FLASH_ERR_DRV_TIMEOUT; + flash_data_t state; + + while (true) { + state=*addr_ptr; + if (state==0xffff) { + val=FLASH_ERR_OK; + break; + } + if (--timeout == 0) { + break; + } + } + return val; +} + + + //---------------------------------------------------------------------------- // Erase Block int @@ -303,16 +336,17 @@ 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 + // Verify erase operation if (FLASH_ERR_OK == res) { while (len > 0) { + + res = wait_while_busy_erase(66000000,b_p); + 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++;