📄 lpc2200nand.c
字号:
/**************************************************************************
* FILENAME: lpc2200Nand.c *
* *
* VERSION: V1.0 *
* *
* DESCRIPTION: NXP LPC2200 interface to NAND flash reference design *
* Pls. refer to corresponding application notes for *
* Hardware design. *
* *
* TOOLS: ARM Developer Suite v1.2 *
* Flash Magic V3.33.157 *
* *
* *
* REVISION HISTORY *
* Version Author Date Remarks *
* 1.0 Xiaodong Xie 12/12/2006 Created *
***************************************************************************/
/**
* @file
* These NAND flash control routines are designed to provide the
* application programmer with a hardware dependent and hardware independent
* interface for the communication with NAND flash.
*
* The NAND flash control routines perform the following functions:
* Initialization of the LPC2200 interface to NAND flash
* read NAND flash manufacture & device ID
* NAND flash block earse
* NAND flash page write
* NAND flash page read
* read NAND flash status register
* reset NAND flash
* NAND flash copy back
*/
#include "LPC2294.h"
#include "lpc2200nand.h"
//***************************************************************************
//* Name: nandFlashInit
//* Input(s) : none.
//* Returns : none.
//* Description : initialize LPC2294 interface to x8 NAND flash
//***************************************************************************
void nandFlashInit(void)
{
//Configure Bank0 as Nand Flash controller
PINSEL2 = PINSEL2
& ( ~(0x3<<26) )
| ( 1<<25 ) //enable Addr2 as NAND flash ALE
//enable Addr3 as NAND flash CLE
| ( 1<<8 ) //enable WE
& ( ~( 0x3<<4 ) )
| ( 1<<4 ); //enable CS0, OE, D0...D7, D8...D15
BCFG0 = (( 0<<28 ) //8bit width of data bus
| ( 0x0<<11 ) //1 CCLK cycle write
| ( 1<<10 )
| ( 0x1<<5 ) //4 CCLK cycle read
| ( 0x0 )); //1 CCLK cycle idle
//GPIO P019 as CS pin,P018 as Busy Status pin
PINSEL1 &= ( ~0xf0 );
IO0DIR = IO0DIR
| ( 1<<19 ) //P019 configured as output pin
& ( ~( 1<<18 ) ); //P018 configured as input pin
}
//***************************************************************************
//* Name: nandFlashReadID
//* Input(s) : none.
//* Returns : unsigned int Id.
//* Description : Read x8 NAND flash manufacturer ID and device ID
//***************************************************************************
unsigned int nandFlashReadID( void )
{
unsigned int Id, TimeoutCounter = 0;
nandOpen();
nandWr_Cmd( NAND_CMD_RD_ID );
nandWr_Addr( 0 );
//read ID consume at less 20nS
while ( ( !nandRd_ReadyBusy() ) && ( TimeoutCounter < 10 ) )
TimeoutCounter++;
if( TimeoutCounter >= 11 )
return 0;
Id = nandRd_Data() << 8;
Id |= nandRd_Data();
nandClose();
return Id;
}
//***************************************************************************
//* Name: nandFlashBlockErase
//* Input(s) : unsigned int NandAddr.
//* Returns : unsigned char NandStatus.
//* Description : x8 NAND flash block erase
//* Notes: NandAddr
//* A0 - A7 column address
//* A8 low/high half page selection for x8 device
//* A9 - A16 low block address
//* A17 - A24 high block address
//***************************************************************************
unsigned char nandFlashBlockErase( unsigned int NandAddr )
{
unsigned char NandStatus = 0x0;
nandOpen();
nandWr_Cmd( NAND_CMD_BLOCKERASE_I );
nandWr_Addr( ( unsigned short ) ( ( NandAddr >> 9 ) & 0xff) ); //low block address
nandWr_Addr( ( unsigned short ) ( ( NandAddr >> 17 ) & 0xff) ); //high block address
nandWr_Cmd( NAND_CMD_BLOCKERASE_II );
//read NAND status register
nandWr_Cmd( NAND_CMD_RD_STATUS );
do
{
NandStatus = nandRd_Data();
}while(!(NandStatus & 0x40));
nandWr_Cmd( NAND_CMD_RD_DONE );
nandClose();
return NandStatus;
}
//***************************************************************************
//* Name: nandFlashPageWrite
//* Input(s) : unsigned int NandAddr.
//* unsigned char *buffer.
//* Returns : unsigned char NandStatus.
//* Description : x8 NAND flash page write.
//* Because we are using a x8 NAND, the data width is 8bit (unsigned char *Buffer).
//* *Buffer should contain 512 Bytes data and 16 Bytes ECC information
//* Notes: NandAddr
//* A0 - A7 column address
//* A8 low/high half page selection
//* A9 - A16 low block address
//* A17 - A24 high block address
//* *buffer
//* |-----from startcolumn----->|---------->| one page
//* data field spare field
//***************************************************************************
unsigned char nandFlashPageWrite( unsigned int NandAddr , unsigned char *Buffer )
{
unsigned char NandStatus = 0x0;
unsigned int i;
// for x8 NAND flash device, one page = 512 + 16 Bytes
unsigned short StartColumn = 528 - (NandAddr & 0x1ff);
nandOpen();
if ( ( NandAddr >> 8 ) & 0x1 )
{
nandWr_Cmd( NAND_CMD_AREA_B ); //begin from "B" half page
}
else
{
nandWr_Cmd( NAND_CMD_AREA_A ); //begin from "A" half page
}
nandWr_Cmd( NAND_CMD_PAGEPROG_I ); //program command 1st cycle with 80h
nandWr_Addr( ( unsigned short ) ( NandAddr & 0xff ) ); //column address
nandWr_Addr( ( unsigned short ) ( ( NandAddr >> 9 ) & 0xff) ); //low block address
nandWr_Addr( ( unsigned short ) ( ( NandAddr >> 17 ) & 0xff) ); //high block address
for ( i = 0; i < StartColumn; i++ )
nandWr_Data( Buffer[i] );
nandWr_Cmd( NAND_CMD_PAGEPROG_II );//confirm program with 10h
//read NAND status register
nandWr_Cmd( NAND_CMD_RD_STATUS );
//wait until write operation success
do
{
NandStatus = nandRd_Data();
}while(!(NandStatus & 0x40));
nandWr_Cmd( NAND_CMD_RD_DONE );
nandClose();
return NandStatus;
}
//***************************************************************************
//* Name: nandFlashPageRead
//* Input(s) : unsigned int NandAddr.
//* unsigned char *Buffer.
//* Returns : void
//* Description : x8 NAND flash page write
//* Because we are using a x8 NAND, the data width is 8bit (unsigned char *Buffer).
//* *Buffer should contain 512 Bytes data and 16 Bytes ECC information
//* Notes: NandAddr
//* A0 - A7 column address
//* A8 low/high half page selection
//* A9 - A16 low block address
//* A17 - A24 high block address
//* *buffer
//* |-----from startcolumn----->|---------->| one page
//* data field spare field
//***************************************************************************
void nandFlashPageRead( unsigned int NandAddr , unsigned char *Buffer )
{
unsigned char NandStatus;
unsigned short i;
// for x8 NAND flash device, one page = 512 + 16 Bytes
unsigned int StartColumn = 528 - (NandAddr & 0x1ff);
nandOpen();
if ( ( NandAddr >> 8 ) & 0x1 )
{
nandWr_Cmd( NAND_CMD_AREA_B ); //begin from "B" half page
}
else
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -