📄 drv_nandflash.c
字号:
----------------
#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 + -