裸机跑nand flash.可以在原本为FF的地方写入,读出。但再次往相同地方写入时就写不正确,只有原来为‘1’的bit改写成功。例如原本写入了0xef(1110 1111),可以改为0xab(1010 1011),要改为0xcd(1100 1101)就失败了,变成了0x89(1000 1001);求大神解答!
芯片是s5pv210,K9K8G08U0B
程序如下: 自己写的裸机程序,下面的是nand flash 部分。
#define u32 vola
tile unsigned long
//-->For nand flash register address
#define MP0_3con *((u32*)0xe0200320)
#define MP0_1con *((u32*)0xe02002e0)
#define
NFCONF *((u32*)0xb0e00000)
#define NFCONT *((u32*)0xb0e00004)
#define NFCMD *((u32*)0xb0e00008)
#define NFDATA *((volatile unsigned char*)0xb0e00010)
#define NFADDR *((u32*)0xb0e0000c)
#define NFSTAT *((u32*)0xb0e00028)
//--<For nand flash register address
#define tacls 4
#define twrph0 3
#define twrph1 2
#define NF_en_on NFCONT &= ~(1<<1) //enable nand flash chip select
#define NF_en_off NFCONT |= (1<<1) //disable nand flash chip select
//---->For uart put char&str
#define UTRSTAT0 *((volatile unsigned long*)0xE2900010)
#define UTXH0 *((volatile unsigned long*)0xE2900020)
void put_char(char c)
{
while(!(UTRSTAT0 & (1 << 1))) ; //绛夊緟涓插彛缂撳瓨绌洪棽
if((UTRSTAT0 & (1<<1))==(1<<1)) //濡傛灉绌洪棽锛屽垯杩涘叆瀛楃鎵撳嵃
{
while(!(UTRSTAT0 & (1 << 1))) ;//绛夊緟绌洪棽
UTXH0 = c; //鍚戠紦瀛樺彂閫佸瓧绗? while(!(UTRSTAT0 & (1 << 1))) ;//绛夊緟绌洪棽
}
}
void put_str(char *p)
{
int i;
for(i=0;*(p+i);i++) //濡傛灉*(p+i)涓嶆槸' '锛屽垯鎵撳嵃瀛楃
{
put_char(p[i]);
}
}
//----<For uart put char&str
void put_hex(u32 reg,char b)
{
int i ;
char c;
for(i=b-1;i>=0;i--)
{
c=(reg>>(4*i))&0xf;
if(c<10)
{c +=0x30; put_char(c);}
else
{c +=0x37; put_char(c);}
}
put_str(" ");
}
void NF_init()
{
MP0_3con &= ~0xfffff;
MP0_3con |= 0x22222; //GPIO澶嶇敤锛岄€変负nand flash
MP0_1con &= ~(0xf<<8);
MP0_1con |= (0x3<<8);
NFCONF = (tacls<<12)|(twrph0<<8)|(twrph1<<4)|(1<<3)|(1<<1); //MLCFlash,5 address cycles
NFCONT &= ~(1<<16);
NFCONT |= (1<<0); //LOCK:disable lock,enable NF controller
NF_en_on; //enable nand flash chip select
NFCMD = 0xff; //reset nand flash
while (!(NFSTAT & (1<<4))); //if bit [4] = 0.busy
NFSTAT |= (1<<4);
NF_en_off; //disable nand flash chip select
}
void read_id()
{
char id[6];
int i;
NF_en_on;
NFCMD = 0x90 ; //鍙戦€?read ID鎸囦护
for(i=0;i<5;i++);
NFADDR = 0X00; //鍙戦€?ID鍦板潃
for(i=0;i<5;i++);
for(i=0;i<6;i++)
{
id[i]=NFDATA;
}
for(i=0;i<6;i++) //鎵撳嵃ID
{
put_hex(id[i],4);
}
NF_en_off;
}
void erase_addr(u32 addr) //鍧楁摝闄ゅ湴鍧€澶勭悊
{
NFADDR=(addr>>11)&0x7f;
NFADDR=(addr>>19)&0xff;
NFADDR=(addr>>27)&0xff;
}
void nf_addr(u32 addr) //鍐欏叆璇诲嚭鍦板潃澶勭悊
{
NFADDR=(addr & 0xff);
NFADDR=(addr>>8)&0x7;
NFADDR=(addr>>11)&0x7f;
NFADDR=(addr>>19)&0xff;
NFADDR=(addr>>27)&0x7;
}
void block_erase(u32 addr)
{
int i;
NF_en_on;
NFCMD = 0x60; //鍧楁摝闄ゆ寚浠?
erase_addr(addr);//鎿﹂櫎鍦板潃
NFCMD = 0xD0;//鍧楁摝闄?ed cycle 鎸囦护
for(i=0;i<3;i++);//寤舵椂
while (!(NFSTAT & (1<<4)));
NFSTAT |= (1<<4);
NFCMD = 0x70;
if(NFDATA & 0X01) //瀵熺湅鏄惁鎿﹂櫎鎴愬姛
put_str("erase fail ");
else
put_str("erase successful ");
NF_en_off;
}
void write_NF(u32 addr)
{
int i;
NF_en_on;
NFCMD= 0x80;
nf_addr(addr);
for(i=0;i<8;i++)
{
NFDATA = 0x84;
put_hex(NFDATA,4);
}
NFCMD = 0x10;
while (!(NFSTAT & (1<<4)));
NFSTAT |= (1<<4);
for(i=0;i<100;i++);
NFCMD = 0x70;
if(NFDATA & 0X01) //鏌ョ湅鏄惁鍐欏叆鎴愬姛
put_str("write fail ");
else
put_str("write successful ");
NF_en_off;
}
void read_NF(u32 addr)
{
int i;
char read_data[8192];
NF_en_on;
NFCMD = 0x00;
nf_addr(addr);
NFCMD = 0x30;
while (!(NFSTAT & (1<<4)));
NFSTAT |= (1<<4);
for(i=0;i<8;i++)
{
read_data[i] = NFDATA;
put_hex(read_data[i],4);
}
NF_en_off;
}
int main()
{
NF_init();
read_id();
block_erase(0x101000500);
write_NF(0x10100500);
read_NF(0x10100500);
put_str("end of nand_flash check ");
while(1);
}
----------------
每次写之前都进行擦除操作
一周热门 更多>