📄 nand.c
字号:
/* =========================== Flash_Erase ============================================ * Function: * 擦除nand flash中一块的数据 * Params: * page:被擦除块的起始页数 * ==================================================================================== */void Flash_Erase(unsigned long page){ unsigned int state; unsigned int ADD2, ADD3; ADD3=(unsigned int)((page<<16)>>24); ADD2=(unsigned int)((page<<24)>>24); Select(); CLE_H(); writeb(0x60, NANDADDR); /* Block Erase command (60h) */ CLE_L(); ALE_H(); writeb(ADD2, NANDADDR); writeb(ADD3, NANDADDR); ALE_L(); CLE_H(); writeb(0xd0, NANDADDR); /* Block Erase Confirm command (D0h) */ CLE_L(); while((readw(MBASS+PADAT)&0x4000)==0x0000) ; CLE_H(); writeb(0x70, NANDADDR); CLE_L(); state=readb(NANDADDR); NSelect(); if(state != 0xC0){ ADD2 = page >> 5; printf("\nNAND Flash Erase error at block %d, return %x\n", ADD2, state); }}/* =========================== Flash_Eraseall ============================================ * Function: * 擦除nand flash中所有的数据 * ==================================================================================== */void Flash_Eraseall(){ int i; printf("Erase Entire NAND now!"); for(i = 0; i < info_flash[2]; i++) { if((i % 80) == 0){ printf("\n"); } printf("."); Flash_Erase((unsigned long)i*(unsigned long)info_flash[3]); } printf("\nThe nand flash erase all block is ended.\n");}/* =========================== Flash_Displaybad ============================================ * Function: * 显示nand flash 中的坏块 * Return Value: * 1:坏块被检查过 0:坏块没有被检查 * ========================================================================================= */int Flash_Displaybad(){ char i; int x, y; union NandChange ch; memset(ch.b, 0, 4); memset(badinfo, 0x01, 2048); Flash_Pageread(0, 512); if(data[0]!=0x55) { printf("There is no information about bad block of nand flash. Please check it at first!!!\n"); return 0; } printf("In Nand Flash, the bad block information as follow:"); y=(int)data[1]; if(y==0) { printf("There is no bad block in the Nand flash!\n"); return 1; } if(y>32) y=32; for(i=0; i<y; i++) { ch.b[2]=data[2+i*2+1]; ch.b[3]=data[2+i*2]; x=ch.a; badinfo[x]=0x00; if(i%15==0) printf("\n"); printf("Block%d ", x); } printf("\n"); return 1;}/* =========================== Flash_Initialcheck ============================================ * Function: * 检查整个nand flash中的坏块,并初始化坏块表 * =========================================================================================== */void Flash_Initialcheck(){ unsigned int i, j; int m, n, k,l; char* paddr; char buffer[8]; union NandChange ch; paddr=(char*)__USER_SPACE; l=k=n=m=j=0; memset(buffer, 0, 8); memset(ch.b, 0, 4); i=Flash_Displaybad(); if(i==1) return; Flash_Readdata(0, 16384, (int)paddr); printf("Checking Flash!!! Please wait...\n"); for(i=0; i<info_flash[2]; i++) { if(Flash_Checkbad(i*info_flash[3])!=0x01) { printf("The bad block is %4x\n", i*info_flash[3]); badinfo[i]=0x00; info_flash[10]++; if(j<32) { ch.a=i; paddr[2+j*2]=ch.b[3]; paddr[2+j*2+1]=ch.b[2]; if((i>=LOGDBOFFSET)&&(i<CARDDBOFFSET)) //LogDb Partition: 6M--22M { ch.a=i-LOGDBOFFSET+1; paddr[66+2+2*m]=ch.b[3]; paddr[66+2+2*m+1]=ch.b[2]; if(ch.a>=LOGDBSIZE) { paddr[66+2+64+2*m]=0xff; paddr[66+2+64+2*m+1]=0xff; } m+=1; } if((i>=CARDDBOFFSET)&&(i<IDINDEXOFFSET)) //CardDb Partition: 22M--29M { ch.a=i-CARDDBOFFSET+1; paddr[196+2+2*n]=ch.b[3]; paddr[196+2+2*n+1]=ch.b[2]; if(ch.a>CARDDBSIZE) { paddr[196+2+64+2*n]=0xff; paddr[196+2+64+2*n+1]=0xff; } n+=1; } if((i>=IDINDEXOFFSET)&&(i<NUMINDEXOFFSET)) //ID index Partition: 29M--30.5M { ch.a=i-IDINDEXOFFSET+1; paddr[326+2+2*n]=ch.b[3]; paddr[326+2+2*n+1]=ch.b[2]; if(ch.a>IDINDEXSIZE) { paddr[326+2+64+2*n]=0xff; paddr[326+2+64+2*n+1]=0xff; } k+=1; } if((i>=NUMINDEXOFFSET)&&(i<2048)) //Number index Partition: 30.5M--32M { ch.a=i-NUMINDEXOFFSET+1; paddr[456+2+2*n]=ch.b[3]; paddr[456+2+2*n+1]=ch.b[2]; if(ch.a>NUMINDEXSIZE) { paddr[456+2+64+2*n]=0xff; paddr[456+2+64+2*n+1]=0xff; } l+=1; } } j++; } else badinfo[i]=0x01; } paddr[0]=0x55; paddr[1]=(char)info_flash[10]; paddr[456]=paddr[196]=paddr[66]=paddr[326]=0xAA; paddr[67]=(char)m; paddr[197]=(char)n; paddr[327]=(char)k; paddr[457]=(char)l; if(paddr[67]!=0x00) //LogDB { j=0; for(i=0; i<(int)(paddr[67]); i++) { ch.b[3]=paddr[66+2+2*i]; ch.b[2]=paddr[66+2+2*i+1]; if(ch.a<LOGDBSIZE) { //ch.a=LOGDBOFFSET+LOGDBSIZE+j; ch.a=LOGDBSIZE+2+j; m=ch.a; while((j<32)&&(badinfo[m]!=0x01)) { j++; //ch.a=LOGDBOFFSET+LOGDBSIZE+j; ch.a=LOGDBSIZE+2+j; m=ch.a; } paddr[66+2+64+2*i]=ch.b[3]; paddr[66+2+64+2*i+1]=ch.b[2]; j++; } } } if(paddr[197]!=0x00) //CardDB { j=0; for(i=0; i<(int)(paddr[197]); i++) { ch.b[3]=paddr[196+2+2*i]; ch.b[2]=paddr[196+2+2*i+1]; if(ch.a<CARDDBSIZE) { //ch.a=CARDDBOFFSET+CARDDBSIZE+j; ch.a=CARDDBSIZE+2+j; m=ch.a; while((j<32)&&(badinfo[m]!=0x01)) { j++; //ch.a=CARDDBOFFSET+CARDDBSIZE+j; ch.a=CARDDBSIZE+2+j; m=ch.a; } paddr[196+2+64+2*i]=ch.b[3]; paddr[196+2+64+2*i+1]=ch.b[2]; j++; } } } if(paddr[327]!=0x00) //ID index { j=0; for(i=0; i<(int)(paddr[327]); i++) { ch.b[3]=paddr[326+2+2*i]; ch.b[2]=paddr[326+2+2*i+1]; if(ch.a<IDINDEXSIZE) { ch.a=IDINDEXSIZE+2+j; m=ch.a; while((j<32)&&(badinfo[m]!=0x01)) { j++; ch.a=IDINDEXSIZE+2+j; m=ch.a; } paddr[326+2+64+2*i]=ch.b[3]; paddr[326+2+64+2*i+1]=ch.b[2]; j++; } } } if(paddr[457]!=0x00) //Number index { j=0; for(i=0; i<(int)(paddr[457]); i++) { ch.b[3]=paddr[456+2+2*i]; ch.b[2]=paddr[456+2+2*i+1]; if(ch.a<NUMINDEXSIZE) { ch.a=NUMINDEXSIZE+2+j; m=ch.a; while((j<32)&&(badinfo[m]!=0x01)) { j++; ch.a=NUMINDEXSIZE+2+j; m=ch.a; } paddr[456+2+64+2*i]=ch.b[3]; paddr[456+2+64+2*i+1]=ch.b[2]; j++; } } } Flash_Erase(0); Flash_Writedata(0, 16384, (int)paddr);}/* =========================== Flash_Checkbad ============================================ * Function: * 检查nand flash中的一块是不是坏块 * Params: * page:被检查块的起始页数 * Return Value: * 0x00:坏块 0x01:没问题 * ======================================================================================= */int Flash_Checkbad(unsigned long page){ unsigned int i; unsigned char status=0x00; unsigned int ADD2, ADD3; ADD3=(unsigned int)((page<<16)>>24); ADD2=(unsigned int)((page<<24)>>24); for(i=0; i<info_flash[3]; i++) { Select(); CLE_H(); writel(0x50, NANDADDR); //flashstart[0]=Read2_cmd; CLE_L(); ALE_H(); writeb(0x05, NANDADDR); //flashstart[0]=0x05; writeb(ADD2|i, NANDADDR); //flashstart[0]=ADD2|i; writeb(ADD3, NANDADDR); //flashstart[0]=ADD3; ALE_L(); while((readw(MBASS+PADAT)&0x4000)==0x0000) ; status=readb(NANDADDR); //flashstart[0]; NSelect(); if(status!=0xff) break; } if(status!=0xff) return 0x00; else return 0x01;}/* =========================== Flash_Download ============================================ * Function: * 从网络上面下载文件到nand flash中 * Params: * flag: 下载标志 1:下载内核, 0:下载jffs2文件系统, 其他:表示下载yaffs文件系统 * filename: 要下载的文件名 * ======================================================================================= */void Flash_Download(int flag, char* filename){ IP_ADDR Server; int dltype, typeset, board_dltype; int num, nflag; ADDRESS addr; ADDRESS paddr; char fnbuf[80]; char *fn, *p; /* Get/set initial/default values */ nflag=flag; num=0; paddr=(ADDRESS)__USER_SPACE; addr=(ADDRESS)__USER_SPACE; uif_dlio = UIF_DLIO_NETWORK; dltype = board_get_filetype(); typeset = FALSE; fn=filename; if (!board_dlio_init()) return; /* Initialize network stack */ net_init(); /* * Valid filename */ if (fn == NULL) { board_get_filename(fnbuf); fn = &fnbuf[0]; } /* * If file type not explicitly specified, extract from filename */ if (typeset == FALSE) { p = &fn[strlen(fn)]; while ((*p != '.') && (p != fn)) --p; if (*p == '.') ++p; if (strncasecmp(p,"SREC",3) == 0) dltype = UIF_DLIO_SREC; if (strncasecmp(p,"ELF",3) == 0) dltype = UIF_DLIO_ELF; if (strncasecmp(p,"COFF",3) == 0) dltype = UIF_DLIO_COFF; if (strncasecmp(p,"BIN",3) == 0) dltype = UIF_DLIO_IMAGE; if ((board_dltype = board_dlio_filetype(fn,p)) != UIF_DLIO_UNKNOWN) dltype = board_dltype; } board_get_server((unsigned char *)Server); printf("Downloading Image"); printf(" '%s' from %d.%d.%d.%d\n", fn, Server[0], Server[1], Server[2], Server[3] ); /* * Perform the TFTP download here.... */ if(tftp_read(&nif1, fn, Server)) { paddr=addr; num=download_nand(addr); tftp_end(TRUE); } /* Make sure interrupts are disabled */ board_irq_disable(); board_dlio_done(); cpu_cache_flush(); disasm_last_address = cpu_pc_get(); md_last_address = cpu_pc_get(); if(nflag==1) Flash_Writedata(32, num, paddr); //write linux kernel else { if(nflag==0) Flash_Writedata(4096, num, paddr); //write jffs filesystem else Flash_WritedataEx(4096, num, paddr); //write yaffs filesystem } printf("\n");}/* =========================== Flash_CreateDB ============================================ * Function: * 在nand flash中产生卡片数据库的首部 * ======================================================================================= */void Flash_CreateDB(){ char data[132]; memset(data, 0, 132); data[131]=data[130]=data[129]=data[128]=0xff; data[3]=0x84; data[5]=0x01; data[6]=0x86; data[7]=0xA0; data[15]=0x40; data[19]=0x0b; data[20]=0x06; data[21]=0x10; data[22]=0x04; data[23]=data[24]=0x01; data[25]=data[26]=0x04; data[27]=data[29]=0x01; data[28]=0x08; data[30]=0x12; data[34]=0x06; data[35]=0x43; data[36]=0x61; data[37]=0x72; data[38]=0x64; data[39]=0x44; data[40]=0x62; data[44]=0x0e; data[45]=0x2f; data[46]=0x64; data[47]=0x65; data[48]=0x76; data[49]=0x2f; data[50]=0x6d; data[51]=0x74; data[52]=0x64; data[53]=0x62; data[54]=0x6c; data[55]=0x6f; data[56]=0x63; data[57]=0x6b; data[58]=0x34; data[59]=0x07; data[60]=data[62]=0x01; data[63]=0x88; data[82]=0x07; data[83]=data[85]=0x01; data[84]=0x02; data[86]=0x78; Flash_Writedata(CARDDBOFFSET*32, 132, (unsigned long)data); }/* =========================== Flash_CreateLog =========================================== * Function: * 在nand flash中产生事件记录数据库的首部 * ======================================================================================= */void Flash_CreateLog(){ char data[32]; memset(data, 0, 32); Flash_Writedata(LOGDBOFFSET*32, 32, (unsigned long)data);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -