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

📄 nandflash.c

📁 2440的启动代码
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <string.h>
#include "def.h"
#include "option.h"
#include "2440addr.h"
#include "2440lib.h"
#include "2440slib.h"
#include "mmu.h"
#include "profile.h"
#include "memtest.h"

#include "usbmain.h"
#include "usbout.h"
#include "usblib.h"
#include "2440usb.h"


typedef struct _SectorInfo
{
    int dwReserved1;              // Reserved - used by FAL
    int  bOEMReserved;             // For use by OEM
    int  bBadBlock;	            // Indicates if block is BAD
    int  wReserved2;               // Reserved - used by FAL

}SectorInfo, *PSectorInfo;


#define BAD_CHECK	(0)
#define ECC_CHECK	(0)


/*#define READ_REGISTER_BYTE(p) (p)
#define WRITE_REGISTER_BYTE(p, v) (p) = (v);
#define READ_REGISTER_USHORT(p) (p)
#define WRITE_REGISTER_USHORT(p, v) (p) = (v);
#define READ_REGISTER_ULONG(p)  (p)
#define WRITE_REGISTER_ULONG(p, v) (p) = (v);*/


//  Status bit pattern
#define STATUS_READY                0x40
#define STATUS_ERROR                0x01


#define NF_MECC_UnLock()         {rNFCONT&=~(1<<5);}
#define NF_MECC_Lock()         {rNFCONT|=(1<<5);}
#define NF_SECC_UnLock()         {rNFCONT&=~(1<<6);}
#define NF_SECC_Lock()         {rNFCONT|=(1<<6);}
#define NF_CMD(cmd)			{rNFCMD=cmd;}
#define NF_ADDR(addr)		{rNFADDR=addr;}	
#define NF_nFCE_L()			{rNFCONT&=~(1<<1);}
#define NF_nFCE_H()			{rNFCONT|=(1<<1);}
#define NF_RSTECC()			{rNFCONT|=(1<<4);}
#define NF_RDDATA() 		(rNFDATA)
#define NF_RDDATA8() 		((*(volatile unsigned char*)0x4E000010) )
#define NF_WRDATA(data) 	{rNFDATA=data;}
#define NF_WRDATA8(data) 	{rNFDATA8=(BYTE)data;}
#define NF_WAITRB()     while(!(rNFSTAT&(1<<0)))


#define NF_DATA_W(val)  NF_WRDATA8(val)
#define NF_DATA_W4(val)	NF_WRDATA(val)

// RnB Signal
#define NF_CLEAR_RB()    		{rNFSTAT |= (1<<2);}	// Have write '1' to clear this bit.
#define NF_DETECT_RB()    		{while(!(rNFSTAT&(1<<2)));}

#define NF_CE_L()     NF_nFCE_L()
#define NF_CE_H()     NF_nFCE_H()
#define NF_DATA_R()   rNFDATA
#define NF_ECC()      rNFMECC0






typedef DWORD  SECTOR_ADDR;
typedef PDWORD PSECTOR_ADDR;
typedef DWORD  BLOCK_ID;
typedef PDWORD PBLOCK_ID;
static U32 srcAddress;
static U32 targetBlock;	    // Block number (0 ~ 4095)
static U32 targetSize;	    // Total byte size 

//U32 downloadAddress;
extern U32 downloadAddress;

#define NFCONF_INIT                 0xF850

//  NAND Flash Command. This appears to be generic across all NAND flash chips
#define CMD_READ                    0x00        //  Read
#define CMD_READ1                   0x01        //  Read1
#define CMD_READ2                   0x50        //  Read2
#define CMD_READID                  0x90        //  ReadID
#define CMD_WRITE                   0x80        //  Write phase 1
#define CMD_WRITE2                  0x10        //  Write phase 2
#define CMD_ERASE                   0x60        //  Erase phase 1
#define CMD_ERASE2                  0xd0        //  Erase phase 2
#define CMD_STATUS                  0x70        //  Status read
#define CMD_RESET                   0xff        //  Reset

//  Status bit pattern
#define STATUS_READY                0x40        //  Ready
#define STATUS_ERROR                0x01        //  Error
#define VALIDADDR                   0x05
#define NEED_EXT_ADDR               1
#define SECTOR_SIZE                 512

#define BLOCK_STATUS_UNKNOWN	0x01
#define BLOCK_STATUS_BAD		0x02
#define BLOCK_STATUS_READONLY	0x04
#define BLOCK_STATUS_RESERVED 0x08

#define OEM_BLOCK_RESERVED		0x01
#define OEM_BLOCK_READONLY		0x02
#define BADBLOCKMARK          0x00
#define NUM_BLOCKS            4096

#define IMAGE_START_BLOCK           9

void WritePage512(LPBYTE Buf, PULONG pReg);

extern U32 downloadFileSize;

//*********************************************************************
void NF_Reset()
{
	int i;
    NF_CE_L();

	NF_CLEAR_RB();///用了他,
    NF_CMD(CMD_RESET);
	for(i=0;i<10;i++);  //tWB = 100ns. //??????

    NF_CE_H();
}

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

BOOL NAND_WriteSectorInfo(SECTOR_ADDR sectorAddr, PSectorInfo pInfo)
{
    BOOL    bRet = TRUE;


    //  Chip enable
    NF_CE_L();
	NF_CLEAR_RB();

    //  Write the command
    //  First, let's point to the spare area
    NF_CMD(CMD_READ2);
    NF_CMD(CMD_WRITE);

    //  Write the address
    NF_ADDR(0x00);
    NF_ADDR(sectorAddr & 0xff);
    NF_ADDR((sectorAddr >> 8) & 0xff);

    if (NEED_EXT_ADDR) {
        NF_ADDR((sectorAddr >> 16) & 0xff);
    }

    //  Now let's write the SectorInfo data
    //
    //  Write the first reserved field (DWORD)
    NF_DATA_W4( pInfo->dwReserved1 );

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

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

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

    //  Issue the write complete command
    NF_CMD(CMD_WRITE2);

    //  Check ready bit
	NF_DETECT_RB();	 // Wait tR(max 12us)

    //  Check the status of program
    NF_CMD(CMD_STATUS);

    if(NF_DATA_R() & STATUS_ERROR) {
     Uart_Printf("NAND_WriteSectorInfo() ######## Error Programming page %d!\n", sectorAddr);
        bRet = FALSE;
    }

    NF_CE_H();

    return bRet;
}




//***********************************************************************
/*static void InputTargetBlock(void)
{
    Uart_Printf("\nSource size:0h~%xh\n",downloadProgramSize);
    Uart_Printf("\nAvailable target block number: 0~4095\n");
    Uart_Printf("Input target block number:");
    //targetBlock=GetInputNum();	// Block number(0~4095)
    targetBlock = Uart_GetIntNum();	// Block number(0~4095)
    if(targetSize==0)
    {
    	Uart_Printf("\nInput target size(0x4000*n):");
    	targetSize=Uart_GetIntNum();	// Total byte size
    }
}*/

//********************************************************************
static int NF_ReadPage(U32 block,U32 page,U8 *buffer)
{
    int i;
    unsigned int blockPage;
    U8 ecc0,ecc1,ecc2;
    U8 *bufPt=buffer;
    U8 se[16];	   
    
    page=page&0x1f;
    blockPage=(block<<5)+page;
    NF_RSTECC();   // Initialize ECC
    NF_MECC_UnLock();

    NF_CE_L();  
	NF_CLEAR_RB();

    NF_CMD(0x00);   // Read command
    NF_ADDR(0);	    // Column = 0
    NF_ADDR(blockPage&0xff);	    //
    NF_ADDR((blockPage>>8)&0xff);   // Block & Page num.
    NF_ADDR((blockPage>>16)&0xff);  //

    for(i=0;i<10;i++); //wait tWB(100ns)/////??????
    
    NF_WAITRB();    // Wait tR(max 12us)
    for(i=0;i<512;i++)
    {
    	*bufPt++=NF_DATA_R();	// Read one page
    }

}

//**********************************************************************
BOOL IsBlockBad(BLOCK_ID blockID)
{
    DWORD   dwPageID = blockID << 5;
    BOOL    bRet = FALSE;
    BYTE    wFlag;

    //GRABMUTEX();

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

    //  Issue the command
    NF_CMD(CMD_READ2);

    //  Set up address
    NF_ADDR(VALIDADDR);
    NF_ADDR((dwPageID) & 0xff);
    NF_ADDR((dwPageID >> 8) & 0xff);

    if (NEED_EXT_ADDR) {
        NF_ADDR((dwPageID >> 16) & 0xff);
    }

    //  Wait for Ready bit
	NF_DETECT_RB();	 // Wait tR(max 12us)

    //  Now get the byte we want
    wFlag = (BYTE) NF_DATA_R();

  //  if(wFlag != 0xff) {
    if(wFlag != 0xff) {
        bRet = TRUE;
    }

    //  Disable the chip
    NF_CE_H();

   // RELEASEMUTEX();
    return bRet;
}

//**********************************************************************
char FMD_EraseBlock(BLOCK_ID blockID)
{

    BOOL    bRet = TRUE;
    DWORD   dwPageID = blockID << 5;
		//Uart_Printf("FMD_EraseBlock::::::1 \r\n");



/*#ifndef NOSYSCALL
	if(blockID < IMAGE_START_BLOCK)
	{
		bRet = FALSE;
		Uart_Printf("\nFMD_EraseBlock continue\n");
		//RELEASEMUTEX();
		return bRet;
	}
#endif*/


    //  Enable the chip
    NF_CE_L();
    //Uart_Printf("FMD_EraseBlock::::::2 \r\n");
	NF_CLEAR_RB();
//Uart_Printf("FMD_EraseBlock::::::3 \r\n");
    //  Issue command
    NF_CMD(CMD_ERASE);
//Uart_Printf("FMD_EraseBlock::::::4 \r\n");
    //  Set up address
    NF_ADDR((dwPageID) & 0xff);
    NF_ADDR((dwPageID >> 8) & 0xff);
//Uart_Printf("FMD_EraseBlock::::::5 \r\n");
    if (NEED_EXT_ADDR) {
        NF_ADDR((dwPageID >> 16) & 0xff);
    }

    //  Complete erase operation
    NF_CMD(CMD_ERASE2);
//Uart_Printf("FMD_EraseBlock::::::6 \r\n");
    //  Wait for ready bit
	NF_DETECT_RB();	 // Wait tR(max 12us)
//Uart_Printf("FMD_EraseBlock::::::7 \r\n");
    //  Check the status
    NF_CMD(CMD_STATUS);
//Uart_Printf("FMD_EraseBlock::::::8 \r\n");
    if(NF_DATA_R() & STATUS_ERROR) {
        Uart_Printf("######## Error Erasing block %d!\n", blockID);
        bRet = FALSE;
    }

    NF_CE_H();


    return bRet;
   
}


//***********************************************************************
BOOL FMD_WriteSector(SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff, PSectorInfo pSectorInfoBuff,
                        DWORD dwNumSectors)
{
    DWORD   i;
    BOOL    bRet = TRUE;
    DWORD   dwECCVal;
    BYTE    eccBuf[4];
		//Uart_Printf("FMD_WriteSector::::::1 \r\n");

    if((!pSectorBuff && !pSectorInfoBuff) || dwNumSectors != 1) {
//#ifdef BOOT_LOADER
        Uart_Printf("Invalid parameters!\r\n");
//#else
//       RETAILMSG(1, (TEXT("Invalid parameters!\n")));
//#endif
//#ifndef NOSYSCALL
//        SetLastError(ERROR_INVALID_PARAMETER);
//#endif
        return FALSE;
    }
	//Uart_Printf("FMD_WriteSector::::::2 \r\n");
	NF_Reset();

    if(!pSectorBuff) {
        //  If we are asked just to write the SectorInfo, we will do that separately
        bRet = NAND_WriteSectorInfo(startSectorAddr, pSectorInfoBuff);
        Uart_Printf("FMD_WriteSector::::::3 \r\n");
		return bRet;			// Do not write the actual sector information...
    }

    //GRABMUTEX();

    //  Initialize ECC register
    NF_RSTECC();
	NF_MECC_UnLock();

    //  Enable Chip
    NF_CE_L();

    //  Issue command
    NF_CMD(CMD_READ);
    NF_CMD(CMD_WRITE);

    //  Setup address
    NF_ADDR(0x00);
    NF_ADDR((startSectorAddr) & 0xff);
    NF_ADDR((startSectorAddr >> 8) & 0xff);

    if (NEED_EXT_ADDR) {
        NF_ADDR((startSectorAddr >> 16) & 0xff);
    }

    //  Special case to handle un-aligned buffer pointer.
    //
    if( ((DWORD) pSectorBuff) & 0x3) {
        //  Write the data
        for(i=0; i<SECTOR_SIZE; i++) {
            NF_DATA_W(pSectorBuff[i]);
        }
    }

⌨️ 快捷键说明

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