⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nand.c

📁 arm7,44b0芯片的blob程序,适用于学嵌入式linux的新手.
💻 C
字号:
/* Command sets */#define CMD_SEQ_DIN     0x80    /* Sequencial Data Input command */#define CMD_READ0       0x00    /* 1'st half address command */#define CMD_READ1       0x01    /* 2'st half address command */#define CMD_READ2       0x50    /* Spare area command */#define CMD_ID          0x90    /* ID command */#define CMD_RESET       0xff    /* Reset command */#define CMD_PAGE_PGM    0x10    /* Page program command */#define CMD_BLK_ERASE1  0x60    /* Block erase command1 */#define CMD_BLK_ERASE2  0xd0    /* Block erase command2 */#define CMD_STATUS      0x70    /* Read status command */#define CLE         (0x20) /* GPF5 */#define ALE         (0x40) /* GPF6 */#define RB          (0x80) /* GPF7 */volatile unsigned char *nand_base = 0x04000000;void nand_cmd(int cmd){     int i;     REG(PDATF) |= CLE;     REG(PDATF) &=~ALE;     *nand_base = (unsigned char)cmd;     for(i=0; i<5; i++);}void nand_paddr(int addr){     int i;     REG(PDATF) |= ALE;     REG(PDATF) &=~CLE;     *nand_base = 0;     *nand_base = (unsigned char)addr&0xff;     *nand_base = (unsigned char)(addr>>8)&0x7f;     for(i=0; i<5; i++);}void nand_baddr(int addr){     int i;     REG(PDATF) |= ALE;     REG(PDATF) &=~CLE;     *nand_base = (unsigned char)addr&0xff;     *nand_base = (unsigned char)(addr>>8)&0x7f;     for(i=0; i<5; i++);}void nand_eraseblock(int baddr){     nand_cmd(CMD_BLK_ERASE1);     nand_baddr(baddr<<5);     nand_cmd(CMD_BLK_ERASE2);     REG(PDATF) &= ~(ALE|CLE);     while(!(REG(PDATF)&RB));     nand_cmd(CMD_STATUS);     REG(PDATF) &= ~(ALE|CLE);     if((*nand_base)&1){         SerialOutputString("\nErase block error!\n\n");     }}void nand_verifypage(int paddr, char *buf){     int i;     char rb[528];     nand_cmd(CMD_READ0);     nand_paddr(paddr);     REG(PDATF) &= ~(ALE|CLE);     while(!(REG(PDATF)&RB));     for(i=0; i<512; i++){         rb[i] = *nand_base;     }     for(i=0; i<512; i++){         if(buf[i] != rb[i]){             SerialOutputString("Verify Page error: ");             SerialOutputHex(paddr);             SerialOutputString("\n");             return;         }     }}void nand_readpage(int paddr, char *buf){     int i;     nand_cmd(CMD_READ0);     nand_paddr(paddr);     REG(PDATF) &= ~(ALE|CLE);     while(!(REG(PDATF)&RB));     for(i=0; i<512; i++){         buf[i] = *nand_base;     }}void nand_writepage(int paddr, char *buf){     int i;     nand_cmd(CMD_SEQ_DIN);     nand_paddr(paddr);     REG(PDATF) &= ~(ALE|CLE);     for(i=0; i<512; i++){         *nand_base = buf[i];     }     nand_cmd(CMD_PAGE_PGM);     while(!(REG(PDATF)&RB));     nand_cmd(CMD_STATUS);     if((*nand_base)&1){         SerialOutputString("\nWrite block error!\n\n");     }}int nand_readid(void){     int id = 0, i;     nand_cmd(CMD_ID);     REG(PDATF) |= ALE;     REG(PDATF) &=~CLE;     *nand_base = 0;     REG(PDATF) &= ~(ALE|CLE);     for(i=0; i<5; i++); //wait 100ns     id = (*nand_base)<<8;     id += *nand_base;     SerialOutputString("\nNAND FLASH ID: ");     SerialOutputHex(id);     SerialOutputString("\n");     return id;}void nand_write(char *dst, char *src, int nword){     int block, page;     nword >>= 12;     nword ++;     block = (int)dst>>14;     nword += block;     SerialOutputString("nand_write: from ");     SerialOutputHex(block);     SerialOutputString(" to ");     SerialOutputHex(nword);     SerialOutputString("\n");     for(; block<nword; block++){         nand_eraseblock(block);         for(page=0; page<32; page++){             nand_writepage((block<<5)+page, src);             nand_verifypage((block<<5)+page, src);             src += 512;         }     }}void nand_read(char *dst, char *src, int nword){     int block, page;     nword >>= 12;     nword ++;     block = (int)src>>14;     nword += block;     for(; block<nword; block++){         for(page=0; page<32; page++){             nand_readpage((block<<5)+page, dst);             dst += 512;         }     }}void nand_test(void){     int i, j, p;     char buf[528];     for(i=0; i<1024; i++){         nand_eraseblock(i);         for(j=0; j<32; j++){             nand_readpage((i<<5)+j, buf);             for(p=0; p<512; p++){                 if(buf[p] != 0xff){                     SerialOutputString("Bad Page: ");                     SerialOutputHex((i<<5)+j);                     SerialOutputString("\n");                     break;                 }             }         }     }} static int dmaddr;static int dm(int argc, char *argv[]){ int i, j, data; if(argc == 2){     strtou32(argv[1], &dmaddr);  } for(i=0; i<16; i++){     SerialOutputHex(dmaddr);     SerialOutputString(": ");     for(j=0; j<16; j+=4){         data = *(int *)dmaddr;         SerialOutputHex(data);         SerialOutputString(" ");         dmaddr += 4;     }     SerialOutputString("\n"); } return 0;}static char dmhelp[] = "dm {address}\n""dump memory as word\n";__commandlist(dm, "dm", dmhelp);static int wb(int argc, char *argv[]){ int wbaddr; int data; if(argc == 3){     strtou32(argv[1], &wbaddr);     strtou32(argv[2], &data); }else{     return -1; } *(unsigned char*)wbaddr = (unsigned char)data; SerialOutputHex(wbaddr); SerialOutputString(": "); data = *(unsigned char*)wbaddr; SerialOutputHex(data); SerialOutputString("\n"); return 0;}static char wbhelp[] = "wb {address} {data}\n""write byte to memory\n";__commandlist(wb, "wb", wbhelp);static int dbaddr;static int db(int argc, char *argv[]){ int i, j; unsigned char data; if(argc == 2){     strtou32(argv[1], &dbaddr);  }/* SerialOutputHex(dbaddr); SerialOutputString(": "); data = *(unsigned char*)dbaddr; SerialOutputHex(data); SerialOutputString("\n"); dbaddr ++;*/ for(i=0; i<8; i++){     SerialOutputHex(dbaddr);     SerialOutputString(": ");     for(j=0; j<8; j++){         data = *(unsigned char*)dbaddr;         SerialOutputHex(data);         SerialOutputString(" ");         dbaddr += 1;     }     SerialOutputString("\n"); } return 0;}static char dbhelp[] = "db {address}\n""dump memory as byte\n";__commandlist(db, "db", dbhelp);static int ne(int argc, char *argv[]){ int blk1, blk2; int i, j, p; char buf[528]; if(argc == 2){     strtou32(argv[1], &blk1);     blk2 = blk1; }else if(argc == 3){     strtou32(argv[1], &blk1);     strtou32(argv[2], &blk2); } for(i=blk1; i<=blk2; i++){     nand_eraseblock(i);     for(j=0; j<32; j++){         nand_readpage((i<<5)+j, buf);         for(p=0; p<512; p++){             if(buf[p] != 0xff){                 SerialOutputString("Bad Page: ");                 SerialOutputHex((i<<5)+j);                 SerialOutputString("\n");                 break;             }         }     } } return 0;}static char nehelp[] = "ne {blk1} {blk2}\n""erase nand flash from block blk1 to blk2\n";__commandlist(ne, "ne", nehelp);static int nraddr;static int nr(int argc, char *argv[]){ int i, j; char buf[528]; if(argc == 2){     strtou32(argv[1], &nraddr); } nand_readpage(nraddr, buf); for(i=0; i<512; i+=16){     SerialOutputHex(i);     SerialOutputString(": ");     for(j=i; j<i+16; j+=4){         SerialOutputHex(*(int *)(buf+j));         SerialOutputString(" ");     }     SerialOutputString("\n"); } nraddr ++; return 0;}static char nrhelp[] = "nr {page}\n""read nand page\n";__commandlist(nr, "nr", nrhelp);static int nwaddr, nwmaddr;static int nw(int argc, char *argv[]){ char buf[528]; if(argc == 2){     strtou32(argv[1], &nwaddr); }else if(argc == 3){     strtou32(argv[1], &nwaddr);     strtou32(argv[2], &nwmaddr); }      nand_writepage(nwaddr, (char *)nwmaddr); nand_verifypage(nwaddr, (char *)nwmaddr); nwaddr ++; nwmaddr += 512; return 0;}static char nwhelp[] = "nw {page} {address}\n""write memory data to nand flash page\n";__commandlist(nw, "nw", nwhelp);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -