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

📄 c2374.c

📁 M29W320E flash驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
*******************************************************************************/
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 + -