# HG changeset patch # User jlarmour # Date 1085640211 0 # Node ID 79f7073a7a007ce1ccaa63f38e4b8993235808ec # Parent 55f30b7a6e966b888d7f1d4ea824925261cd2182 * cdl/flash_atmel_at49xxxx.cdl: * include/flash_at49xxxx.inl: Added workaround for Atmel AT91FR40162 erase bug. diff --git a/packages/devs/flash/atmel/at49xxxx/current/ChangeLog b/packages/devs/flash/atmel/at49xxxx/current/ChangeLog --- a/packages/devs/flash/atmel/at49xxxx/current/ChangeLog +++ b/packages/devs/flash/atmel/at49xxxx/current/ChangeLog @@ -1,3 +1,9 @@ +2004-05-11 Thomas Koeller + + * cdl/flash_atmel_at49xxxx.cdl: + * include/flash_at49xxxx.inl: Added workaround for Atmel + AT91FR40162 erase bug. + 2003-11-10 Gary Thomas * include/flash_at49xxxx_parts.inl: Add AT29LV200BB diff --git a/packages/devs/flash/atmel/at49xxxx/current/cdl/flash_atmel_at49xxxx.cdl b/packages/devs/flash/atmel/at49xxxx/current/cdl/flash_atmel_at49xxxx.cdl --- a/packages/devs/flash/atmel/at49xxxx/current/cdl/flash_atmel_at49xxxx.cdl +++ b/packages/devs/flash/atmel/at49xxxx/current/cdl/flash_atmel_at49xxxx.cdl @@ -59,6 +59,18 @@ cdl_package CYGPKG_DEVS_FLASH_ATMEL_AT49 implements CYGHWR_IO_FLASH_DEVICE include_dir cyg/io + + cdl_option CYGHWR_DEVS_FLASH_ATMEL_AT49XXXX_ERASE_BUG_WORKAROUND { + display "AT91FR40162 erase bug workaround" + flavor bool + default_value 0 + description " + The flash chips used in Atmel AT91FR40162 microcontrollers have a silicon bug + that causes erase operations to be unreliable unless any data to be erased is + cleared first, see http://www.atmel.com/dyn/resources/prod_documents/doc6076.pdf. + Selecting this option enables that workaround. Of course, erase operations will be + slower then." + } } # EOF flash_atmel_49xxxx.cdl diff --git a/packages/devs/flash/atmel/at49xxxx/current/include/flash_at49xxxx.inl b/packages/devs/flash/atmel/at49xxxx/current/include/flash_at49xxxx.inl --- a/packages/devs/flash/atmel/at49xxxx/current/include/flash_at49xxxx.inl +++ b/packages/devs/flash/atmel/at49xxxx/current/include/flash_at49xxxx.inl @@ -56,6 +56,7 @@ //========================================================================== #include +#include #include #include #include @@ -272,7 +273,7 @@ flash_erase_block(void* block, unsigned volatile flash_data_t* b_p = (volatile flash_data_t*) block; int res = FLASH_ERR_OK; - int len = 0; + unsigned int len = 0; cyg_bool bootblock = false; cyg_uint32 *bootblocks = (cyg_uint32 *)0; @@ -282,6 +283,32 @@ flash_erase_block(void* block, unsigned ROM = (volatile flash_data_t*) ((unsigned long)block & flash_dev_info->base_mask); +#if defined(CYGHWR_DEVS_FLASH_ATMEL_AT49XXXX_ERASE_BUG_WORKAROUND) + + // Before erasing the data, overwrite it with all zeroes. This is a workaround + // for a silicon bug that affects erasing of some devices, see + // http://www.atmel.com/dyn/resources/prod_documents/doc6076.pdf. + for (len = size / sizeof *b_p; (FLASH_ERR_OK == res) && (len > 0); len--, b_p++) { + // Program data [byte] - 4 step sequence + ROM[FLASH_Setup_Addr1] = FLASH_Setup_Code1; + ROM[FLASH_Setup_Addr2] = FLASH_Setup_Code2; + ROM[FLASH_Setup_Addr1] = FLASH_Program; + *b_p = 0; + + res = wait_while_busy(5000000, b_p, 0); + + if (*b_p != 0) + // Only update return value if operation was OK + if (FLASH_ERR_OK == res) res = FLASH_ERR_DRV_VERIFY; + } + + if (FLASH_ERR_OK != res) + return res; + + b_p = (volatile flash_data_t*) block; + +#endif // defined(CYGHWR_DEVS_FLASH_ATMEL_AT49XXXX_ERASE_BUG_WORKAROUND) + // Assume not "boot" sector, full size bootblock = false; len = flash_dev_info->block_size;