This is the mail archive of the ecos-patches@sourceware.org mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]