Index: packages/devs/flash/amd/am29xxxxx/current/ChangeLog =================================================================== RCS file: /cvs/ecos/ecos/packages/devs/flash/amd/am29xxxxx/current/ChangeLog,v retrieving revision 1.35 diff -u -r1.35 ChangeLog --- packages/devs/flash/amd/am29xxxxx/current/ChangeLog 12 Jun 2005 13:41:11 -0000 1.35 +++ packages/devs/flash/amd/am29xxxxx/current/ChangeLog 8 Sep 2005 08:12:22 -0000 @@ -1,3 +1,8 @@ +2005-09-08 Peter Korsgaard + + * include/flash_am29xxxxx.inl (flash_program_buf): Handle writes + with length not a multiple of flash word size. + 2005-04-17 David Vrabel * include/flash_am29xxxxx_parts.inl [CYGHWR_DEVS_FLASH_AMD_AM29F002T]: Index: packages/devs/flash/amd/am29xxxxx/current/include/flash_am29xxxxx.inl =================================================================== RCS file: /cvs/ecos/ecos/packages/devs/flash/amd/am29xxxxx/current/include/flash_am29xxxxx.inl,v retrieving revision 1.22 diff -u -r1.22 flash_am29xxxxx.inl --- packages/devs/flash/amd/am29xxxxx/current/include/flash_am29xxxxx.inl 23 Apr 2004 20:50:32 -0000 1.22 +++ packages/devs/flash/amd/am29xxxxx/current/include/flash_am29xxxxx.inl 8 Sep 2005 08:12:22 -0000 @@ -442,6 +442,7 @@ const CYG_ADDRWORD mask = flash_dev_info->bufsiz * sizeof (flash_data_t) - 1; unsigned long rem_sect_size; + int remain; // check the address is suitably aligned if ((unsigned long)addr & (CYGNUM_FLASH_INTERLEAVE * CYGNUM_FLASH_WIDTH / 8 - 1)) @@ -454,6 +455,7 @@ f_s1 = FLASH_P2V(BANK + FLASH_Setup_Addr1); f_s2 = FLASH_P2V(BANK + FLASH_Setup_Addr2); rem_sect_size = 0; + remain = len % sizeof (flash_data_t); len /= sizeof (flash_data_t); while (len > 0) { @@ -527,6 +529,51 @@ len -= nwords; } + // Program remaining bytes if len not a multiple of flash word size + if ((FLASH_ERR_OK == res) && remain) + { + // construct final word to be programmed with 0xff in the + // remaining bytes + flash_data_t final = (flash_data_t)-1; + unsigned char *src = (unsigned char*)data_ptr; + unsigned char *dst = (unsigned char*)&final; + + while (remain--) + *dst++ = *src++; + + addr_v = FLASH_P2V(addr_p); + + // Program data [byte] - 4 step sequence + *f_s1 = FLASH_Setup_Code1; + *f_s2 = FLASH_Setup_Code2; + *f_s1 = FLASH_Program; + *addr_v = final; + + timeout = CYGNUM_FLASH_TIMEOUT_PROGRAM; + while (true) { + flash_data_t state = *addr_v; + if (final == state) { + break; + } + + // Can't check for FLASH_Err since it'll fail in parallel + // configurations. + + if (--timeout == 0) { + res = FLASH_ERR_DRV_TIMEOUT; + break; + } + } + + if (FLASH_ERR_OK != res) + *FLASH_P2V(ROM) = FLASH_Reset; + + if (*addr_v != final) { + // Only update return value if erase operation was OK + if (FLASH_ERR_OK == res) res = FLASH_ERR_DRV_VERIFY; + } + } + // Ideally, we'd want to return not only the failure code, but also // the address/device that reported the error. return res;