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

📄 drv_nandflash.c

📁 drive for nandflash on sansung corp.
💻 C
📖 第 1 页 / 共 2 页
字号:
----------------
#include "drv_nf.h"

//#define _16BIT_NAND_IF_

//---------------------------------------------------------------------------------
// Global & static variables
//---------------------------------------------------------------------------------

static unsigned char write_buf[528];
static unsigned short fls_ldcnt;			// 0~64
static unsigned char  checkSum;
static unsigned short databuf_cnt;		// 0~512
static unsigned long page_cnt;
static unsigned long  ulStAddr;

//---------------------------------------------------------------------------------
//  	Function name 		: fnFlash_PageRead
// 	Function description	: page read function of flash with ECC
//
//      Parameters
//         Input  		:unsigned long 	ulAddress  		page address
//         Output 		:unsigned char* pReadBuf		buf for store read data
//         I/O    		:void
//
//      Return value 		:unsigned char	FLASH_SUCCESS		read Success
//						FLASH_ECC_ERROR		ecc check error
//						FLASH_PAR_ERR		parameter error
//	Global variable 	:void
//---------------------------------------------------------------------------------
unsigned char fnFlash_PageRead(unsigned long ulAddress, unsigned char* pReadData){

	unsigned short colAddrL,colAddrH,pageAddr,blockAddrL,blockAddrH;
	unsigned char* getRedt;
	unsigned char* ECCRet;
	unsigned char* pReadBuf;
	int i, Cnt;

	pReadBuf = pReadData ;

	#ifdef	DEBUG
		/* check parameter */
		if  (ulAddress >=(MAX_BLK_NUM * MAX_PG_NUM * PG_SIZE))
			return FLASH_PAR_ERR;
	#endif

	colAddrL=(unsigned short)(ulAddress & 0x000000ff);            /*A7-0 */
//	colAddrH=(unsigned short)((ulAddress & 0x00000f00)>>8);       /*A11-8 */
  	pageAddr=(unsigned short)((ulAddress & 0x0001fe00)>>9) ;     /*A16-9*/
	blockAddrL=(unsigned short)((ulAddress & 0x0fe0000)>>17);    /*A23-17*/
//	blockAddrH=(unsigned short)((ulAddress & 0x10000000)>>28);    /*A28*/

	SET_NAND_CE_L;
  	SET_CLE_H;		/* set CLE H*/

	*(volatile unsigned char*)NAND_Flash_BASE_ADDRESS=READ_MODE1_CMD;	/* read mode 1 */

	SET_CLE_L;		/*set CLE low */
	SET_ALE_H;		/*set ALE h*/

	*(volatile unsigned char*)NAND_Flash_BASE_ADDRESS=colAddrL;		/* send col address*/
//	*(volatile unsigned char*)NAND_Flash_BASE_ADDRESS=colAddrH;		/* send col address*/
	*(volatile unsigned char*)NAND_Flash_BASE_ADDRESS=pageAddr;		/* send page address*/
	*(volatile unsigned char*)NAND_Flash_BASE_ADDRESS=blockAddrL;	/* send block l address*/
//	*(volatile unsigned char*)NAND_Flash_BASE_ADDRESS=blockAddrH;	/* send block h address*/

	SET_ALE_L;		/*set ALE L*/

//	SET_CLE_H;     /* set CLE H*/
//	*(volatile unsigned char*)NAND_Flash_BASE_ADDRESS = READ_ADV_CMD; /* adv read mode 1*/
//	SET_CLE_L;     /* set CLE low*/

  	asm("nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");
 	  asm("nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");
 	  asm("nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");
 	  asm("nop");
  	do{}
 	while (!CHECK_BUSY);		/*wait R/#B to high*/


	#ifdef ECC
		RESET_ECC;
		EN_ECC;
	#endif

  	for (Cnt=0; Cnt< 512; Cnt++){
  	        asm("nop");
  		*(volatile unsigned char*)pReadBuf++=*(volatile unsigned char*)NAND_Flash_BASE_ADDRESS;
                asm("nop");
                //pReadBuf+=1;
  	}

  	#ifdef ECC
		DIS_ECC;

		/*read redundant data */
		getRedt = pReadBuf;

 		for (Cnt=0; Cnt< 3; Cnt++){
  			*(volatile unsigned char*)pReadBuf=*(volatile unsigned char*)NAND_Flash_BASE_ADDRESS;
  			pReadBuf +=2;
  		}
		do{}
		while (!CHECK_ECC_READY);

		/*Compare ECC data*/
		ECCRet = ECC_AREA0_COL_ADDR;

		for (i=0; i<6; i++){
      			if (* ECCRet++ != * getRedt++)
        			return FLASH_ECC_ERROR;
	 	}
	#endif

	SET_NAND_CE_H;

	return FLASH_SUCCESS;

}

/***************************************************************************************************
 *      Name:           fnCheck_busy
 *      Type:           void
 *      Ret val:        void
 *
 *      Argument:
 *  Function :  delay 200ns(include set_cle_low or set_ale_low) then wait till flash R/#B =1
 *************************************************************************************************/
 void fnCheck_busy (void) {
 //wait R/#B to low
  asm("nop");
  asm("nop");
  asm("nop");
  asm("nop");
  asm("nop");
  asm("nop");
  asm("nop");
  asm("nop");
  asm("nop");
  asm("nop");
  asm("nop");
  asm("nop");
  asm("nop");
  asm("nop");
  asm("nop");
  asm("nop");
  asm("nop");
  asm("nop");
  asm("nop");
  asm("nop");
  asm("nop");
  //wait R/#B to high
        do{}
        while (!CHECK_BUSY);   //   #define CHECK_BUSY			(*(volatile unsigned char*)0x300f46 & 0x10 )
  asm("nop");
}

/***************************************************************************************************
 *      Name:           fnReset_flash
 *      Type:           void
 *      Ret val:        void
 *
 *      Argument:
 *  Function :  reset 8bit SM card(CE different)
 *************************************************************************************************/
 void fnReset_flash(void){
  int i;
  
	SET_NAND_CE_L;
        SET_CLE_H;              //set CLE H

        *(volatile unsigned char*)NAND_Flash_BASE_ADDRESS=RESET_CMD;    //write RESET command
        SET_CLE_L;              //set CE L

        //Wait flash R/#B ready (worst case 500us reset when erase; delay 1ms for safe)
  for (i=0; i<25000; i++) {
    asm("nop");
  }

	SET_NAND_CE_H;
        return;
 }


//---------------------------------------------------------------------------------
//  	Function name 		: fnFlash_Init
// 	Function description	: inital 16 bit nand flash
//
//      Parameters
//         Input  		:void
//         Output 		:void
//         I/O    		:void
//
//      Return value 		:void
//
//	Global variable 	:void
//---------------------------------------------------------------------------------

 void fnFlash_Init (void){

 	/*select ALE, CLE port as output*/
  	SET_ALE_L;
 	SET_ALE_OUTPUT;
 	SET_CLE_L;
 	SET_CLE_OUTPUT;

 	/* select CE15,16 data is high (P51)*/
 	SET_NAND_CE_H;
 	/*select CE/GPIO port function as CE*/
 	SET_NAND_CE_GPIO;
 	/*select CE as output*/
 	SET_NAND_CE_OUTPUT;

 	/* set flash device mode*/
#ifdef _16BIT_NAND_IF_
  	SET_DEVICE_16;
#else
	SET_DEVICE_8;
#endif	// _16BIT_NAND_IF_

 	/*select NAND flash/SMC map to area 15 and boot function*/
 	/*user can modify here for change boot mode*/
	SET_NAND_AREA;

 	/*select SMWE,SMRD port function as smart media I/F function */
 	CLR_SMIFREG;
 	SET_SMIF_WE;
 	SET_SMIF_RD;

 	/*set by/ry signal as input*/
 	SET_BUSY_INPUT;

 	/*disable write protect*/
 	SET_WP_H;
 	SET_WP_GPIO;

 	/*set wp pin as output	*/
 	SET_WP_OUTPUT;

        fnReset_flash();

 	return;

}

//---------------------------------------------------------------------------------
//  	Function name 		: fnFlash_PageWrite
// 	Function description	: write page data to SMC
//
//      Parameters
//         Input  		:unsigned long 	ulAddress  		page address
//         Output 		:unsigned char* pWriteBuf		buf for store write data
//         I/O    		:void
//
//      Return value 		:unsigned char	FLASH_SUCCESS		write Success
//						FLASH_ECC_ERROR		ecc check error
//						FLASH_PAR_ERR		parameter error
//						FLASH_WRITE_ERR		write error
//	Global variable 	:void
//---------------------------------------------------------------------------------
unsigned char fnFlash_PageWrite( unsigned long ulAddress, unsigned char* pWriteData){

	unsigned char  RetVal;
	unsigned char  ReadStatus;
	unsigned short colAddrL,colAddrH, pageAddr,blockAddrL,blockAddrH;
	unsigned short Cnt;
	unsigned char* ECCRet;
	unsigned char* Write_ECC;

	RetVal=FLASH_SUCCESS;

	#ifdef	DEBUG
		/* check parameter */
		if  (ulAddress >=(MAX_BLK_NUM * MAX_PG_NUM * PG_SIZE))
			return FLASH_PAR_ERR;
	#endif

	colAddrL=(unsigned short)(ulAddress & 0x000000ff);            /*A7-0 */
//	colAddrH=(unsigned short)((ulAddress & 0x00000f00)>>8);       /*A11-8 */
  	pageAddr=(unsigned short)((ulAddress & 0x0001fe00)>>9) ;     /*A16-9*/
	blockAddrL=(unsigned short)((ulAddress & 0x0fe0000)>>17);    /*A23-17*/
//	blockAddrH=(unsigned short)((ulAddress & 0x10000000)>>28);    /*A28*/


	SET_NAND_CE_L;
	SET_CLE_H;	/* set CLE high*/

	*(volatile unsigned char*)NAND_Flash_BASE_ADDRESS=AUTO_WRITE_CMD;/* write command*/

	SET_CLE_L;		/* set CLE low*/
	SET_ALE_H;		/* set ALE h*/

	*(volatile unsigned char*)NAND_Flash_BASE_ADDRESS=colAddrL;		/* send col address*/
//	*(volatile unsigned char*)NAND_Flash_BASE_ADDRESS=colAddrH;		/* send col address*/
	*(volatile unsigned char*)NAND_Flash_BASE_ADDRESS=pageAddr;		/* send page address*/
	*(volatile unsigned char*)NAND_Flash_BASE_ADDRESS=blockAddrL;	/* send block l address*/
//	*(volatile unsigned char*)NAND_Flash_BASE_ADDRESS=blockAddrH;	/* send block h address*/

	SET_ALE_L;		/*set ALE L*/


#ifdef ECC
	RESET_ECC;
	EN_ECC;
#endif

#ifdef _16BIT_NAND_IF_
  	for (Cnt=0; Cnt< 256; Cnt++)
	{
		*(volatile unsigned short*)NAND_Flash_BASE_ADDRESS= *(volatile unsigned short*)pWriteData;
		pWriteData+=2;
	}
#else
	for (Cnt=0; Cnt< 512; Cnt++)
	{
		*(volatile unsigned char*)NAND_Flash_BASE_ADDRESS= *(volatile unsigned char*)pWriteData;
		pWriteData++;
	}
#endif	// _16BIT_NAND_IF_

#ifdef ECC
		DIS_ECC;

		do{}
		while (!CHECK_ECC_READY);

  		/*Write ECC data to redundant area (first 6byte/3word)*/
  		ECCRet = ECC_AREA0_COL_ADDR;

  		Write_ECC = pWriteData;

  		for (Cnt=0; Cnt<6; Cnt++){
    			*Write_ECC ++ = * ECCRet ++;
  		}

#ifdef _16BIT_NAND_IF_
	  	for (Cnt=0; Cnt< 3; Cnt++){
	  		*(volatile unsigned short*)NAND_Flash_BASE_ADDRESS = *(volatile unsigned short*)pWriteData;
	  		pWriteData +=2;
	  	}
#else
	  	for (Cnt=0; Cnt< 6; Cnt++){
	  		*(volatile unsigned char*)NAND_Flash_BASE_ADDRESS = *(volatile unsigned char*)pWriteData;
	  		pWriteData +=1;
	  	}
#endif	// _16BIT_NAND_IF_

#endif	// ECC

	SET_CLE_H;	/* set CLE high*/
	*(volatile unsigned char*)NAND_Flash_BASE_ADDRESS=PAGE_WRITE_CMD;
	SET_CLE_L;	/*set CLE l*/


  	asm("nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");
 	asm("nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");
 	asm("nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");

⌨️ 快捷键说明

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