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

📄 c2188.c

📁 Flash Low Level Driver Code
💻 C
📖 第 1 页 / 共 4 页
字号:
   
   /* Issue the Program Command*/
   NAND_CommandInput((ubyte)0x10);
                                            
                                                                               
   /* Wait for ready */
   ubStatus=waitForReady();
     
  
   NAND_Close();
  if( (ubStatus&(0x80))==0)
  	return ubStatus&(0x80);

  return ubStatus&(0x01); 
}
/**************  NAND_CopyBack ***************/
  
  



/******************************************************************************
                  NAND_CacheProgram

Function:       NAND_Ret NAND_CacheProgram(udword udPageAddresses[],
                                            ubyte piecesNumber,ubyte *Buffers[], 
                                             udword udlength[],ubyte* errorPage)
Arguments:      udPageAddresses:
                  The addresses of page where copy in.
                piecesNumber:
                  the number of data pieces to write
                Buffers:
                  buffer of data to write
                udlength:
                  the size of each piece of data to write
                errorPage:
                  the number of the page where (if happen) the cache program 
                  have failed
                  
Return Value: 	NAND_FLASH_SIZE_OVERFLOW:
                  The address is not within the flash
                NAND_PASS
                  The operation are successfully executed
                NAND_FAIL 
                  The operation are not successfully executed.	
                NAND_WRONG_ADDRESS
                  The pages are not in the same half of the flash.
Description:    This function issue a cache program command as explained in the
                datasheet of the 2112 byte/1056 word page family. 
				The function stores in errorPage parameter, the page where the 
				program have failed(if it happen)

******************************************************************************/

NAND_Ret NAND_CacheProgram(udword udPageAddresses[],ubyte piecesNumber, dataWidth **Buffers, uword udlength[],ubyte* errorPage)
{

 ubyte ubStatus;
 udword index;
 ubyte i,j;
 byte lastPage=-1;
 byte currentPage=0;
 byte prev,next;
 
 
 ubyte count;
 int val,value;
 ubyte random_op;
 
 
 
/*check addresses*/

 for (i=0; i<piecesNumber; i++){

 	/*check if the addresses are within a same block*/
	 if (ADDRESS_2_BLOCK(udPageAddresses[i]) != ADDRESS_2_BLOCK(udPageAddresses[0]) )
     	return NAND_WRONG_ADDRESS;	
		
 	/*check if the addresses are within the flash*/
 	if (udPageAddresses[i]>=FLASH_SIZE)
 	  return NAND_FLASH_SIZE_OVERFLOW;
 	
 	  
    /*check if there is an overflow in main or spare*/
    
	if ((udlength[i] & 0x8000) != 0) { 
	/*IN SPARE */
        if (( (udPageAddresses[i] & (0x000003FF<<SHIFT_A8)) + (udlength[i]&0x7FFF) ) > PAGE_SPARE_SIZE) {  
        	return NAND_FAIL;
        }
    } else 
    /* IN MAIN */
	    if ( ( (udPageAddresses[i] & (0x000003FF<<SHIFT_A8)) + udlength[i]) > PAGE_SIZE) { 
	    	return NAND_FAIL;
	}
    
    
    /*check if there is an overlapping*/
    prev = ( udPageAddresses[i]  & (0x0000FC00<<SHIFT_A8) ) >> (10+SHIFT_A8);
    
    for (j=i+1; j<piecesNumber; j++){    	
    
    	/*check if the addresses are within a same block*/
		if (ADDRESS_2_BLOCK(udPageAddresses[j]) != ADDRESS_2_BLOCK(udPageAddresses[0]) )
    		return NAND_WRONG_ADDRESS;	    
    
    	next = ( udPageAddresses[j]  & (0x0000FC00<<SHIFT_A8) ) >> (10+SHIFT_A8);

		/* the same page*/ 
    	if (prev == next) { 
    		/* i spare ~ j spare */
    		if (  ((udlength[i] & 0x8000) != 0) && ((udlength[j] & 0x8000) != 0)  ) {
			  if (udPageAddresses[j]>udPageAddresses[i]){ /* j address > i address */
			  	if ( ((udPageAddresses[i] & (0x000003FF<<SHIFT_A8))+(udlength[i]&0x7FFF) ) > (udPageAddresses[j] & (0x000003FF<<SHIFT_A8)) ) {
   			   			return NAND_FAIL;
   			   	}
			  } else { /* i address > j address */
			  	if ( ((udPageAddresses[j] & (0x000003FF<<SHIFT_A8))+(udlength[j]&0x7FFF) ) > (udPageAddresses[i] & (0x000003FF<<SHIFT_A8)) ) {
   			   			return NAND_FAIL;
   			   	}
			  }    		
    		}
    		/* i main ~ j main */
    		if (  ((udlength[i] & 0x8000) == 0) && ((udlength[j] & 0x8000) == 0)  ) {
    		  if (udPageAddresses[j]>udPageAddresses[i]){ /* j address > i address */
			  	if ( ((udPageAddresses[i] & (0x000003FF<<SHIFT_A8))+(udlength[i]&0x7FFF) ) > (udPageAddresses[j] & (0x000003FF<<SHIFT_A8)) ) {
   			   			return NAND_FAIL;
   			   	}
			  } else { /* i address > j address */
			  	if ( ((udPageAddresses[j] & (0x000003FF<<SHIFT_A8))+(udlength[j]&0x7FFF) ) > (udPageAddresses[i] & (0x000003FF<<SHIFT_A8)) ) {
   			   			return NAND_FAIL;
   			   	}
			  }    		    		
    		}
    		
    		/* i main ~ j spare */
    		if ( ((udlength[i] & 0x8000) == 0) && ((udlength[j] & 0x8000) != 0) ){
    		  if ( ((udPageAddresses[i] & (0x000003FF<<SHIFT_A8))+udlength[i]) > (udPageAddresses[j] & (0x000003FF<<SHIFT_A8))+PAGE_DATA_SIZE ) { 
   			  	return NAND_FAIL;
   			  }		
    		}  		
    		
    		/* i spare ~ j main */
    		if ( ((udlength[i] & 0x8000) != 0) && ((udlength[j] & 0x8000) == 0) ){
    		  if ( ((udPageAddresses[j] & (0x000003FF<<SHIFT_A8))+udlength[j]) > (udPageAddresses[i] & (0x000003FF<<SHIFT_A8))+PAGE_DATA_SIZE ) { 
   			  	return NAND_FAIL;
   			  }		
    		} 
    	}		
    }		
    	
    	
    		
			
 }
 
  
 /* program flash */
 
 count = 0;
 val = -1;
 value =-1;
 do {
  		 	
	 	for (j=0; j<piecesNumber; j++){
 			next = ( udPageAddresses[j]  & (0x0000FC00<<SHIFT_A8) ) >> (10+SHIFT_A8);
	 		if ( ( next != value) && ( next > val ) ) {
		       value = next;
	    	   break;
	    	}
 		} 		
 	
  	/* find the min page different to previous min ( val ) */
 	for (j=0; j<piecesNumber; j++){ 		
 		next = ( udPageAddresses[j]  & (0x0000FC00<<SHIFT_A8) ) >> (10+SHIFT_A8);
 		
 		if ( (val == -1) && ( next < value ) ) {
 			value = next;		
 		} else {
 			if ((val != -1) && ( next > val ) && ( next < value ) ) {
 				value = next; 		
 			} 	
 		}
 	
 	}
 	
 	val = value;
 	
 	/* Perform cache program with random data input of the chuncks with page address equal to val*/
 	random_op = 0 ;
 	for (i=0; i<piecesNumber; i++) {
 		
 		next = ( udPageAddresses[i]  & (0x0000FC00<<SHIFT_A8) ) >> (10+SHIFT_A8);

		if (next == val) {
			
			count++;
			
			if ( random_op) {
				
				/* Issue random Data input command */
		 		NAND_CommandInput((ubyte)0x85);
				
				/* insert the column address */		
			    if((udlength[i]&0x8000)==0x8000){
	   				InsertColumnAddressSpare(udPageAddresses[i]);  		
	    		}else{
	   	 			InsertColumnAddress(udPageAddresses[i]);  		
	    		}
	    		
	    		
	    		/* write data */

				#ifdef DMA_ENABLE
					
					/* to be implemented*/

	    		#else
		 			for (index=0; index<((0x7FFF)&udlength[i]);index++)
			 			NAND_DataInput(*((*(Buffers+i))+index));
	    		#endif
				
								
			} else {
			
				/* Issue page program code */
 				NAND_CommandInput((ubyte)0x80);
				
				/* insert the address  */		
				if((udlength[i]&0x8000)==0x8000){
	   				InsertSpareAddress(udPageAddresses[i]);  
			    }else{
	    			InsertAddress(udPageAddresses[i]);  
	    		}
				
				/* write data */
				#ifdef DMA_ENABLE
					
					/* to be implemented*/

	    		#else
				 	for (index=0;index<((0x7FFF)&udlength[i]);index++)
					 	NAND_DataInput(*((*(Buffers+i))+index));
			    #endif
			
			}
			
			random_op = 1;
		}
 	}
 
 
 	if (count<piecesNumber){   
 		/* issue cache program confirm code */
		NAND_CommandInput((ubyte)0x15);	
	
		/* Wait for Cache Register ready, SR6=1 */
    	NAND_CommandInput((ubyte)0x70);
    	ubStatus = NAND_DataOutput();
    
    	ubStatus = waitForReady();
	 		 
		if ((ubStatus & 0x02) == 0x01) {  
			*errorPage = lastPage;
	 		NAND_Close();
    		return NAND_FAIL;	 		 		
		}	 
	}
 
 
 } while (count<piecesNumber);
 
 /* issue page program confirm code */
 NAND_CommandInput((ubyte)0x10);
 
 ubStatus = waitForReady();
	 		 
 if ((ubStatus & 0x01) == 0x01) { 
 	*errorPage = currentPage;
	NAND_Close();
    
 	return NAND_FAIL;	 		 		
 }	 
  
 NAND_Close();
  
 return NAND_PASS;
 
} 
/******************************************************************************
                  NAND_ReadElectronicSignature

Function:         void NAND_ReadElectronicSignature(ubyte *Buffer)
Arguments:        Buffer:
                     contains the byte returned from ReadElectronicSignature
                     command.
Return Value:     na	
Description:      The ReadElectronicSignature operation issue a 
                  ReadElectronicSignature Command as explained in the datasheet 
                  of the 2112 byte/1056 word page family.
******************************************************************************/
void NAND_ReadElectronicSignature(dataWidth *Buffer) { 
  
   ubyte ubIndex;

   NAND_Open();
   /* Insert ReadElectronicSignature command */                          
   NAND_CommandInput((ubyte)0x90); 
                                                                                             

   /* Issue the address */                          
   NAND_AddressInput((ubyte)0x00); /* first address byte */
   
   /* read data */
   for (ubIndex=0;ubIndex<4;ubIndex++)
    Buffer[ubIndex]= NAND_DataOutput();
    
   NAND_Close();
       
  
}   

/******************************************************************************
                      NAND_Reset

Function:         void NAND_Reset(void)
Arguments:        na
Return Value:     na 			
Description:      The Reset operation issue a Reset Command as explained in the
                  datasheet of the 2112 byte/1056 word page family.

******************************************************************************/
void NAND_Reset(void) {

   NAND_Open();
  
   /* Issue the Reset Command*/
   NAND_CommandInput((ubyte)0xFF); 
     
   NAND_Close();  

}  
/**************  NAND_Reset ***************/   


/******************************************************************************
                      NAND_Lock

Function:         void NAND_Lock(void)
Arguments:        na
Return Value:     na 			
Description:      The NAND_Lock function issue a Lock Command as explained in the
                  datasheet of the 2112 byte/1056 word page family.

******************************************************************************/
void NAND_Lock(void)
{
	NAND_Open();
	/*issue the lock command*/
	NAND_CommandInput((ubyte)0x2A);
	NAND_Close();  
}


/******************************************************************************
                      LockDown

Function:         void NAND_LockDown(void)
Arguments:        na
Return Value:     na 			
Description:      The NAND_LockDown function issue a Lock Down Command as 
                  explained in the datasheet of the 2112 byte/1056 word page 
                  family.

******************************************************************************/
void NAND_LockDown(void)
{
	NAND_Open();
	/*issue the lock down command*/
	NAND_CommandInput((ubyte)0x2C);
	NAND_Close();  
}

/******************************************************************************
                      NAND_UnLock

Function:         void NAND_UnLock(udword startBlock,udword endBlock)
Arguments:        startBlock:
					the address of the first block to unlock
				  endBlock:
				    the address of the last block to unlock
				    
Return Value:     NAND_WRONG_ADDRESS
					the addresses provide as arguments aren't valid
				  NAND_FLASH_SIZE_OVERFLOW:
				    the addresses provided as arguments  exceedes the flash size
Description:      The NAND_UnLock function issue a UnLock Command as explained 
                  in the datasheet of the 2112 byte/1056 word page family.

******************************************************************************/
NAND_Ret NAND_UnLock(udword startBlock,udword endBlock)
{
	if(((startBlock%BLOCK_SIZE)!=0)||((startBlock%BLOCK_SIZE)!=0)||(startBlock>endBlock))
		return NAND_WRONG_ADDRESS;
	if( (startBlock >= FLASH_SIZE )||(endBlock >= FLASH_SIZE))
   		 return NAND_FLASH_SIZE_OVERFLOW;
   		 
	NAND_Open();
	
	/*issue lock command*/
	NAND_CommandInput((ubyte)0x23);
	InsertBlockAddress(startBlock);


	NAND_CommandInput((ubyte)0x24);
	InsertBlockAddress(endBlock);
	NAND_Close(); 
	return NAND_PASS; 
}



	

/******************************************************************************
                      NAND_ReadBlockLockStatus(udword address)

Function:         NAND_Ret NAND_ReadBlockLockStatus(udword address)
Arguments:        address:
					the address of the block to check
				    
Return Value:     NAND_WRONG_ADDRESS
					the addresse provided isn't valid
				  NAND_FLASH_SIZE_OVERFLOW:
				    the addresse provided as argument exceede the flash size
				  NAND_UNLOCKED_BLOCK
				    the block is not locked
				  NAND_LOCKED_BLOCK
				    the block is locked
				  NAND_LOCK_DOWN
				    the block is locked tight
Description:      The NAND_ReadBlockLockStatus function issue a read block lock 
				  status Command as explained in the datasheet of the 
				  2112 byte/1056 word page family.
              

******************************************************************************/
NAND_Ret NAND_ReadBlockLockStatus(udword address)
{
	ubyte ubStatus;
	
	if((address%BLOCK_SIZE)!=0)
		return NAND_WRONG_ADDRESS;
	if( address >= FLASH_SIZE )
   		 return NAND_FLASH_SIZE_OVERFLOW;
	NAND_Open();
	
	/*read lock status command*/
	NAND_CommandInput((ubyte)0x7A);
	
	InsertBlockAddress(address);
	
	/*read the block lock status*/
	ubStatus=NAND_DataOutput();

	return ubStatus&0x0f;
	NAND_Close();  
	return NAND_PASS;
}



/******************************************************************************
                      NAND_UnlockDown()

Function:         void NAND_UnlockDown()
Arguments:        na
				    
Return Value:     na
Description:      The NAND_UnlockDown function unlocks Locked-Down blocks
              

******************************************************************************/
void NAND_UnlockDown(){
	NAND_Open();
	NAND_SetWriteProtect();
	/* wait almost 100ns as explained in the datasheet */
	NAND_WaitTime(100); 
	NAND_UnsetWriteProtect();	
	NAND_Close();
}

⌨️ 快捷键说明

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