📄 c2635.c
字号:
/*******************************************************************************
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()!=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 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 FlashMultipleBlockErase(uBlockType ublNumBlocks,uBlockType
*ublpBlock,ReturnType *rpResults)
Arguments: ublNumBlocks holds the number of blocks in the array ubBlock
ublpBlocks is an array containing the blocks to be erased.
rpResults is an array that it holds the results of every single block
erase.
Every elements of rpResults will be filled with below values:
Flash_Success
Flash_BlockEraseFailed
Flash_BlockProtected
If a time-out occurs because the MPU is too slow then the function returns
Flash_MpuTooSlow
Return Value: The function returns the following conditions:
Flash_Success
Flash_BlockEraseFailed
Flash_BlockNrInvalid
Flash_OperationTimeOut
Flash_SpecificError : if a no standard error occour.In this case the
field sprRetVal of the global variable eiErrorInfo will be filled
with Flash_MpuTooSlow when any blocks are not erased because DQ3
the MPU is too slow.
Description: This function erases up to ublNumBlocks in the flash. The blocks
can be listed in any order. The function does not return until the blocks are
erased. If any blocks are protected or invalid none of the blocks are erased,
in this casse the function return Flash_BlockEraseFailed.
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 1: Check for invalid block
Step 2: Check if some blocks are protected
Step 3: Write Block Erase command
Step 4: Check for time-out blocks
Step 5: Wait for the timer bit to be set.
Step 6: Follow Data Toggle Flow Chart until Program/Erase Controller has
completed
Step 7: Return to Read mode (if an error occurred)
*******************************************************************************/
ReturnType FlashMultipleBlockErase(uBlockType ublNumBlocks,uBlockType *ublpBlock,ReturnType *rpResults) {
ReturnType rRetVal = Flash_Success, /* Holds return value: optimistic initially! */
rProtStatus; /* Holds the protection status of each block */
uBlockType ublCurBlock; /* Range Variable to track current block */
uCPUBusType ucFirstRead, ucSecondRead; /* used to check toggle bit DQ2 */
/* Step 1: Check for invalid block. */
if( ublNumBlocks > NUM_BLOCKS ){ /* Check specified blocks <= NUM_BLOCKS */
eiErrorInfo.sprRetVal = FlashSpec_TooManyBlocks;
return Flash_SpecificError;
} /* EndIf */
/* Step 2: Check if some blocks are protected */
for (ublCurBlock=0; ublCurBlock < ublNumBlocks;ublCurBlock++) {
if (FlashCheckBlockProtection(ublCurBlock)==Flash_BlockProtected) {
rProtStatus = Flash_BlockProtected;
rRetVal = Flash_BlockEraseFailed;
} else
rProtStatus =Flash_Success;
if (rpResults != NULL)
rpResults[ublCurBlock] = rProtStatus;
} /* Next ublCurBlock */
/* Step 3: Write Block 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) );
/* DSI!: Disable Interrupt, Time critical section. Additional blocks must be added
every 50us */
for( ublCurBlock = 0; ublCurBlock < ublNumBlocks; ublCurBlock++ ) {
FlashWrite( BlockOffset[ublpBlock[ublCurBlock]], (uCPUBusType)CMD(0x0030) );
/* Check for Erase Timeout Period (is bit DQ3 set?)*/
if( (FlashRead( BlockOffset[ublpBlock[0]] ) & CMD(0x0008)) != 0 )
break; /* Cannot set any more blocks due to timeout */
} /* Next ublCurBlock */
/* ENI!: Enable Interrupt */
/* Step 4: Check for time-out blocks */
/* if timeout occurred then check if current block is erasing or not */
/* Use DQ2 of status register, toggle implies block is erasing */
if ( ublCurBlock < ublNumBlocks ) {
ucFirstRead = FlashRead( BlockOffset[ublpBlock[ublCurBlock]] ) & CMD(0x0004);
ucSecondRead = FlashRead( BlockOffset[ublpBlock[ublCurBlock]] ) & CMD(0x0004);
if( ucFirstRead != ucSecondRead )
ublCurBlock++; /* Point to the next block */
if( ublCurBlock < ublNumBlocks ){
/* Indicate that some blocks have been timed out of the erase list */
rRetVal = Flash_SpecificError;
eiErrorInfo.sprRetVal = FlashSpec_MpuTooSlow;
} /* EndIf */
/* Now specify all other blocks as not being erased */
while( ublCurBlock < ublNumBlocks ) {
rpResults[ublCurBlock++] = Flash_BlockEraseFailed;
} /* EndWhile */
} /* EndIf ( ublCurBlock < ublNumBlocks ) */
/* Step 5: Wait for the Erase Timer Bit (DQ3) to be set */
FlashTimeOut(0); /* Initialize TimeOut Counter */
while( !(FlashRead( BlockOffset[ublpBlock[0]] ) & CMD(0x0008) ) ){
if (FlashTimeOut(5) == Flash_OperationTimeOut) {
FlashWrite( ANY_ADDR, (uCPUBusType)CMD(0x00F0) ); /* Use single instruction
cycle method */
return Flash_OperationTimeOut;
} /* EndIf */
} /* EndWhile */
/* Step 6: Follow Data Toggle Flow Chart until Program/Erase Controlle completes */
if( FlashDataToggle() != Flash_Success ) {
if (rpResults != NULL) {
for (ublCurBlock=0;ublCurBlock < ublNumBlocks;ublCurBlock++)
if (rpResults[ublCurBlock]==Flash_Success)
rpResults[ublCurBlock] = FlashCheckBlockEraseError(ublCurBlock);
} /* EndIf */
/* Step 7: Return to Read mode (if an error occurred) */
FlashWrite( ANY_ADDR, (uCPUBusType)CMD(0x00F0) ); /* Use single instruction cycle method */
rRetVal=Flash_BlockEraseFailed;
} /* EndIf */
return rRetVal;
} /* EndFunction FlashMultipleBlockErase */
/*******************************************************************************
Function: ReturnType FlashProgram( udword udMode, udword udAddrOff,
udword udNrOfElementsInArray, void *pArray )
Arguments: udMode changes between programming modes
udAddrOff is the address offset into the flash to be programmed
udNrOfElementsInArray holds the number of elements (uCPUBusType) in the array.
pArray is a void pointer to the array with the contents to be programmed.
Return Value: The function returns the following conditions:
Flash_Success
Flash_AddressInvalid
Flash_ProgramFailed
Description: This function is used to program an array into the flash. It does
not erase the flash first and will not produce proper results, if the block(s)
are not erased first.
Any errors are returned without any further attempts to program other addresses
of the device. The function returns Flash_Success when all addresses have
successfully been programmed.
Note: Two program modes are available:
- udMode = 0, Normal Program Mode
The number of elements (udNumberOfElementsInArray) contained in pArray
are programmed directly to the flash starting with udAddrOff.
- udMode = 1, Single Value Program Mode
? Only the first value of the pArray will be programmed to the flash
starting from udAddrOff.
.
Pseudo Code:
Step 1: Check whether the data to be programmed are are within the
Flash memory
Step 2: Determine first and last block to program
Step 3: Check protection status for the blocks to be programmed
Step 4: Issue the Unlock Bypass command
Step 5: Unlock Bypass Program command
Step 6: Wait until Program/Erase Controller has completed
Step 7: Return to Read Mode
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -