⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 c2635.c

📁 Flash Memory 依據標準CFI CMD做Erase/Program過程的參考碼
💻 C
📖 第 1 页 / 共 5 页
字号:



/*******************************************************************************
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 + -