Board logo

标题: 51读写nandflash例程 [打印本页]

作者: linuxarm    时间: 2006-6-22 20:27     标题: 51读写nandflash例程

下面是CYPRESS 68013上的一个读写samsung K9F1G的例子程序,


说明:程序针对mcu:cypress 68013,flash:samsung k9f1g08u,MCU运行于48M,对于其它频率,一些时序常数可能需要修改.程序实现了FLASH的CLEAR,WRITE,READ基本操作.


/******************************************************************/
/*AC Timing Characteristics define for Command / Address / Data Input
/*for cpu frequency 48MHZ,
/******************************************************************/


#define TDS 130
#define TDH 125
#define TWHR 300
/******************************************************************/


//IO PORT MAP


#define POW_LED PD1
#define RUN_LED PD2


//flash control line map
#define SIG_CEn PA4 //o
#define SIG_WEn PA1 //o
#define SIG_REn PA5 //o
#define SIG_CLEp PA3 //o
#define SIG_ALEp PA2 //o
#define SIG_RB PA6 //i
#define SIG_WP PA0 //o
#define SIG_DATA IOB //data bus
#define SIG_DATA_DIR OEB
#define SIG_CON_DIR OEA
#define SIG_LED_DIR OED
#define init_con_io() {SIG_CON_DIR=0xbf;SIG_WP=0x1;SIG_LED_DIR=0XFF;}


/*some macro define


#define LATCH_DATA(LATCH,dataa) {if(LATCH){SIG_DATA_DIR=0xff;SIG_DATA=dataa;}\
else {SIG_DATA_DIR=0x00;dataa=SIG_DATA;}}
#define SIG_INVALIDATE() {SIG_CEn=SIG_WEn=SIG_REn=HIGH;\
SIG_CLEp=SIG_ALEp=LOW; }
#define SIGNAL_SETUP(x) {unsigned char i;for(i=x;i>0;i--)_nop_( );}
#define SIGNAL_HOLD(x) {unsigned char i;for(i=x;i>0;i--)_nop_( );}


/******************************************************************/
/*function: a Command Latch Cycle
/*input: comm: commamd no.
/******************************************************************/
void ss_comm_latch(unsigned char comm,unsigned char wait)
{
SIG_ALEp=SIG_CEn=SIG_WEn=LOW;
SIG_CLEp=HIGH;
SIG_REn=HIGH;
LATCH_DATA(1,comm);
SIGNAL_SETUP(TDS); //tds
SIG_WEn=HIGH;
if(wait)while(SIG_RB);
SIGNAL_HOLD(TDH); //tdh
SIG_INVALIDATE();


}
/******************************************************************/
/*function: Address Latch Cycle
/*input: addr: addr no.
/******************************************************************/
void ss_addr_latch(unsigned char addr)
{
SIG_CLEp=SIG_CEn=SIG_WEn=LOW;
SIG_ALEp=SIG_REn=HIGH;
LATCH_DATA(1,addr);
SIGNAL_SETUP(TDS); //tals
SIG_WEn=HIGH;
SIGNAL_HOLD(TDH); //twh
SIG_INVALIDATE();


}
/******************************************************************/
/*function: Input Data Latch Cycle
/*input: dat: input DATA
/******************************************************************/
void ss_data_latch(unsigned char dat)
{
SIG_ALEp=SIG_CLEp=SIG_CEn=SIG_WEn=LOW;
SIG_REn=HIGH;
LATCH_DATA(1,dat);
SIGNAL_SETUP(TDS); //tds tcs
SIG_WEn=HIGH;
SIGNAL_HOLD(TDH); //tdh,tch
SIG_INVALIDATE();


}
/******************************************************************/
/*function: Serial Access Cycle after Read
/*input: wait: if wait R/B pin
/******************************************************************/
unsigned char ss_serial_acess(unsigned char wait)
{
unsigned char rddata;
if(wait)
while(!SIG_RB); //trr
SIG_CLEp=SIG_ALEp=SIG_REn=SIG_CEn=LOW;
SIG_WEn=HIGH;
SIGNAL_SETUP(TDS); //trea
LATCH_DATA(0,rddata);
SIG_REn=HIGH;
SIGNAL_HOLD(TDH); //treh
SIG_INVALIDATE();
return rddata;
}
/******************************************************************/
/*function: Status Read Cycle
/*input: wait: if wait R/B pin
/******************************************************************/


作者: linuxarm    时间: 2006-6-22 20:28

unsigned char ss_status_read(unsigned char wait)
{
unsigned char rddata;
if(wait)
while(!SIG_RB);
ss_comm_latch(0x70,0);
SIG_CLEp=SIG_CEn=LOW;
SIGNAL_SETUP(TDS); //tclr
SIG_REn=LOW;
SIGNAL_SETUP(TDS); //trea
LATCH_DATA(0,rddata);
SIG_REn=HIGH;
SIGNAL_HOLD(TDH); //trhz
SIG_INVALIDATE();
return rddata;
}

/******************************************************************/
/*function: erase flash
/*input: addrH: flash row address,16 bit width refer to datasheet
/*return: I/O status
/* I/O No. Page Program Block Erase Cache Prorgam Read Definition
/* I/O 0 Pass/Fail Pass/Fail Pass/Fail(N) Not use Pass : "0" Fail : "1"
/* I/O 1 Not use Not use Pass/Fail(N-1) Not use Pass : "0" Fail : "1"
/* I/O 2 Not use Not use Not use Not use "0"
/* I/O 3 Not Use Not Use Not Use Not Use "0"
/* I/O 4 Not Use Not Use Not Use Not Use "0"
/* I/O 5 Ready/Busy Ready/Busy True Ready/Busy Ready/Busy Busy : "0" Ready : "1"
/* I/O 6 Ready/Busy Ready/Busy Ready/Busy Ready/Busy Busy : "0" Ready : "1"
/* I/O 7 Write Protect Write Protect Write Protect Write Protect Protected: "0" Not Protected:"1"
/******************************************************************/

unsigned char flash_erase(unsigned int addrH)
{
ss_comm_latch(0x60,0);
ss_addr_latch(LOWBYTE(addrH));
ss_addr_latch(HIGHBYTE(addrH));

ss_comm_latch(0xd0,1); //twb
return ss_status_read(1); //status is 0x60h(write protect is set)/0xe0h(non wp) is good
}

/******************************************************************/
/*function: read flash
/*input: addrH: flash row address,16 bit width refer to datasheet
/* addrL: flash column address,12 bit width
/* databuf: out data buffer pointer
/* buflen: unsigned char num from flash
/******************************************************************/
unsigned char flash_read_PAG(unsigned int addrH,
unsigned int addrL,
unsigned char *databuf,
unsigned int buflen)
{
ss_comm_latch(0x00,0);
ss_addr_latch(LOWBYTE(addrL));
ss_addr_latch(HIGHBYTE(addrL));
ss_addr_latch(LOWBYTE(addrH));
ss_addr_latch(HIGHBYTE(addrH));

ss_comm_latch(0x30,1); //twb+tr
for(;buflen>0;buflen--,databuf++)
*databuf=ss_serial_acess(1);
return TRUE;
}

/******************************************************************/
/*function: write flash
/*input: addrH: flash row address,16 bit width refer to datasheet
/* addrL: flash column address,12 bit width
/* databuf: data buffer pointer
/* buflen: unsigned char num to flash
/******************************************************************/

unsigned char flash_write_PAG(unsigned int addrH,
unsigned int addrL,
unsigned char* databuf,
unsigned int buflen,
{
ss_comm_latch(0x80,0);
ss_addr_latch(LOWBYTE(addrL));
ss_addr_latch(HIGHBYTE(addrL));
ss_addr_latch(LOWBYTE(addrH));
ss_addr_latch(HIGHBYTE(addrH));

for(;buflen>0;buflen--,databuf++)
ss_data_latch(*databuf);
ss_comm_latch(0x10,1); //twb+tprog
return ss_status_read(1);
}
io MAP已经补充,

SIGNAL_HOLD,//确保信号保持时间

SIGNAL_SETUP,//确保信号建立时间

SIG_INVALIDATE(); //System Interface Using CE don’t-care.






欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0