📄 nand_lpc.c
字号:
/*****************************************************************************
* nand.c: nand flash read and write
*
* Copyright(C) 2007, uCdragon
* All rights reserved.
*
* History
* 2007.03.16 lqm@ucdragon.net
*
******************************************************************************/
#include "nand_lpc.h"
//#ifdef NAND_FLASH_SUPPORT
typedef struct
{
uint32_t id;
uint32_t size;
}NFChipInfo;
static NFChipInfo NandFlashChip[] =
{
{0xec73, SIZE_16M}, {0xec75, SIZE_32M}, {0xec76, SIZE_64M},
{0xec79, SIZE_128M}, {0, 0},
};
static NFChipInfo * pNand = 0;
static uint8_t NandAddr;
#define READCMD0 0
#define READCMD1 1
#define READCMD2 0x50
#define ERASECMD0 0x60
#define ERASECMD1 0xd0
#define PROGCMD0 0x80
#define PROGCMD1 0x10
#define QUERYCMD 0x70
#define READIDCMD 0x90
#define RESETCMD 0xFF
#define NFWrCmd(cmd) *(volatile uint8_t *)NandFlash_CLE = (cmd)
#define NFWrAddr(addr) *(volatile uint8_t *)NandFlash_ALE = (addr)
#define NFWrDat(dat) *(volatile uint8_t *)NandFlash_DATA =(dat)
#define NFRdDat() *(volatile uint8_t *)NandFlash_DATA
static uint32_t NFWaitBusy( void )
{
uint8_t stat;
NFWrCmd(QUERYCMD) ;
do
{
stat = NFRdDat();
}
while ( !( stat & 0x40 ) ) ;
NFWrCmd(READCMD0) ;
return stat & 1 ;
}
static uint32_t NFReadID( void )
{
uint32_t id, loop = 0;
NFChipEn();
NFWrCmd( RESETCMD );
NFWrAddr( 0 );
// loop = 10000;
// while(loop--);
// Delay( 2 );
NFWrCmd( READIDCMD );
NFWrAddr( 0 );
while ( ( NFIsBusy() ) && ( loop < 10000 ) )
loop++;
if ( loop >= 10000 )
return 0;
id = NFRdDat() << 8;
id |= NFRdDat();
NFChipDs();
return id;
}
int NandInit( void )
{
#if 1 //NAND_FLASH_SUPPORT
EMC_STA_CFG1 = 0x00000080;
/* for NAND FLASH */
PINSEL0 &= ~(0xF << 20); //0.10,0.11 as gpio
FIO0DIR &= ~(1 << 10); //0.10 input
FIO0DIR |= 1 << 11; //0.11 output
//EMC_CONFIG = 0;//little endian
//EMC_STA_CFG1 = 0;//8 bit,buffer...disabled
//EMC_STA_WAITWEN1 = 0;
//EMC_STA_WAITOEN1 = 0;
EMC_STA_WAITRD1 = 8; //2 should be enough
EMC_STA_WAITWR1 = 8;
//EMC_CTRL = 1;//enable,no map,normal mode
#endif
printf("%s, %d\n",__FUNCTION__, __LINE__);
uint32_t id = NFReadID();
pNand = NandFlashChip;
while(pNand->id)
{
if(pNand->id == id) break;
pNand++;
}
if(!pNand->id) pNand = 0;
else
{
NandAddr = pNand->size >= SIZE_64M;
}
printf("NAND found ID = %08X\n", id);
IODIR0 = 0xffff0000;
IOCLR0 = 0xffff0000;
return id;
}
uint32_t NFEraseBlock( uint32_t addr )
{
uint8_t stat;
addr &= NAND_BLOCK_MASK;
NFChipEn();
NFWrCmd( ERASECMD0 );
NFWrAddr( addr );
NFWrAddr( addr >> 8 );
if ( NandAddr )
NFWrAddr( addr >> 16 );
NFWrCmd( ERASECMD1 );
stat = NFWaitBusy();
NFChipDs();
//printf( "Erase block 0x%08x %s\n" , addr , stat ? "fail" : "ok" );
return stat;
}
//addr = page address
void NFReadPage( uint32_t addr , uint8_t* buf )
{
uint16_t i;
NFChipEn();
NFWrCmd( READCMD0 );
NFWrAddr( 0 );
NFWrAddr( addr );
NFWrAddr( addr >> 8 );
if ( NandAddr )
NFWrAddr( addr >> 16 );
// InitEcc();
NFWaitBusy();
for ( i = 0; i < NAND_SECTOR_LEN; i++ )
buf[i] = NFRdDat();
NFChipDs();
}
//addr = page address
uint32_t NFWritePage( uint32_t addr , uint8_t* buf )
{
uint32_t i = NAND_SECTOR_LEN, stat;
while (NFIsBusy());
NFChipEn();
NFWrCmd( READCMD0 );
NFWrCmd( PROGCMD0 );
NFWrAddr( 0 );
NFWrAddr( addr );
NFWrAddr( addr >> 8 );
if ( NandAddr )
NFWrAddr( addr >> 16 );
// InitEcc();
while(i--)
NFWrDat( *buf++ );
NFWrCmd( PROGCMD1 );
stat = NFWaitBusy();
NFChipDs();
return stat;
}
//addr = page address
void NFReadoob( uint32_t addr , uint8_t* buf )
{
uint16_t i;
NFChipEn();
NFWrCmd( READCMD2 ); //0x50
NFWrAddr( 0 ); //0x00
NFWrAddr( addr ); //0x28
NFWrAddr( addr >> 8 ); //0x00
if ( NandAddr )
NFWrAddr( addr >> 16 ); //0x00
// InitEcc();
NFWaitBusy();
for ( i = 0; i < 16; i++ )
buf[i] = NFRdDat();
NFChipDs();
}
//#endif /* NAND_SUPPORT */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -