This is the mail archive of the
ecos-patches@sourceware.org
mailing list for the eCos project.
Re: flash/am29xxxxx flash_program_buf length fix
>>>>> "Andrew" == Andrew Lunn <andrew@lunn.ch> writes:
Hi,
Andrew> Special case the last bytes in the driver. You need to build
Andrew> a word with 0xff for the bytes you don't want to modify when
Andrew> do a write to flash for the word. The bits set to 1 won't
Andrew> change and the bits you do want to change will change.
The following patch does just that.
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 <jacmet@sunsite.dk>
+
+ * include/flash_am29xxxxx.inl (flash_program_buf): Handle writes
+ with length not a multiple of flash word size.
+
2005-04-17 David Vrabel <dvrabel@arcom.com>
* 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;
--
Bye, Peter Korsgaard