#define _16AS8 CYGNUM_FLASH_16AS8
#endif
-#if (_16AS8 == 0)
+
+# if (_16AS8 == 0)||CYGHWR_DEVS_FLASH_ST_M29W320D
# define FLASH_Setup_Addr1 (0x555)
# define FLASH_Setup_Addr2 (0x2AA)
# define FLASH_VendorID_Addr (0)
# define FLASH_DeviceID_Addr3 (0x1e)
# define FLASH_WP_Addr (4)
#endif
+
#define FLASH_Setup_Code1 FLASHWORD( 0xAA )
#define FLASH_Setup_Code2 FLASHWORD( 0x55 )
#define FLASH_Setup_Erase FLASHWORD( 0x80 )
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))
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) {
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 write 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;
if (flash_dev_info->bootblock) {
cyg_uint32 * bootblocks = flash_dev_info->bootblocks;
while (*bootblocks != _LAST_BOOTBLOCK) {
- int ls = flash_dev_info->block_size;
-
- if (*bootblocks++ == (res - base)) {
- while (res + *bootblocks < a) {
+ if (*bootblocks++ == (res - base)) { /* Matching offset marker */
+ while (res + *bootblocks <= a) {
res += *bootblocks++;
}
+ *remain_size = *bootblocks - (a - res);
+ break;
} else {
+ int ls = flash_dev_info->block_size;
// Skip over segment
while ((ls -= *bootblocks++) > 0) ;
}
}
-
- if (*bootblocks != _LAST_BOOTBLOCK)
- *remain_size = *bootblocks - (a - res);
}
return (flash_data_t *) res;
}
-#endif // CYGONCE_DEVS_FLASH_AMD_AM29XXXXX_INL
+#endif // CYGONCE_DEVS_FLASH_AMD_AM29XXXXX_INL
\ No newline at end of file