📄 flashmem.c
字号:
/* write the data */
for (ix = 0; ix < (FLASH28_BUFFER_SIZE / FLASH_WIDTH); ix++)
{
if (pFB != NULL)
{
value = *pFB++;
}
*pFlash++ = value;
}
/* confirm the write */
*pFA = FLASH28_CMD_CONFIRM_WRITE;
while ((*pFA & FLASH28F008_STAT_WSMS) != FLASH28F008_STAT_WSMS);
/* Check Write Error Status */
if ( (*pFA & FLASH28_CMD_WSM_ERROR) != 0)
{
retVal = ERROR;
*pFA = FLASH28F008_CMD_CLEAR_STATUS;
*pFA = FLASH28_CMD_RESET;
}
nBytes -= FLASH28_BUFFER_SIZE;
adrs += FLASH28_BUFFER_SIZE;
}
*pFA = FLASH28_CMD_RESET;
if (nBytes > 0 && (retVal != ERROR))
{
#ifdef FLASH_DEBUG_PRINT
printf("sysSectorWrite: Rest %i bytes\n", nBytes);
#endif /* FLASH_DEBUG_PRINT */
}
/* adjust parameters value for writing the rest if required */
offset = adrs;
size = nBytes;
}
#endif /* INCLUDE_FLASH_WRITE_BUFFER */
for ( pFA = FLASH_CAST (FLASH_ADRS + offset);
(pFA <FLASH_CAST (FLASH_ADRS + size + offset)) &&
(retVal == OK);
pFA++)
{
if (pFB != NULL)
value = *pFB++;
*pFA = FLASH28_CMD_PROG_SETUP; /* write setup */
*pFA = value; /* data to write */
/* Check Write State Machine Status */
do
{
}
while ((*pFA & FLASH28F008_STAT_WSMS) != FLASH28F008_STAT_WSMS);
/* Check Byte Write Error Status */
if ((*pFA & FLASH28F008_STAT_BWS) != 0)
{
*pFA = FLASH28F008_CMD_CLEAR_STATUS;
retVal = ERROR;
}
*pFA = FLASH28_CMD_RESET;
}
SYS_FLASH_WRITE_DISABLE_RTN (); /* lower Vpp */
break;
case (FLASH_28F256):
case (FLASH_28F512):
case (FLASH_28F010):
case (FLASH_28F020):
{
SYS_FLASH_WRITE_ENABLE_RTN (); /* raise Vpp */
for (pFA = FLASH_CAST (FLASH_ADRS + offset); (pFA < FLASH_CAST
(FLASH_ADRS + size + offset)) && (retVal == OK); pFA++)
for (ix = 0; TRUE; ix++)
{
if (pFB != NULL)
value = *pFB++;
*pFA = FLASH28_CMD_PROG_SETUP; /* write setup */
*pFA = value; /* data to write */
sysFlashDelay (10); /* wait for write */
*pFA = FLASH28_CMD_PROG_VERIFY; /* verify command */
sysFlashDelay (6); /* wait for verify */
if (*pFA == value) /* done? */
break;
if (ix == 25) /* error? */
{
retVal = ERROR;
break;
}
}
pFA = FLASH_CAST (FLASH_ADRS);
*pFA = FLASH28_CMD_RESET;
*pFA = FLASH28_CMD_READ_MEM;
sysFlashDelay (6);
SYS_FLASH_WRITE_DISABLE_RTN (); /* lower Vpp */
break;
}
case (FLASH_29F010):
case (FLASH_29LV160T):
case (FLASH_29LV160B):
case (FLASH_29LV040B):
{
SYS_FLASH_WRITE_ENABLE_RTN (); /* enable write */
for (pFA = FLASH_CAST (FLASH_ADRS + offset); pFA < FLASH_CAST
(FLASH_ADRS + size + offset) && (retVal == OK); pFA++)
{
*(FLASH_CAST FLASH29_REG_FIRST_CYCLE) = FLASH29_CMD_FIRST;
*(FLASH_CAST FLASH29_REG_SECOND_CYCLE) = FLASH29_CMD_SECOND;
*(FLASH_CAST FLASH29_REG_FIRST_CYCLE) = FLASH29_CMD_PROGRAM;
if (pFB != NULL)
value = *pFB++;
*pFA = value; /* data to write */
do {
retVal = sysFlashDataPoll (pFA, (FLASH_DEF) value);
} while ((*pFA != value) && (retVal == OK));
}
*(FLASH_CAST FLASH29_REG_FIRST_CYCLE) = FLASH29_CMD_FIRST;
*(FLASH_CAST FLASH29_REG_SECOND_CYCLE) = FLASH29_CMD_SECOND;
*(FLASH_CAST FLASH29_REG_FIRST_CYCLE) = FLASH29_CMD_READ_RESET;
SYS_FLASH_WRITE_DISABLE_RTN (); /* disable write */
break;
}
case (FLASH_29C040A):
sectorSize = 256;
twc = 1;
/* FALL THROUGH */
case (FLASH_29LV1024):
{
for (pFA = FLASH_CAST (FLASH_ADRS + offset);
pFA < FLASH_CAST (FLASH_ADRS + size + offset); )
{
/* Enable sector write */
*(FLASH_CAST FLASH29_REG_FIRST_CYCLE) = FLASH29_CMD_FIRST;
*(FLASH_CAST FLASH29_REG_SECOND_CYCLE) = FLASH29_CMD_SECOND;
*(FLASH_CAST FLASH29_REG_FIRST_CYCLE) = FLASH29_CMD_PROGRAM;
/*
* write the sector:
* 29LV1024: 128 half-word accesses = 256 bytes
* 29C040A 256 byte accesses
*/
for (ix = 0; ix < sectorSize; ix++)
{
if (pFB != NULL)
value = *pFB++;
/* ensure entire sector written */
if (pFA >= FLASH_CAST (FLASH_ADRS + size + offset))
value = (FLASH_DEF) 0xFFFFFFFF;
*pFA++ = value; /* data to write */
}
/*
* Ensure write cycle completes. Atmel chip spec suggest
* waiting for a specified time rather than polling for
* completion.
*
* It seems that we cannot always safely use taskDelay()
*/
sysFlashDelay (10000 * twc);
}
break;
}
default:
retVal = ERROR;
}
return (retVal);
}
/******************************************************************************
*
* sysFlashTypeGet - determine the device type of on-board flash memory
*
* This routine uses the `autoselect' command to determine the device type of
* on-board flash memory for flash 29F\f2xxx\f1 devices.
*
* RETURNS: An integer indicating the device type of on-board flash memory.
*/
UINT8 sysFlashTypeGet (void)
{
volatile FLASH_DEF * pFA = FLASH_CAST (FLASH_ADRS); /* flash address */
UINT8 retVal;
SYS_FLASH_WRITE_ENABLE_RTN (); /* enable writes */
*(FLASH_CAST FLASH29_REG_FIRST_CYCLE) = FLASH29_CMD_FIRST;
*(FLASH_CAST FLASH29_REG_SECOND_CYCLE) = FLASH29_CMD_SECOND;
*(FLASH_CAST FLASH29_REG_FIRST_CYCLE) = FLASH29_CMD_AUTOSELECT;
/* 29LV1024 (at least) requires 20ms delay */
/* It seems we cannot always safely use taskDelay() */
sysFlashDelay (20000);
retVal = (UINT8) *++pFA;
*(FLASH_CAST FLASH29_REG_FIRST_CYCLE) = FLASH29_CMD_FIRST;
*(FLASH_CAST FLASH29_REG_SECOND_CYCLE) = FLASH29_CMD_SECOND;
*(FLASH_CAST FLASH29_REG_FIRST_CYCLE) = FLASH29_CMD_READ_RESET;
sysFlashDelay (20000);
SYS_FLASH_WRITE_DISABLE_RTN (); /* disable writes */
return (retVal);
}
/******************************************************************************
*
* sysFlashSet - write to flash memory
*
* This routine copies a specified string into flash memory after calling
* sysFlashErase() and clearing flash memory.
*
*
* RETURNS: OK, or ERROR if the write fails or the input parameters are
* out of range.
*
* SEE ALSO: sysFlashErase(), sysFlashGet(), sysFlashTypeGet(), sysFlashWrite()
*
* INTERNAL
* If multiple tasks are calling sysFlashSet() and sysFlashGet(),
* they should use a semaphore to ensure mutually exclusive access to flash
* memory.
*/
STATUS sysFlashSet
(
char * string, /* string to be copied into flash memory */
int strLen, /* maximum number of bytes to copy */
int offset /* byte offset into flash memory */
)
{
static UINT8 flashType = FLASH_MEM_TYPE;
char *tempBuffer;
if ( (offset < 0) || (strLen < 0) ||
((offset + strLen) > FLASH_SIZE) || ( (offset - FLASH_SECTOR(offset) + strLen) > FLASH_SECTOR_SIZE ) )
{
#ifdef FLASH_DEBUG
logMsg("sysFlashSet : ERROR strLen = %d, offset = %d\n",strLen,offset,3,4,5,6);
#endif /* FLASH_DEBUG */
return(ERROR);
}
/* see if contents are actually changing */
if (bcmp ((char *) (FLASH_ADRS + offset), string, strLen) == 0)
return(OK);
if (tempBuffer = malloc(FLASH_SECTOR_SIZE), tempBuffer == 0)
return(ERROR);
bcopyBytes ((char *) FLASH_ADRS + FLASH_SECTOR(offset), tempBuffer, FLASH_SECTOR_SIZE);
bcopyBytes (string, (tempBuffer + offset - FLASH_SECTOR(offset)), strLen);
if (flashType == 0)
flashType = sysFlashTypeGet ();
switch (flashType)
{
case (FLASH_28F640J3A):
case (FLASH_28F320J3A):
case (FLASH_28F128J3A):
/* erase the sector */
if (sysSectorErase (FLASH_CAST (FLASH_ADRS + offset), flashType) == ERROR)
{
free (tempBuffer);
return(ERROR);
}
break;
case FLASH_29C040A:
case FLASH_29LV1024:
/* do not erase these as not required */
break;
case (FLASH_29LV160T):
case (FLASH_29LV160B):
case (FLASH_29LV040B):
/* erase the sector */
if (sysSectorErase (FLASH_CAST (FLASH_ADRS + offset), flashType) == ERROR)
{
free (tempBuffer);
return(ERROR);
}
break;
default:
if (sysFlashErase (flashType) == ERROR) /* erase device */
{
free (tempBuffer);
return(ERROR);
}
break;
} /* endswitch */
if (sysFlashWrite (FLASH_CAST (tempBuffer), FLASH_SECTOR_SIZE, FLASH_SECTOR(offset), flashType, 0) == ERROR)
{
#ifdef FLASH_DEBUG
logMsg("sysFlashSet : write ERROR FLASH_CAST (string) = 0x%x, strLen = %d, offset = %d, flashType = %d\n",
FLASH_CAST (string),strLen,offset,flashType,5,6);
#endif /* FLASH_DEBUG */
return(ERROR);
}
return(OK);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -