/***********************************************************************
Internal routine to copy data to Flash Memory. It is assumed that the
destination area has been erased, and that bytes is an even number.
Returns non-zero on success; zero is returned on error and fm_err contains
failure data. FMInfo and pBase are assumed initialized.
* * * NOTE: This routine has been hand optimized for performance. * * *
***********************************************************************/
#define W_FS_ITER 350 /* number of fail-safe loop iterations per msec */
/** Re-measure this constant if the fail-safe loop is changed! **/
static fm_cpy(pDst, pSrc, bytes)
register volatile unsigned short *pDst; /* where in Flash to copy data to */
register unsigned short *pSrc; /* where to copy data from */
register size_t bytes; /* # bytes to copy -- must be even */
{
register volatile unsigned short *ptr1; /* fast FM_ADDR1 ptr */
register volatile unsigned short *ptr2; /* fast FM_ADDR2 ptr */
register unsigned short fmd1, fmd2; /* fast FM_DATA values */
register unsigned short val; /* value read in verify loop */
register unsigned short fail_safe; /* safety counter */
/* put these in registers for speed: */
ptr1 = pBase + FM_ADDR1;
ptr2 = pBase + FM_ADDR2;
fmd1 = FM_DATA1;
fmd2 = FM_DATA2;
/* loop writing and verifying a word at a time: */
while (bytes)
{
/* this duplicates a call to fm_cmd(), for speed: */
*ptr1 = fmd1;
*ptr2 = fmd2;
*ptr1 = FMCMD_WRITE;
/* write two bytes: */
*pDst = *pSrc;
/* do this here - a bit of parallel processing: */
bytes -= 2;
val = *pSrc;
/* loop checking for write completion: */
for (fail_safe = FMInfo.MaxWrite_ * W_FS_ITER; --fail_safe; )
if (*pDst == val)
break; /* done! */
/* if loop was exhausted, go handle the error: */
if (fail_safe == 0)
{ fm_tofs_error(pDst, val, *pDst, 4);
return 0;
}
/* move to the next location and loop back: */
++pSrc;
++pDst;
}
/* return happy: */
return 1;
}
/* End of File */