?? c2374.c
字號:
*******************************************************************************/
ReturnType FlashCheckBlockProtection( uBlockType ublBlockNr ) {
ReturnType rRetVal; /* Holds the return value */
uCPUBusType ucProtStatus; /* Holds the protection status */
/* Step 1: Check that the block number exists */
if ( ublBlockNr >= NUM_BLOCKS )
return Flash_BlockNrInvalid;
/* Step 2: Send the AutoSelect command */
FlashWrite( ConvAddr(0x00555), (uCPUBusType)CMD(0x00AA) ); /* 1st Cycle */
FlashWrite( ConvAddr(0x002AA), (uCPUBusType)CMD(0x0055) ); /* 2nd Cycle */
FlashWrite( ConvAddr(0x00555), (uCPUBusType)CMD(0x0090) ); /* 3rd Cycle */
/* Step 3: Read Protection Status */
ucProtStatus=FlashRead( BlockOffset[ublBlockNr] + ShAddr(0x02));
if ( (ucProtStatus & CMD(0x00ff)) == 0)
rRetVal = Flash_BlockUnprotected;
else if ( (ucProtStatus & CMD(0x00ff)) == CMD(0x0001) )
rRetVal = Flash_BlockProtected;
else
rRetVal = Flash_BlockProtectionUnclear;
/* Step 4: Return to Read mode */
FlashWrite( ANY_ADDR, (uCPUBusType)CMD(0x00F0) ); /* Use single instruction cycle method */
return rRetVal;
} /* EndFunction FlashCheckBlockProtection */
/*******************************************************************************
Function: ReturnType FlashCheckCompatibility( void )
Arguments: None
Return Values: The function returns the following conditions:
Flash_Success
Flash_WrongType
Description: This function checks the compatibility of the device with
the SW driver.
Pseudo Code:
Step 1: Read the Device Id
Step 2: Read the Manufacturer Code
Step 3: Check the results
*******************************************************************************/
ReturnType FlashCheckCompatibility( void ) {
ReturnType rRetVal, rCheck1, rCheck2; /* Holds the results of the Read operations */
uCPUBusType ucDeviceId, ucManufacturerCode; /* Holds the values read */
rRetVal = Flash_WrongType;
/* Step 1: Read the Device Id */
rCheck1 = FlashReadDeviceId( &ucDeviceId );
/* Step 2: Read the ManufactureCode */
rCheck2 = FlashReadManufacturerCode( &ucManufacturerCode );
/* Step 3: Check the results */
if ( (rCheck1 == Flash_Success) && (rCheck2 == Flash_Success)
&& (ucDeviceId == EXPECTED_DEVICE) && (ucManufacturerCode == MANUFACTURER_ST) )
rRetVal = Flash_Success;
return rRetVal;
} /* EndFunction FlashCheckCompatibility */
/*******************************************************************************
Function: ReturnType FlashCheckBlockEraseError( uBlockType ublBlock )
Arguments: ublBlock specifies the block to be checked
Return Value:
Flash_Success
FlashBlockEraseFailed
Description: This function can only be called after an erase operation which
has failed the FlashDataPoll() function. It must be called before the reset
is made. The function reads bit 2 of the Status Register to check if the block
has erased successfully or not. Successfully erased blocks should have DQ2
set to 1 following the erase. Failed blocks will have DQ2 toggle.
Pseudo Code:
Step 1: Read DQ2 in the block twice
Step 2: If they are both the same then return Flash_Success
Step 3: Else return Flash_BlockEraseFailed
*******************************************************************************/
static ReturnType FlashCheckBlockEraseError( uBlockType ublBlock ){
uCPUBusType ucFirstRead, ucSecondRead; /* Two variables used for clarity*/
/* Step 1: Read DQ2 in the block twice */
ucFirstRead = FlashRead( BlockOffset[ublBlock] ) & CMD(0x0004);
ucSecondRead = FlashRead( BlockOffset[ublBlock] ) & CMD(0x0004);
/* Step 2: If they are the same return Flash_Success */
if( ucFirstRead == ucSecondRead )
return Flash_Success;
/* Step 3: Else return Flash_BlockEraseFailed */
return Flash_BlockEraseFailed;
} /*EndFunction FlashCheckBlockEraseError*/
/*******************************************************************************
Function: ReturnType FlashChipErase( ReturnType *rpResults )
Arguments: rpResults is a pointer to an array where the results will be
stored. If rpResults == NULL then no results have been stored.
Return Value: The function returns the following conditions:
Flash_Success
Flash_ChipEraseFailed
Description: The function can be used to erase the whole flash chip. Each Block
is erased in turn. The function only returns when all of the Blocks have
been erased. If rpResults is not NULL, it will be filled with the error
conditions for each block.
Pseudo Code:
Step 1: Check if some blocks are protected
Step 2: Send Chip Erase Command
Step 3: Check for blocks erased correctly
Step 4: Return to Read mode (if an error occurred)
*******************************************************************************/
ReturnType FlashChipErase( ReturnType *rpResults ) {
ReturnType rRetVal = Flash_Success, /* Holds return value: optimistic initially! */
rProtStatus; /* Holds the protection status of each block */
uBlockType ublCurBlock; /* Used to tack current block in a range */
/* Step 1: Check if some blocks are protected */
for (ublCurBlock=0; ublCurBlock < NUM_BLOCKS;ublCurBlock++) {
if (FlashCheckBlockProtection(ublCurBlock)==Flash_BlockProtected) {
rProtStatus = Flash_BlockProtected;
rRetVal = Flash_ChipEraseFailed;
} else
rProtStatus =Flash_Success;
if (rpResults != NULL)
rpResults[ublCurBlock] = rProtStatus;
} /* Next ublCurBlock */
/* Step 2: Send Chip Erase Command */
FlashWrite( ConvAddr(0x00555), (uCPUBusType)CMD(0x00AA) );
FlashWrite( ConvAddr(0x002AA), (uCPUBusType)CMD(0x0055) );
FlashWrite( ConvAddr(0x00555), (uCPUBusType)CMD(0x0080) );
FlashWrite( ConvAddr(0x00555), (uCPUBusType)CMD(0x00AA) );
FlashWrite( ConvAddr(0x002AA), (uCPUBusType)CMD(0x0055) );
FlashWrite( ConvAddr(0x00555), (uCPUBusType)CMD(0x0010) );
/* Step 3: Check for blocks erased correctly */
if( FlashDataToggle(ANY_ADDR)!=Flash_Success){
rRetVal= Flash_ChipEraseFailed;
if (rpResults != NULL){
for (ublCurBlock=0;ublCurBlock < NUM_BLOCKS;ublCurBlock++)
if (rpResults[ublCurBlock]==Flash_Success)
rpResults[ublCurBlock] = FlashCheckBlockEraseError(ublCurBlock);
} /* EndIf */
/* Step 4: Return to Read mode (if an error occurred) */
FlashWrite( ANY_ADDR, (uCPUBusType)CMD(0x00F0) ); /* Use single instruction cycle method */
} /* EndIf */
return rRetVal;
} /* EndFunction FlashChipErase */
/*******************************************************************************
Function: ReturnType FlashChipUnprotect( ReturnType *rpResults )
Arguments: rpResults, if not NULL, it contains the status of every block.
This device does not support this functionality. If rpResults == NULL
then no results are stored. Otherwise the Flash_NoInformationAvailable
is written to the array.
Return Value: The function returns the following conditions:
Flash_Success
Flash_ChipUnprotectFailed
Description: This function unprotects the whole flash chip implementing the
In-System Unprotection procedure (see the device datasheet).
Pseudo Code:
Step 1: filling of rpResults
Step 2: protect all blocks
Step 3: setup phase
Step 4: unprotect phase
Step 5: verify phase
Step 6: if verified and the current block isn't last block, increment current
block number and repeat from step 3; else return Flash_Success
Step 7: if not verified and if attempts number is < 1000, repeat from step 2,
else return Flash_ChipUnprotectFailed
*******************************************************************************/
ReturnType FlashChipUnprotect( ReturnType *rpResults )
{
uBlockType ublCurBlockNr;
uCPUBusType ucReadData;
word wAttempt;
udword udAddrOff,i;
/* Step 1: filling of rpResults */
if (rpResults !=NULL) {
for (ublCurBlockNr=0; ublCurBlockNr<NUM_BLOCKS; ublCurBlockNr++)
rpResults[ublCurBlockNr]=Flash_NoInformationAvailable;
} /* EndIf */
/* Step 2: protect all blocks */
i = 0;
for (ublCurBlockNr=0; ublCurBlockNr<NUM_BLOCKS; ublCurBlockNr+=BlockGroupOffset[i++]){
if (FlashGroupProtect(ublCurBlockNr) == Flash_GroupProtectFailed)
return Flash_ChipUnprotectFailed;
} /* Next ublCurBlockNr */
/* Reset command */
FlashWrite( ANY_ADDR, (uCPUBusType)CMD(0x00F0) ); /* Use single instruction cycle method */
wAttempt = 0;
ublCurBlockNr = 0;
udAddrOff = ANY_ADDR & 0x11111100;
i = 0;
/* Step 3: setup phase */
FlashWrite( (udAddrOff | ShAddr(0x00000042)), CMD(0x0060) );
do {
FlashWrite( (udAddrOff | ShAddr(0x00000042)), CMD(0x0060) );
FlashPause(10000);
do {
/* Step 4: unprotect phase */
FlashWrite( (BlockOffset[ublCurBlockNr] | ShAddr(0x00000042)), CMD(0x0040) );
FlashPause(4);
ucReadData = FlashRead( BlockOffset[ublCurBlockNr] | ShAddr(0x00000042) );
/* Step 5: verify phase */
if ( ucReadData == CMD(0x0000) ){
/* Step 6: if verified, if the current block isn't last block increment current block
number and repeat step from 3 else return Flash_Success */
ublCurBlockNr += BlockGroupOffset[i++]; /* Next group */
if ( ublCurBlockNr < NUM_BLOCKS ) {
continue;
}
else {
/* Reset command */
FlashWrite( ANY_ADDR, (uCPUBusType)CMD(0x00F0) ); /* Use single instruction cycle method */
return Flash_Success;
}
} /* EndIf */
else
break;
} while (1);
/* Step 7: if not verified and if attempts number is < 1000, repeat step from 2,
else return Flash_ChipUnprotectFailed */
} while (++wAttempt < 1000 );
FlashWrite( ANY_ADDR, (uCPUBusType)CMD(0x00F0) ); /* Use single instruction cycle method */
return Flash_ChipUnprotectFailed;
} /* EndFunction FlashChipUnprotect */
/*******************************************************************************
Function: ReturnType FlashDataToggle( udword udAddrOff )
Arguments: none
Return Value: The function returns Flash_Success if the Program/Erase Controller
is successful or Flash_SpecificError if there is a problem.In this case
the field eiErrorInfo.sprRetVal will be filled with FlashSpec_ToggleFailed value.
If the Program/Erase Controller do not finish before time-out expired
the function return Flash_OperationTimeout.
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. In the Data Sheets, the Data Toggle Flow Chart shows the operation
of the function.
Pseudo Code:
Step 1: Read DQ5 and DQ6 (into word)
Step 2: Read DQ6 (into another a word)
Step 3: If DQ6 did not toggle between the two reads then return Flash_Success
Step 4: Else if DQ5 is zero then operation is not yet complete, goto 1
Step 5: Else (DQ5 != 0), read DQ6 again
Step 6: If DQ6 did not toggle between the last two reads then return
Flash_Success
Step 7: Else return Flash_ToggleFail
*******************************************************************************/
static ReturnType FlashDataToggle( udword udAddrOff ){
uCPUBusType ucVal1, ucVal2; /* hold values read from any address offset within
the Flash Memory */
FlashTimeOut(0); /* Initialize TimeOut Counter */
while(FlashTimeOut(120) != Flash_OperationTimeOut) {
/* TimeOut: If, for some reason, the hardware fails then this
loop exit and the function return flash_OperationTimeOut. */
/* Step 1: Read DQ5 and DQ6 (into word) */
ucVal2 = FlashRead( udAddrOff ); /* Read DQ5 and DQ6 from the Flash (any
address) */
/* Step 2: Read DQ6 (into another a word) */
ucVal1 = FlashRead( udAddrOff ); /* Read DQ6 from the Flash (any address) */
/* Step 3: If DQ6 did not toggle between the two reads then return
Flash_Success */
if( (ucVal1&CMD(0x0040)) == (ucVal2&CMD(0x0040)) ) /* DQ6 == NO Toggle */
return Flash_Success;
/* Step 4: Else if DQ5 is zero then operation is not yet complete */
if( (ucVal2&CMD(0x0020)) != CMD(0x0020) )
continue;
/* Step 5: Else (DQ5 == 1), read DQ6 twice */
ucVal1 = FlashRead( udAddrOff ); /* Read DQ6 from the Flash (any address) */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -