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

📄 nandflash.c

📁 2440的启动代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    else {

				//Uart_Printf("FMD_WriteSector::::::4 \r\n");
				for(i=0;i<512;i++) {
		   			NF_WRDATA8(*pSectorBuff++);	// Write one page to NFM from buffer
      		}
				
        //WritePage512(pSectorBuff,(PULONG)rNFDATA);

    }

    //  Read out the ECC value generated by HW
	NF_MECC_Lock();
    dwECCVal = NF_ECC();///将NFMECC0/存器里产生的ECC数据放在SPARE AREA里去。

	// Write the SectorInfo data to the media
	// NOTE: This hardware is odd: only a byte can be written at a time and it must reside in the
	//       upper byte of a USHORT.
	if(pSectorInfoBuff)
	{
		//Uart_Printf("FMD_WriteSector::::::5 \r\n");
        //  Write the first reserved field (DWORD)
        NF_DATA_W4(pSectorInfoBuff->dwReserved1);

        //  Write OEM reserved flag
        NF_DATA_W( (pSectorInfoBuff->bOEMReserved) );

        //  Write the bad block flag
        NF_DATA_W( (pSectorInfoBuff->bBadBlock) );

        //  Write the second reserved field
        NF_DATA_W( (pSectorInfoBuff->wReserved2 >> 8) & 0xff );
        NF_DATA_W( (pSectorInfoBuff->wReserved2) & 0xff );

	}else///如果不要INFOBUFF信息FOR CE里查询,则写sizeof(SectorInfo)个字节为0XFF。
	{
		// Make sure we advance the Flash's write pointer (even though we aren't writing the SectorInfo data)
		for(i=0; i<sizeof(SectorInfo); i++)
		{
            NF_DATA_W(0xff);
		}
	}

		//Uart_Printf("FMD_WriteSector::::::6 \r\n");
    //  ECC stuff should be here
    eccBuf[0] = (BYTE) ((dwECCVal) & 0xff);
    eccBuf[1] = (BYTE) ((dwECCVal >> 8) & 0xff);
    eccBuf[2] = (BYTE) ((dwECCVal >> 16) & 0xff);

    //  Write the ECC value to the flash
    for(i=0; i<3; i++) {//将ECC generator发生器产生的ECC 码写到SPARE 区域里去。
        NF_DATA_W(eccBuf[i]);
    }

    for(i=0; i<5; i++) { /////??
        NF_DATA_W(0xff);
    }

	NF_CLEAR_RB();
    //  Finish up the write operation
    NF_CMD(CMD_WRITE2);

    //  Wait for RB
	NF_DETECT_RB();	 // Wait tR(max 12us)

    //  Check the status
    NF_CMD(CMD_STATUS);

    if(NF_DATA_R() & STATUS_ERROR) {
//#ifdef BOOT_LOADER
        Uart_Printf("FMD_WriteSector() ######## Error Programming page %d!\r\n", startSectorAddr);
//#else
//        RETAILMSG(1, (TEXT("FMD_WriteSector() ######## Error Programming page %d!\n"), startSectorAddr));
//#endif
        bRet = FALSE;
    }

    //  Disable the chip
    NF_CE_H();

    //RELEASEMUTEX();
    return bRet;
}

#define TACLS		  0
#define TWRPH0		6
#define TWRPH1		2






static U16 NF8_CheckId(void)
{
    int i;
	U16 id, id4th;
    
	NF_nFCE_L();
      	NF_CMD(0x90);
	NF_ADDR(0x0);
	for (i=0; i<10; i++);
	//Uart_Printf("NFSTAT: 0x%x\n", rNFSTAT);
       id=NF_RDDATA8()<<8;	// Maker code 0xec
       id|=NF_RDDATA8();	// Devide code(K9S1208V:0x76), (K9K2G16U0M:0xca)

	NF_nFCE_H();
       return id;
}

//***********************************************************************
void NF_ReadID(void)
{
	U16 id;
	U8 maker, device;

//	NF8_Init();
	id = NF8_CheckId();
	
	device = (U8)id;
	maker = (U8)(id>>8);
	
	if(device!=0x76)
		Uart_Printf("Read Nand Flash ID FAIL!!!\n");
	
	Uart_Printf("Nand Flash ID(0xec76):0x%x%x\n", maker, device);
	

//v1.2
  /*  Uart_SendString("Nand Mfg: ");
    Uart_SendDWORD((DWORD)wData1, TRUE);
    Uart_SendString("Nand Dev: ");
    Uart_SendDWORD((DWORD)wData2, TRUE);
    */
}

//************************************************************************
PVOID FMD_Init(void)
{
//	RETAILMSG(1, (TEXT("FMD::FMD_Init\r\n")));
    //  0. Create the Mutex for shared access between the kernel and MSFLASH

    //rNFReg = (PUSHORT) (0x4E000000);///
    //v_s2440CLKPWR = (CLKPWRreg *) ( CLKPWR_BASE | 0x20000000 );

	
    //  Enable the clock to NAND controller
    rCLKCON |= (1<<4);

	//Uart_Printf("FlashDrv!FMD!FMD_Init: rNFReg = %x \r\n", (USHORT)rNFCONF);

    /*rNFCONF = rNFReg;
    rNFCONT = (PUSHORT) ((PBYTE) rNFReg + 0x04);
    rNFCMD  = (PUSHORT) ((PBYTE) rNFReg + 0x08);
    rNFADDR = (PUSHORT) ((PBYTE) rNFReg + 0x0C);
    rNFDATA = (PULONG)  ((PBYTE) rNFReg + 0x10);
    rNFSTAT = (PUSHORT) ((PBYTE) rNFReg + 0x20);
    rNFECC  = (PULONG)  ((PBYTE) rNFReg + 0x2C);*/

    //  Now we need enable the NAND Flash controller
    //GRABMUTEX();
    rNFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4)|(0<<0);
    rNFCONT = (0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(0<<6)|(0<<5)|(1<<4)|(1<<1)|(1<<0);
    rNFSTAT = 0;
    
    
    
   /* WRITE_REGISTER_USHORT(rNFCONF, (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4)|(0<<0));
    WRITE_REGISTER_USHORT(rNFCONT, (0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(0<<6)|(0<<5)|(1<<4)|(1<<1)|(1<<0));
    WRITE_REGISTER_USHORT(rNFSTAT, 0);*/
    //RELEASEMUTEX();

//	NF_Reset();

	//RETAILMSG(1, (TEXT("FMD::FMD_Init Done\r\n")));
		NF_ReadID(); 
    return (PVOID)rNFCONF;

ErrExit:
    //FMD_Deinit((PVOID)rNFCONF);
    return 0;
}




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

void K9S1208_Program(U32 DownBlock)   
{
//    unsigned long interrupt_reservoir;
    int i;
    int programError=0;
    U8 *srcPt,*saveSrcPt;
    U32 blockIndex,blockLimit;
	SectorInfo si;
		FMD_Init();
    //downloadAddress=0x30100000;
    //    downloadAddress=0x30200000; 
    Uart_Printf("\n[ NAND Flash writing program]\n");

   // NF_Init();
     NF_Reset();

//    rINTMSK = BIT_ALLMSK; 	
    targetSize=downloadFileSize;
    //Uart_Printf("target Size=0x%x\n",targetSize);
    //if(targetSize==0)
    //{
        srcAddress=0x30100000; 
     //  srcAddress=0x30200000; 
        //Uart_Printf("the data must be downloaded using ICE from %xh\n",srcAddress);			
    //}
   // else 
	//srcAddress=downloadAddress+4; //to discard the data head for the size
 	    
    //InputTargetBlock();
    targetBlock=DownBlock;
		targetSize=downloadFileSize;

    Uart_Printf("\nsource base address(0x3010000x)=0x%x\n",srcAddress);
    Uart_Printf("target start block number      =%d\n",targetBlock);
    Uart_Printf("target size        (0x4000*n)  =0x%x\n",targetSize);

    srcPt=(U8 *)srcAddress;
    blockIndex=targetBlock;

	 si.bOEMReserved = 0xff;//OEM_BLOCK_RESERVED | OEM_BLOCK_READONLY;
     si.bBadBlock    = 0xff;//BADBLOCKMARK;
     si.dwReserved1  = 0xffff;//0;
     si.wReserved2   = 0xff;//0;
		//Uart_Printf("----------1 \r\n");
	  blockLimit = targetSize / (16*1024); 
	 // Uart_Printf("\nblockLimit:%d\n",blockLimit);
	 
	 

    while(1)
    {
        saveSrcPt=srcPt;	

#if BAD_CHECK       
	if(IsBlockBad(blockIndex))	// 1:bad 0:good
        {
	    blockIndex++;   // for next block
	    //Uart_Printf("----------2 \r\n");
	    continue;
	}
#endif

	if(!FMD_EraseBlock(blockIndex))
	{
	    //Uart_Printf("----------4 \r\n");
	    blockIndex++;   // for next block//不能加一,因为如果是0块,如果他都不能用,
	    Uart_Printf("\nFMD_EraseBlock continue\n");
	    continue;
	}   
	for(i=(blockIndex<<5);i<(blockIndex<<5)+32;i++)
	{

		if (!FMD_WriteSector(i, srcPt,&si, 1))
	//    if(!NF_WritePage(blockIndex,i,srcPt))// block num, page num, buffer
	    {
		    Uart_Printf("NBOOT_Write ERROR: Unable to save NBOOT Flag \r\n");
	        programError=1;
	        break;
	    }
//#if ECC_CHECK    
	    if(!NF_ReadPage(blockIndex,i,srcPt))
	    {
		Uart_Printf("ECC Error(block=%d,page=%d!!!\n",blockIndex,i);
	    }
//#endif	    
		srcPt+=512;	// Increase buffer addr one pase size
	    
	    if((U32)srcPt>=(srcAddress+targetSize)) // Check end of buffer
		break;	// Exit for loop
	}
	
	Uart_Printf(".");
	
	
        if(programError==1)
	{
	    blockIndex++;
	    srcPt=saveSrcPt;
	    programError=0;
	    continue;
	}
	if((U32)srcPt>=(srcAddress+targetSize))
	    break;	// Exit while loop
	blockIndex++;
    }
	//Uart_Printf("----------6 \r\n");
	Uart_Printf("\nDownload Success!!!\r\n");

}

//*************************************************************
//*************************************************************
//*************************************************************
BOOL MarkBlockBad(BLOCK_ID blockID)
{
    DWORD   dwStartPage = blockID << 5;
    BOOL    bRet = TRUE;    
	int i;

    Uart_Printf("MarkBlockBad::::Block Num = %d !!!\r\n",blockID);

    //  Enable chip
    NF_CE_L();
	NF_CLEAR_RB();

    //  Issue command
    //  We are dealing with spare area
    NF_CMD(CMD_READ2);
    NF_CMD(CMD_WRITE);

    //  Set up address
    NF_ADDR(VALIDADDR);
    NF_ADDR((dwStartPage) & 0xff);
    NF_ADDR((dwStartPage >> 8) & 0xff);
    if (NEED_EXT_ADDR) {
        NF_ADDR((dwStartPage >> 16) & 0xff);
    }

    NF_DATA_W(BADBLOCKMARK);

    //  Copmlete the write
    NF_CMD(CMD_WRITE2);

	for(i=0;i<10;i++);  //延时	
    //  Wait for RB
	NF_DETECT_RB();	 // Wait tR(max 12us)

    //  Get the status
    NF_CMD(CMD_STATUS);


    for(i=0;i<3;i++);///延时

    if(NF_DATA_R() &  STATUS_ERROR) {
        Uart_Printf("######## Failed to mark the block bad!\n");
        bRet = FALSE;
    }

    //  Disable chip select
    NF_CE_H();


 
    return bRet;
}












//************************************************************************
BOOL FMD_SetBlockStatus(BLOCK_ID blockID, DWORD dwStatus)
{
    SECTOR_ADDR sectorAddr = blockID << 5;
	BYTE bStatus = 0;


        if(!MarkBlockBad (blockID))
        {
			 Uart_Printf("FMD::MarkBlockBad--Failed\r\n");
            return FALSE;
        }
	//	RETAILMSG(1, (TEXT("MarkBlockBad-Success\r\n")));

    // We don't currently support setting a block to read-only, so fail if request is
    // for read-only and block is not currently read-only.
    return TRUE;
}






//*************************************************************************
void EraseFlash()
{
	U8 key;
	int i;
	Uart_Printf("Are You Sure Erase Blocks ? [Y/N]\n");
	key=Uart_Getch();
	if (( key=='y') || ( key=='Y'))
	{
		Uart_Printf("Start Erase Blocks.... please waite....\n");
		for (i=0;i < NUM_BLOCKS;i++)
		{
			if (!(FMD_EraseBlock(i)))  //擦除整个芯片
			    FMD_SetBlockStatus(i, BLOCK_STATUS_BAD);
		}
			Uart_Printf("Over Erase Blocks\n");
	}
  else Uart_Printf("No Block Erase!\n");

}

⌨️ 快捷键说明

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