📄 drv_nf.c
字号:
//---------------------------------------------------------------------------------
//
// Copyright (C) SEIKO EPSON CORP. 2004
//
// GROUP : SEE LSI
// FILE : drv_nf.c
// MODULE : nand flash
// Function description : all the operation of nand flash
// Revision history :
// Date userName Description
// 2004/02/20 Stella start
//
// Notes :
//
//---------------------------------------------------------------------------------
//---------------------------------------------------------------------------------
// Include files (#include)
//---------------------------------------------------------------------------------
#include "drv_nf.h"
//---------------------------------------------------------------------------------
// Global & static variables
//---------------------------------------------------------------------------------
static unsigned char write_buf[1024];
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;
//static unsigned int ulOldPA;
//static unsigned int tmp_buf[256];
//static unsigned int p;
//---------------------------------------------------------------------------------
// Function name :fnSMC_Reset
// Function description :reset 8 bit smc card
//
// Parameters
// Input :void
// Output :void
// I/O :void
//
// Return value :void
//
// Global variable :void
//---------------------------------------------------------------------------------
void fnSMC_Reset(void){
int i;
SET_CLE_H; /*set CLE H*/
SET_SMC_CE_L; /*set SMC CE L*/
*(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<800; i++) {
asm("nop");
}
SET_SMC_CE_H; /*set SMC CE H*/
return;
}
//---------------------------------------------------------------------------------
// Function name : fnFlash_Reset
// Function description : reset 16 bit nand flash
//
// Parameters
// Input :void
// Output :void
// I/O :void
//
// Return value :void
//
// Global variable :void
//---------------------------------------------------------------------------------
void fnFlash_Reset(void){
int i;
SET_CLE_H; /*set CLE H*/
*(volatile unsigned short*)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<800; i++) {
asm("nop");
}
return;
}
//---------------------------------------------------------------------------------
// Function name : fnSMC_Init
// Function description : inital 8 bit smc
//
// Parameters
// Input :void
// Output :void
// I/O :void
//
// Return value :void
//
// Global variable :void
//---------------------------------------------------------------------------------
void fnSMC_Init(void){
/*select ALE, CLE port as output*/
SET_ALE_L;
SET_ALE_OUTPUT;
SET_CLE_L;
SET_CLE_OUTPUT;
/*select CE14 data is high (P54)*/
SET_SMC_CE_H;
/*select CE as output*/
SET_SMC_CE_OUTPUT;
/*select CE/GPIO port function as GPIO*/
SET_SMC_CE_GPIO;
/*set flash device mode*/
SET_DEVICE_8;
/* Keep CE15 high when SMC operate*/
/*select CE15,16 data is high (P51)*/
SET_NAND_CE_H;
/*select CE as output*/
SET_NAND_CE_OUTPUT;
/*select CE/GPIO port function as GPIO*/
SET_NAND_CE_GPIO;
/*select NAND flash/SMC map to area 15 */
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;
fnSMC_Reset();
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_CE;
/*select CE as output*/
SET_NAND_CE_OUTPUT;
/* set flash device mode*/
SET_DEVICE_16;
/*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;
//fnFlash_Reset();
return;
}
//---------------------------------------------------------------------------------
// Function name : fnSMC_PageRead
// Function description : page read function of smc 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 fnSMC_PageRead(unsigned long ulAddress, unsigned char* pReadData){
unsigned short colAddr,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
colAddr=(unsigned short)(ulAddress & 0x000000ff); /* A7-0 */
pageAddr=(unsigned short)((ulAddress & 0x0001fe00)>>9); /* A16-9 */
blockAddrL=(unsigned short)((ulAddress & 0x01fe0000)>>17); /* A24-17 */
blockAddrH=(unsigned short)((ulAddress & 0x0e000000)>>25); /* A27-25 */
SET_CLE_H; /* set CLE H */
SET_SMC_CE_L; /* set SMC CE L */
*(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=colAddr; /* 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*/
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++){
*pReadBuf=*(volatile unsigned char*)NAND_Flash_BASE_ADDRESS;
pReadBuf++ ;
}
#ifdef ECC
DIS_ECC;
/* read redundant data*/
getRedt = pReadBuf;
for (Cnt=0; Cnt< 6; Cnt++){
* pReadBuf++ = *(volatile unsigned char*)NAND_Flash_BASE_ADDRESS;
}
#endif
SET_SMC_CE_H; /*set SMC CE H */
#ifdef ECC
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
return FLASH_SUCCESS;
}
//---------------------------------------------------------------------------------
// 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 colAddr,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
colAddr=(unsigned short)(ulAddress & 0x000000ff); /* A7-0 */
pageAddr=(unsigned short)((ulAddress & 0x0001fe00)>>9); /* A16-9 */
blockAddrL=(unsigned short)((ulAddress & 0x01fe0000)>>17); /* A24-17 */
blockAddrH=(unsigned short)((ulAddress & 0x0e000000)>>25); /* A27-25 */
SET_CLE_H; /* set CLE H*/
*(volatile unsigned short*)NAND_Flash_BASE_ADDRESS=READ_MODE1_CMD; /* read mode 1 */
SET_CLE_L; /*set CLE low */
SET_ALE_H; /*set ALE h*/
*(volatile unsigned short*)NAND_Flash_BASE_ADDRESS=colAddr; /* send col address */
*(volatile unsigned short*)NAND_Flash_BASE_ADDRESS=pageAddr; /* send page address*/
*(volatile unsigned short*)NAND_Flash_BASE_ADDRESS=blockAddrL; /* send block l address*/
*(volatile unsigned short*)NAND_Flash_BASE_ADDRESS=blockAddrH; /* send block h address*/
SET_ALE_L; /*set ALE 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");
asm("nop");
do{}
while (!CHECK_BUSY); /*wait R/#B to high*/
#ifdef ECC
RESET_ECC;
EN_ECC;
#endif
for (Cnt=0; Cnt< 256; Cnt++){
*(volatile unsigned short*)pReadBuf=*(volatile unsigned short*)NAND_Flash_BASE_ADDRESS;
pReadBuf+=2;
}
#ifdef ECC
DIS_ECC;
/*read redundant data */
getRedt = pReadBuf;
for (Cnt=0; Cnt< 3; Cnt++){
*(volatile unsigned short*)pReadBuf=*(volatile unsigned short*)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
return FLASH_SUCCESS;
}
//---------------------------------------------------------------------------------
// Function name : fnSMC_PageRead_DMA
// Function description : read page data from smart media card by DMA
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -