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

📄 c2374.c

📁 M29W320E flash驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
   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(BlockOffset[ublpBlock[0]]) !=  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:    void FlashPause( udword udMicroSeconds )
Arguments:   udMicroSeconds is the length of the pause in microseconds
Returns:     None
Description: This routine returns after udMicroSeconds have elapsed. It is used
   in several parts of the code to generate a pause required for correct
   operation of the flash part.

Pseudo Code:
   Step 1: Initilize clkReset variable.
   Step 2: Count to the required size.
*******************************************************************************/

#ifdef TIME_H_EXISTS
/*-----------------------------------------------------------------------------
 Note:The Routine uses the function clock() inside of the ANSI C library "time.h". 
-----------------------------------------------------------------------------*/

static void FlashPause(udword udMicroSeconds){
   clock_t clkReset,clkCounts;

   /* Step 1: Initialize clkReset variable */
   clkReset=clock();

   /* Step 2: Count to the required size */
   do
      clkCounts = clock()-clkReset;
   while (clkCounts < ((CLOCKS_PER_SEC/1e6L)*udMicroSeconds));

} /* EndFunction FlashPause */
#else

/*-----------------------------------------------------------------------------
Note: The routine here works by counting. The user may already have a more suitable
      routine for timing which can be used.
-----------------------------------------------------------------------------*/

static void FlashPause(udword udMicroSeconds) {
   static udword udCounter;

   /* Step 1: Compute the count size */
   udCounter = udMicroSeconds * COUNT_FOR_A_MICROSECOND;

   /* Step 2: Count to the required size */
   while( udCounter > 0 ) /* Test to see if finished */
      udCounter--; /* and count down */
} /* EndFunction FlashPause */

#endif





/*******************************************************************************
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
   Step  8:  Decision between direct and single value programming
   Step  9:  Unlock Bypass Reset
*******************************************************************************/
ReturnType FlashProgram(udword udMode, udword udAddrOff, udword udNrOfElementsInArray, void *pArray ) {
   ReturnType rRetVal = Flash_Success; /* Return Value: Initially optimistic */ 
   ReturnType rProtStatus; /* Protection Status of a block */
   uCPUBusType *ucpArrayPointer; /* Use an uCPUBusType to access the array */ 
   udword udLastOff; /* Holds the last offset to be programmed */ 
   uBlockType ublFirstBlock; /* The block where start to program */
   uBlockType ublLastBlock; /* The last block to be programmed */
   uBlockType ublCurBlock; /* Current block */

   if (udMode > 1)
      return Flash_FunctionNotSupported;

   /* Step 1: Check if the data to be programmed are within the Flash memory space */
   udLastOff = udAddrOff + udNrOfElementsInArray - 1; 
   if( udLastOff >= FLASH_SIZE ) 
      return Flash_AddressInvalid; 
   
   /* Step 2: Determine first and last block to program */
   for (ublFirstBlock=0; ublFirstBlock < NUM_BLOCKS-1;ublFirstBlock++)
      if (udAddrOff < BlockOffset[ublFirstBlock+1]) 
         break;
   
   for (ublLastBlock=ublFirstBlock; ublLastBlock < NUM_BLOCKS-1;ublLastBlock++)
      if (udLastOff < BlockOffset[ublLastBlock+1]) 
         break;
   
   /* Step 3: Check protection status for the blocks to be programmed */
   for (ublCurBlock = ublFirstBlock; ublCurBlock <= ublLastBlock; ublCurBlock++){
      if ( (rProtStatus = FlashCheckBlockProtection(ublCurBlock)) != Flash_BlockUnprotected ){
         rRetVal = Flash_BlockProtected;
         if (ublCurBlock == ublFirstBlock){
            eiErrorInfo.udGeneralInfo[0] = udAddrOff;
            return rRetVal; 
         } else {
            eiErrorInfo.udGeneralInfo[0] = BlockOffset[ublCurBlock];
            udLastOff = BlockOffset[ublCurBlock]-1;
         } /* EndIf ublCurBlock */
      } /* EndIf rProtStatus */
   } /* Next ublCurBlock */
   
   /* Step 4: Issue the Unlock Bypass command */
   FlashWrite( ConvAddr(0x00555), (uCPUBusType)CMD(0x00AA) ); /* 1st cycle */
   FlashWrite( ConvAddr(0x002AA), (uCPUBusType)CMD(0x0055) ); /* 2nd cycle */
   FlashWrite( ConvAddr(0x00555), (uCPUBusType)CMD(0x0020) ); /* 3nd cycle */
   
   ucpArrayPointer = (uCPUBusType *)pArray; 
   
   /* Step 5: Unlock Bypass Program command */ 
   while( udAddrOff <= udLastOff ){
      FlashWrite( ANY_ADDR, CMD(0x00A0) ); /* 1st cycle */
      FlashWrite( udAddrOff, *ucpArrayPointer ); /* 2nd Cycle */  
   
      /* Step 6: Wait until Program/Erase Controller has completed */
      if( FlashDataToggle(udAddrOff) != Flash_Success){
         /* Step 7: Return to Read Mode */
         FlashWrite( ANY_ADDR, (uCPUBusType)CMD(0x00F0) ); /* Use single instruction cycle method */
         rRetVal=Flash_ProgramFailed;
         eiErrorInfo.udGeneralInfo[0] = udAddrOff;
         break; /* exit while cycle */
      } /* EndIf */

      /* Step 8: Decision between direct and single value programming */
      if (udMode == 0) /* Decision between direct and single value programming */
         ucpArrayPointer++;
   
      udAddrOff++;
   } /* EndWhile */
   
   /* Step 9: Unlock Bypass Reset */
   FlashWrite( ANY_ADDR, (uCPUBusType)CMD(0x0090) ); /* 1st cycle */
   FlashWrite( ANY_ADDR, (uCPUBusType)CMD(0x0000) ); /* 2st cycle */
   
   return rRetVal;

} /* EndFunction FlashProgram */ 


#if defined(USE_M29W320EB_8) || defined(USE_M29W320ET_8) /* In 8 bit Mode */

/******************************************************************************* 
Function:     ReturnType FlashQuadProgram( udword udAddrOff, uCPUBusType ucValue1, 
                   uCPUBusType ucValue2,uCPUBusType ucValue3, uCPUBusType ucValue4 ) 
Arguments:    udAddrOff is the address to program.
              ucValue1, ucValue2, ucValue3 and ucValue4 are the values to program 
              on the chip
Return Value: The function returns the following conditions:   
               Flash_Success       
               Flash_ProgramFailed 
   
Note:         
1)    This procedure is available both in 8-bit/16-bit mode. 
2)    This procedure automatically put the 2 least significati bits of udAddrOff 
      to zero, to align the address with a quad-bytes/words boundary.

Description: This function programs four consecutive byte/words, starting from the 
             quadbytes/quadwords boundary.

Pseudo Code: 
   Step 1: Align address to quadbytes/quadwords boundary
   Step 2: Program
   Step 3: Wait until the Program/Erase Controller has completed
   Step 4: Return to read Array mode
********************************************************************************/ 
ReturnType FlashQuadProgram( udword udAddrOff, uCPUBusType ucValue1, uCPUBusType ucValue2, 
                             uCPUBusType ucValue3, uCPUBusType ucValue4  ) {
   ReturnType rRetVal = Flash_Success; /* Return value */

   /* Step 1: Align address to QUAD-BYTE/Word boundary */
   udAddrOff = udAddrOff  & (0xFFFFFFFC);

   /* Step 2: Program  */
   /* Note: the command is expressed with ConvAddr, because it is possible both 8bit and 16bit mode*/
   FlashWrite( ConvAddr(0x0555), CMD(0x0055) ); /* Quadruple Byte Command */
   FlashWrite( udAddrOff,   ucValue1 );
   FlashWrite( udAddrOff+1, ucValue2 );
   FlashWrite( udAddrOff+2, ucValue3 );
   FlashWrite( udAddrOff+3, ucValue4 );
   

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -