📄 29f800a.c
字号:
*
* Return Value: The function returns FLASH_SUCCESS if the Program/Erase Controller
* is successful or FLASH_TOGGLE_FAIL if there is a problem.
*******************************************************************************/
static int FlashDataToggle( DWORD iTimeOut_mS )
{
BYTE w1, w2; /* hold values read from any address offset within the Flash Memory */
DWORD msStart_Time, msCurrent_Time;
// msStart_Time = GetTimerTick();
while( 1 ) /* TimeOut!: If, for some reason, the hardware fails then this
loop may not exit. Use a timer function to implement a timeout
from the loop. */
{
/* Step 1: Read DQ6 (into a word) */
w1 = (BYTE)FlashRead( ANY_ADDR ); /* Read DQ6 from the Flash (any address) */
/* Step 2: Read DQ5 and DQ6 (into another word) */
w2 = (BYTE)FlashRead( ANY_ADDR ); /* Read DQ5 and DQ6 from the Flash (any
address) */
/* Step 3: If DQ6 did not toggle between the two reads then return
FLASH_SUCCESS */
if( (w1&0x40) == (w2&0x40) ) /* DQ6 == NO Toggle */
return FLASH_SUCCESS;
/* Step 4: Else if DQ5 is zero then operation is not yet complete */
if( (w2&0x20) == 0x00 )
{
// msCurrent_Time = GetTimerTick();
/* if ((msCurrent_Time - msStart_Time) > iTimeOut_mS)
{
UPPRINTF("return FLASH_SYSTEM_TIMEOUT\r\n");
return FLASH_SYSTEM_TIMEOUT;
}
*/
continue; //go back to while directly
}
/* Step 5: Else (DQ5 == 1), read DQ6 again */
w1 = (BYTE)FlashRead( ANY_ADDR ); /* Read DQ6 from the Flash (any address) */
w2 = (BYTE)FlashRead( ANY_ADDR ); /* Read DQ6 from the Flash (any address) */
/* Step 6: If DQ6 did not toggle between the last two reads then
return FLASH_SUCCESS */
if( (w2&0x40) == (w1&0x40) ) /* DQ6 == NO Toggle */
{
UPPRINTF("return FLASH_SUCCESS\r\n");
return FLASH_SUCCESS;
}
/* Step 7: Else return FLASH_TOGGLE_FAIL */
else /* DQ6 == Toggle here means fail */
{
UPPRINTF("return FLASH_TOGGLE_FAIL\r\n");
return FLASH_TOGGLE_FAIL;
}
} /* end of while loop */
}
#if 0
/*******************************************************************************
* Function: static int FlashDataPoll( DWORD dwOff, void *Val, DWORD iTimeOut_mS )
*
* Description: The function is used to monitor the Program/Erase Controller during
* erase or program operations. It returns when the Program/Erase Controller has
* completed.
* Note: this library does not use the Data Polling Flow Chart to assess the
* correct operation of Program/Erase Controller, but uses the Data Toggle Flow
* Chart instead. The FlashDataPoll() function is only provided here as an
* illustration of the Data Polling Flow Chart in the Data Sheet.
* The code uses the function FlashDataToggle() instead.
* Pseudo Code:
* Step 1: Read DQ5 and DQ7 (into a word)
* Step 2: If DQ7 is the same as wVal(bit 7) then return FLASH_SUCCESS
* Step 3: Else if DQ5 is "0" then operation is not yet complete, goto 1
* Step 4: Else (DQ5 is "1"), time-out, Read DQ7
* Step 5: If DQ7 is now the same as wVal(bit 7) then return FLASH_SUCCESS
* Step 6: Else return FLASH_POLL_FAIL
*
* Arguments: dwOff should hold a valid offset to be polled. For programming
* this will be the offset of the word being programmed. For erasing this can
* be any offset in the block(s) being erased.
* *Val should hold the value being programmed. A value of FFh(x8)/FFFFh(x16) should
* be used when erasing.
* iTimeOut_mS is the system time out limit.
*
* Return Value: The function returns FLASH_SUCCESS if the Program/Erase Controller
* is successful or FLASH_POLL_FAIL if there is a problem.
*******************************************************************************/
static int FlashDataPoll( DWORD dwOff, void *Val, DWORD iTimeOut_mS )
{
#if (_FLASH_TYPE_ == FLASH_x8x16_16BIT_BUS)
WORD w, oriVal = (WORD *)Val; /* holds value read from valid address */
#else if (_FLASH_TYPE_ == FLASH_x8x16_8BIT_BUS)||(_FLASH_TYPE_ == FLASH_x8_8BIT_BUS)
BYTE w, oriVal = (BYTE *)Val; /* holds value read from valid address */
#endif
DWORD msStart_Time, msCurrent_Time;
msStart_Time = GetTimerTick();
while( 1 ) /* TimeOut!: If, for some reason, the hardware fails then this
loop may not exit. Use a timer function to implement a timeout
from the loop. */
{
/* Step 1: Read DQ5 and DQ7 (into a word) */
w = FlashRead( dwOff ); /* Read DQ5, DQ7 at valid addr */
/* Step 2: If DQ7 is the same as wVal(bit 7) then return FLASH_SUCCESS */
#if (_FLASH_TYPE_ == FLASH_x8x16_16BIT_BUS)
if( (w&0x0080) == (oriVal & 0x0080) ) /* DQ7 == DATA */
#else if (_FLASH_TYPE_ == FLASH_x8x16_8BIT_BUS)||(_FLASH_TYPE_ == FLASH_x8_8BIT_BUS)
if( (w&0x80) == (oriVal & 0x80) ) /* DQ7 == DATA */
#endif
{
return FLASH_SUCCESS;
}
/* Step 3: Else if DQ5 is zero then operation is not yet complete */
if( (w&0x20) == 0x00 )
{
msCurrent_Time = GetTimerTick();
if ((msCurrent_Time - msStart_Time) > iTimeOut_mS)
return FLASH_SYSTEM_TIMEOUT;
continue; //go back to while directly
}
/* Step 4: Else (DQ5 == 1) */
w = FlashRead( dwOff ); /* Read DQ7 at valid addr */
/* Step 5: If DQ7 is now the same as wVal(bit 7) then
return FLASH_SUCCESS */
#if (_FLASH_TYPE_ == FLASH_x8x16_16BIT_BUS)
if( (w&0x0080) == (oriVal & 0x0080) ) /* DQ7 == DATA */
#else if (_FLASH_TYPE_ == FLASH_x8x16_8BIT_BUS)||(_FLASH_TYPE_ == FLASH_x8_8BIT_BUS)
if( (w&0x80) == (oriVal & 0x80) ) /* DQ7 == DATA */
#endif
{
return FLASH_SUCCESS;
}
/* Step 6: Else return FLASH_POLL_FAIL */
else /* DQ7 != DATA here means fail */
return FLASH_POLL_FAIL;
} /* end of while loop */
}
#endif
#if 0
/*******************************************************************************
* Function: int FlashBlockErase( BYTE bBlockNum )
*
* Description: This function erases the block "bBlockNum" in the flash. The function
* does not return until the block is erased.
* During the Erase Cycle the Data Toggle Flow Chart of the Data Sheet is
* followed. The polling bit, DQ7, is not used.
* Pseudo Code:
* Step 2: Check for protected or invalid blocks
* Step 3: Write Block Erase command
* Step 6: Follow Data Toggle Flow Chart until Program/Erase Controller has
* completed
* Step 7: Return to Read mode (if an error occurred)
*
* Arguments: bNumBlocks holds the number of blocks in the array bBlock
* bBlock is an array containing the blocks to be erased.
*
* Return Value: The function returns the following conditions:
* FLASH_SUCCESS (-1)
* FLASH_TOO_MANY_BLOCKS (-3)
* FLASH_ERASE_FAIL (-14)
*******************************************************************************/
int FlashBlockErase( BYTE bBlockNum )
{
int iRetVal = FLASH_SUCCESS; /* Holds return value: optimistic initially! */
/* Step 2: Check for protected or invalid blocks. */
if( bBlockNum >= NUM_BLOCKS ) /* Check specified blocks < NUM_BLOCKS */
return FLASH_TOO_MANY_BLOCKS;
/* Step 3: Write Block Erase command */
#if (_FLASH_TYPE_ == FLASH_x8x16_16BIT_BUS)||(_FLASH_TYPE_ == FLASH_x8_8BIT_BUS)
FlashWrite( 0x5555L, 0x00AA );
FlashWrite( 0x2AAAL, 0x0055 );
FlashWrite( 0x5555L, 0x0080 );
FlashWrite( 0x5555L, 0x00AA );
FlashWrite( 0x2AAAL, 0x0055 );
FlashWrite( BlockOffset[bBlockNum], 0x0030 );
#else if (_FLASH_TYPE_ == FLASH_x8x16_8BIT_BUS)
FlashWrite( 0xAAAAL, 0xAA );
FlashWrite( 0x5555L, 0x55 );
FlashWrite( 0xAAAAL, 0x80 );
FlashWrite( 0xAAAAL, 0xAA );
FlashWrite( 0x5555L, 0x55 );
FlashWrite( BlockOffset[bBlockNum], 0x30 );
#endif
/* Step 6: Follow Data Toggle Flow Chart until Program/Erase Controller
completes */
if( FlashDataToggle(60000) != FLASH_SUCCESS )//system out limit is 60s
{
iRetVal = FLASH_ERASE_FAIL;
/* Step 7: Return to Read mode (if an error occurred) */
FlashReadReset();
}
return iRetVal;
}
#endif
/*******************************************************************************
* Function: int FlashChipErase( void )
*
* Description: The function can be used to erase the whole flash chip so long as
* no blocks are protected. If any blocks are protected then nothing is
* erased.
* Pseudo Code:
* Step 3: Send Chip Erase Command
* Step 4: Follow Data Toggle Flow Chart until Program/Erase Controller has
* completed.
* Step 6: Return to Read mode (if an error occurred)
*
* Arguments:
*
* Return Value: On success the function returns FLASH_SUCCESS (-1)
* If the erase algorithms fails then the function returns FLASH_ERASE_FAIL (-2)
*******************************************************************************/
int FlashChipErase( void )
{
int iRetVal = FLASH_SUCCESS; /* Holds return value: optimistic initially! */
int i;
UPPRINTF("FlashReadReset begin\r\n");
/* Step 3: Send Chip Erase Command */
#if (_FLASH_TYPE_ == FLASH_x8x16_16BIT_BUS)||(_FLASH_TYPE_ == FLASH_x8_8BIT_BUS)
FlashWrite( 0x5555L, 0x00AA );
FlashWrite( 0x2AAAL, 0x0055 );
FlashWrite( 0x5555L, 0x0080 );
FlashWrite( 0x5555L, 0x00AA );
FlashWrite( 0x2AAAL, 0x0055 );
FlashWrite( 0x5555L, 0x0010 );
#else if (_FLASH_TYPE_ == FLASH_x8x16_8BIT_BUS)
FlashWrite( 0xAAAAL, 0xAA );
FlashWrite( 0x5555L, 0x55 );
FlashWrite( 0xAAAAL, 0x80 );
FlashWrite( 0xAAAAL, 0xAA );
FlashWrite( 0x5555L, 0x55 );
FlashWrite( 0xAAAAL, 0x10 );
#endif
UPPRINTF("FlashReadReset call FlashPause\r\n");
FlashPause( 100 );//?need?
/* Step 4: Follow Data Toggle Flow Chart until Program/Erase Controller has
completed */
UPPRINTF("FlashReadReset call FlashDataToggle\r\n");
if( FlashDataToggle(6000000) != FLASH_SUCCESS )//system out limit is 60s
{
iRetVal = FLASH_ERASE_FAIL;
/* Step 6: Return to Read mode (if an error occurred) */
FlashReadReset();
}
FlashPause( 100 );//?need?
UPPRINTF("FlashReadReset return\r\n");
return iRetVal;
}
/*******************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -