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

📄 nandflash.c

📁 应用ADS下载nand flash源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	/*if(TargetAdd)
	{
		ulong sBlock;
		sBlock = Flash_Info.TargetAddr >> 14;
		Current_Block_No = sBlock;
		Current_Page_No = Current_Block_No*PAGE_CNT;
	}
	
	else
	{
		Current_Block_No = 0;
		Current_Page_No = 0;
	}*/	
} 

void FlashConfig(void) /* This cofiguration fits for 512 byte page */
{
	rNFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4)|(0<<0);	
	// TACLS		[14:12]	CLE&ALE duration = HCLK*TACLS.
	// TWRPH0		[10:8]	TWRPH0 duration = HCLK*(TWRPH0+1)
	// TWRPH1		[6:4]	TWRPH1 duration = HCLK*(TWRPH1+1)
	// AdvFlash(R)	[3]		Advanced NAND, 0:256/512, 1:1024/2048
	// PageSize(R)	[2]		NAND memory page size
	//						when [3]==0, 0:256, 1:512 bytes/page.
	//						when [3]==1, 0:1024, 1:2048 bytes/page.
	// AddrCycle(R)	[1]		NAND flash addr size
	//						when [3]==0, 0:3-addr, 1:4-addr.
	//						when [3]==1, 0:4-addr, 1:5-addr.
	// BusWidth(R/W) [0]	NAND bus width. 0:8-bit, 1:16-bit.
	
	rNFCONT = (0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0);
	// Lock-tight	[13]	0:Disable lock, 1:Enable lock.
	// Soft Lock	[12]	0:Disable lock, 1:Enable lock.
	// EnablillegalAcINT[10]	Illegal access interupt control. 0:Disable, 1:Enable
	// EnbRnBINT	[9]		RnB interrupt. 0:Disable, 1:Enable
	// RnB_TrandMode[8]		RnB transition detection config. 0:Low to High, 1:High to Low
	// SpareECCLock	[6]		0:Unlock, 1:Lock
	// MainECCLock	[5]		0:Unlock, 1:Lock
	// InitECC(W)	[4]		1:Init ECC decoder/encoder.
	// Reg_nCE		[1]		0:nFCE=0, 1:nFCE=1.
	// NANDC Enable	[0]		operating mode. 0:Disable, 1:Enable.
}

void NF_Reset(void)
{
	int i;
	
	NF_nFCE_L();
	
	NF_CMD(RESET_CTRL);
	
	for(i=0;i<10;i++);
	
	 NF_DETECT_RB();
	
	NF_nFCE_H();
}

void NF_CHECKID(void)
{
	int i;
	
	NF_nFCE_L();
	rNFCMD = ID_CMD;
	rNFADDR = 0x0;
	
	for(i=0;i<10;i++);
	
	NF_nFCE_H();
}

#ifdef SAMSUNG

int Bad_Block_Check(ulong block)
{
  ulong page_address, i;
  uchar data;
  
  page_address = block << 5;
  
  NF_nFCE_L();
  
  NF_CLEAR_RB();
  
  /* Spare array read command */
  rNFCMD = READ_CMD;
  
  /* Read the mark of bad block in spare arrary */
  rNFADDR = (517&0xf);
  
  /* For block number A[17:0] */
  rNFADDR = (page_address&0xff);
   
  /* For block number A[24:17] */
  rNFADDR = ((page_address>>8)&0xff);
  
  /* For block number A[25] */
  rNFADDR = ((page_address>>16)&0xff);
  
  for(i=0;i<10;i++);
  
  NF_DETECT_RB();

  data = NF_RDDATA();
    
  NF_nFCE_H();
	
  if( (data & 0xFF ) != 0xFF )
    {
      return 0;
    }

  return 1;

} /* End of samsung_nand_bad_block_check */ 
#endif


#ifdef TOSHIBA
int Bad_Block_Check(ulong block)
{

  int i;
  ulong page_address, status, page_no, first_page_no;
  ulong sram_buffer=0x0;
  int block_size_shift;
  ushort no_of_shifts = 1;
  int block_size=PAGE_CNT;
  int page_size=PAGE_SIZE;
  ulong ecc;

  block_size_shift=PAGE_CNT;
  while ( block_size_shift != 2 )
  {
    block_size_shift = block_size_shift >> 1;
    no_of_shifts++;
  }

  /*Reset sram memory */
  for (i = 0; i < page_size/4; i++)
  	*(data_reg + i) = 0;

  /* Set the first page number */
  first_page_no = block << no_of_shifts;

  for (  page_no = first_page_no ; page_no < first_page_no+block_size ; page_no++ )
  {
    page_address = page_no << 9;

    *ale_reg = page_address;

    *cle_reg = READ_DATA;

    status = *status_reg;

    while ( status & READ_DATA != 0)
    {
      status = *status_reg;
    }

    status = *status_reg;
    if ( (status & FS_NAND_OP_ERR_MASK != 0) ||
         (status & FS_NAND_ECC_SELF_ERR_MASK != 0) || 
         (status & FS_NAND_READ_ECC_ERR_MASK != 0) )
    {
      return 0;
    }

    /* TESTING ecc malfunction !!*/
    ecc = *ecc_read_reg;   
    if ( ((ecc & FS_NAND_READ_ECC_ERR_MASK)  != 0) || ((ecc & FS_NAND_ECC_UC_ERR_MASK) != 0 ))
    {
      /*printf("fs_nand_common_fnc: fs_nand_read_page - error bad ecc 0: 0x%08x", ecc);*/
	  status = *status_reg;
      if ( (status & FS_NAND_OP_ERR_MASK != 0) ||
           (status & FS_NAND_ECC_SELF_ERR_MASK != 0) || 
           (status & FS_NAND_READ_ECC_ERR_MASK != 0) )
      {
        /* printf("ecc was bad and status was also bad\n");*/
      }
    }

    /* Reading the sram buffer in chunks of 4 bytes */
    for (i = 0; i < page_size/4; i++)
    {
      sram_buffer = *(data_reg + i);
      if ( (sram_buffer & 0xFFFFFFFF ) != 0xFFFFFFFF )
        return 0;
      sram_buffer=0x0;
    }

  } 

  return 1;

} /* End of toshiba_nand_bad_block_check */

#endif

///////////////////////////////////////////////////////////
/*                   MMU Initialization                  */
/////////////////////////////////////////////////////////// 
#ifdef CACHE

#define R1_I         (1<<12)
#define R1_M         (1)
#define R1_C         (1<<2)
#define R1_A         (1<<1)
#define DESC_SEC	 (0x2|(1<<4))
#define CB		     (3<<2)  //cache_on, write_back
#define CNB		     (2<<2)  //cache_on, write_through 
#define NCB          (1<<2)  //cache_off,WR_BUF on
#define NCNB		 (0<<2)  //cache_off,WR_BUF off
#define AP_RW		 (3<<10) //supervisor=RW, user=RW
#define AP_RO		 (2<<10) //supervisor=RW, user=RO

#define DOMAIN_FAULT	(0x0)
#define DOMAIN_CHK	    (0x1) 
#define DOMAIN_NOTCHK	(0x3) 
#define DOMAIN0		    (0x0<<5)
#define DOMAIN1		    (0x1<<5)

#define _MMUTT_STARTADDRESS     0x33ff8000
#define DOMAIN0_ATTR	(0x1<<0) 
#define DOMAIN1_ATTR	(0x0<<2) 
#define RW_CB		(AP_RW|DOMAIN0|CB|DESC_SEC)
#define RW_CNB		(AP_RW|DOMAIN0|CNB|DESC_SEC)
#define RW_NCNB		(AP_RW|DOMAIN0|NCNB|DESC_SEC)
#define RW_FAULT	(AP_RW|DOMAIN1|NCNB|DESC_SEC)

void MMU_Init(void)
{
	int i,j;
    //========================== IMPORTANT NOTE =========================
    // D and I Cache turn on in order to speed up download 
    //===================================================================

    MMU_DisableDCache();
    MMU_DisableICache();

    //If write-back is used,the DCache should be cleared.
    for(i=0;i<64;i++)
    	for(j=0;j<8;j++)
    	    MMU_CleanInvalidateDCacheIndex((i<<26)|(j<<5));
    MMU_InvalidateICache();
    
    #if 0
    //To complete MMU_Init() fast, Icache may be turned on here.
    MMU_EnableICache(); 
    #endif
    
    MMU_DisableMMU();
    MMU_InvalidateTLB();

    //MMU_SetMTT(int vaddrStart,int vaddrEnd,int paddrStart,int attr)
    MMU_SetMTT(0x00000000,0x07f00000,0x00000000,RW_CNB);  //bank0
    MMU_SetMTT(0x08000000,0x0ff00000,0x08000000,RW_CNB);  //bank1
    MMU_SetMTT(0x10000000,0x17f00000,0x10000000,RW_NCNB); //bank2
    MMU_SetMTT(0x18000000,0x1ff00000,0x18000000,RW_NCNB); //bank3
    //MMU_SetMTT(0x20000000,0x27f00000,0x20000000,RW_CB); //bank4
    MMU_SetMTT(0x20000000,0x27f00000,0x20000000,RW_CNB); //bank4 for STRATA Flash
    MMU_SetMTT(0x28000000,0x2ff00000,0x28000000,RW_NCNB); //bank5
    MMU_SetMTT(0x30000000,0x30f00000,0x30000000,RW_CB);	  //bank6-1
    MMU_SetMTT(0x31000000,0x33e00000,0x31000000,RW_NCNB); //bank6-2
    MMU_SetMTT(0x33f00000,0x33f00000,0x33f00000,RW_CB);   //bank6-3
    MMU_SetMTT(0x38000000,0x3ff00000,0x38000000,RW_NCNB); //bank7
    
    MMU_SetMTT(0x40000000,0x47f00000,0x40000000,RW_NCNB); //SFR
    MMU_SetMTT(0x48000000,0x5af00000,0x48000000,RW_NCNB); //SFR
    MMU_SetMTT(0x5b000000,0xfff00000,0x5b000000,RW_FAULT);//not used

    MMU_SetTTBase(_MMUTT_STARTADDRESS);
    MMU_SetDomain(0x55555550|DOMAIN1_ATTR|DOMAIN0_ATTR); 
    	//DOMAIN1: no_access, DOMAIN0,2~15=client(AP is checked)
    MMU_SetProcessId(0x0);
    MMU_EnableAlignFault();
    	
    MMU_EnableMMU();
    MMU_EnableICache();
    MMU_EnableDCache(); //DCache should be turned on after MMU is turned on.
}

void MMU_SetMTT(int vaddrStart,int vaddrEnd,int paddrStart,int attr)
{
    ulong *pTT;
    int i,nSec;
    pTT=(ulong *)_MMUTT_STARTADDRESS+(vaddrStart>>20);
    nSec=(vaddrEnd>>20)-(vaddrStart>>20);
    for(i=0;i<=nSec;i++)*pTT++=attr |(((paddrStart>>20)+i)<<20);
}


/* Define Inline Functions */
__inline void MMU_DisableDCache(void)
{
	__asm
	{
	    mrc  p15,0,r0,c1,c0,0
   		bic  r0,r0,#R1_C
   		mcr  p15,0,r0,c1,c0,0
	}  		
}

__inline void MMU_DisableICache(void)
{
	__asm
	{
   		mrc  p15,0,r0,c1,c0,0
   		bic  r0,r0,#R1_I
   		mcr  p15,0,r0,c1,c0,0
    }
}

__inline void MMU_CleanInvalidateDCacheIndex(ulong index)
{  
	//int r0;
	__asm
	{
   		mov r0, index
   		mcr  p15,0,r0,c7,c14,2
 		//MOV_PC_LR
 	}
}

__inline void MMU_InvalidateICache(void)
{
	__asm
	{
		 mcr  p15,0,r0,c7,c5,0
	}
}

__inline void MMU_DisableMMU(void)
{
	__asm
	{
   		mrc  p15,0,r0,c1,c0,0
   		bic  r0,r0,#R1_M
   		mcr  p15,0,r0,c1,c0,0
   	}
}

__inline void MMU_InvalidateTLB(void)
{
	__asm
	{
		 mcr  p15,0,r0,c8,c7,0
	}
}

__inline void MMU_EnableMMU(void)
{
	__asm
	{
		mrc  p15,0,r0,c1,c0,0
   		orr  r0,r0,#R1_M
   		mcr  p15,0,r0,c1,c0,0
   	}
}

__inline void MMU_EnableDCache(void)
{
	__asm
	{        
   		mrc  p15,0,r0,c1,c0,0
   		orr  r0,r0,#R1_C
   		mcr  p15,0,r0,c1,c0,0
    }
}

__inline void MMU_EnableICache(void)
{        
	__asm
	{
   		mrc  p15,0,r0,c1,c0,0
   		orr  r0,r0,#R1_I
   		mcr  p15,0,r0,c1,c0,0
    }
}

__inline void MMU_SetTTBase(int base)
{
	//int r0;
	__asm
	{
   		mov r0, base //;ro=TTBase
   		mcr  p15,0,r0,c2,c0,0
   	}
}
   	
__inline void MMU_SetDomain(int domain)
{
	//int r0;
	__asm
	{
		mov r0, domain //;ro=domain
   		mcr  p15,0,r0,c3,c0,0
	}
}

__inline void MMU_SetProcessId(ulong pid)
{
    //int r0;
	__asm
	{
		mov r0, pid //ro=pid
		mcr  p15,0,r0,c13,c0,0
	}
}
      
__inline void MMU_EnableAlignFault(void)    	
{
	__asm
	{
		mrc  p15,0,r0,c1,c0,0
   		orr  r0,r0,#R1_A
   		mcr  p15,0,r0,c1,c0,0
	}
}
   	
#endif

⌨️ 快捷键说明

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