nand.c
来自「Centrality Atlas II development software」· C语言 代码 · 共 688 行 · 第 1/2 页
C
688 行
tmp=(volatile unsigned *)databuffer; for(i = 0; i < data_cycles/4; i++){ while(in32(dev->iobase+ATLASII_SM_FIFO_STATUS) & 0x40) ; val=tmp[i]; out32(dev->io_data, val); } out32(dev->io_brdg, 1); while (in32(dev->io_brdg)); return 0; }// Accessing the data reg automatically sets ALE=0,CLE=0//must be 4-byte alignedintnand_read_data(NAND_CHIP *dev, uint8_t *databuffer, int data_cycles) { int i; unsigned *tmp; tmp=(unsigned *)databuffer; for(i = 0; i < data_cycles/4; i++){ while(in32(dev->iobase+ATLASII_SM_FIFO_STATUS) & 0x80) ; tmp[i] = in32(dev->io_data); } out32(dev->io_brdg, 1); while (in32(dev->io_brdg)); return 0;}unsigned GetBlockStatus(NAND_CHIP *dev, unsigned blockID){ PageInfo PI; unsigned page = PAGES2BLK *blockID; nand_read_page(dev, page, (uint8_t *)&PI, SPARESIZE, 1); if(PI.status !=0xFF) return 1; else return 0;} unsigned upgrade_nand_flash(unsigned start_block, unsigned src) { PageInfo PI; int imagesize; int sequence=0; int num_blks=0; int bd_blks=0; int blk_id=0; unsigned page; unsigned status; struct startup_header *hdr; hdr=(struct startup_header *)src; imagesize = hdr->stored_size; if(start_block<2) { ser_putstr((unsigned char *)"upgrade_nand_flash: we have to reserve at least 2 blocks\n"); return -1; } //init nand nand_init(); //skip the reserved good blks; while(num_blks<=start_block) { status=GetBlockStatus(dev, blk_id); if(status==-1) return -1; else if(status==0) num_blks++; else bd_blks++; blk_id++; } PI.status=0xFF; while(1) { //first, is this a good block status=GetBlockStatus(dev, blk_id); if(status==-1) return -1; else if(status==0) { //then erase this block if(nand_erase_blk(dev, blk_id)==-1) return -1; if(nand_read_status(dev, (uint8_t *)&status) !=0) return -1; if((status & 0xFF) != 0xC0) { return -1; } //write data to this block page = blk_id*PAGES2BLK; for( ; page<((blk_id+1)*PAGES2BLK); page++) { if(nand_write_page(dev, page, (uint8_t *)src, DATASIZE, 0)==-1) return -1; PI.erasesig = 0; PI.sequence =sequence; // PI.crctrans = (uint16_t)crc16((uint8_t *) src, DATASIZE ); if(nand_write_page(dev, page, (uint8_t *)&PI, SPARESIZE, 1)==-1) return -1; if(nand_read_status(dev, (uint8_t *)&status) !=0) return -1; if(((status & 0xFF) & 0x01) != 0) { return -1; } imagesize -=DATASIZE; if(imagesize<=0) return 0; src+=DATASIZE; sequence++; } num_blks--; } blk_id++; if(blk_id>(start_block+8192)) //in case something bad happened, never go beyond 128MB return -1; } return 0;} unsigned upgrade_IPL(unsigned src) { PageInfo PI; int imagesize=16*1024; //16K int sequence=0; int blk_id=0; unsigned page; unsigned status; //init nand nand_init(); PI.status=0xFF; //then erase this first block if(nand_erase_blk(dev, blk_id)==-1) return -1; if(nand_read_status(dev, (uint8_t *)&status) !=0) return -1; if((status & 0xFF) != 0xC0) return -1; //write data to the block page = blk_id*PAGES2BLK; for( ; page<((blk_id+1)*PAGES2BLK); page++) { if(nand_write_page(dev, page, (uint8_t *)src, DATASIZE, 0)==-1) return -1; PI.erasesig = 0; PI.sequence =sequence; // PI.crctrans = (uint16_t)crc16((uint8_t *) src, DATASIZE ); if(nand_write_page(dev, page, (uint8_t *)&PI, SPARESIZE, 1)==-1) return -1; if(nand_read_status(dev, (uint8_t *)&status) !=0) return -1; if(((status & 0xFF) & 0x01) != 0) { return -1; } imagesize -=DATASIZE; if(imagesize<=0) return 0; src+=DATASIZE; sequence++; } return 0;} unsigned read_image_from_nand(unsigned start_block, unsigned dst){ PageInfo *PI; int num_blks=0; int sequence=0; int bd_blks=0; int blk_id=0; unsigned page; unsigned status; int imagesize=0; struct startup_header *hdr; if(start_block<2) { ser_putstr((unsigned char *)"read_image_from_nand: we have to reserve at least 2 blocks\n"); return -1; } //init nand nand_init(); //skip the reserved good blks; while(num_blks<=start_block) { status=GetBlockStatus(dev, blk_id); if(status==-1) return -1; else if(status==0) num_blks++; else bd_blks++; blk_id++; } while(1) { //first, is this a good block status=GetBlockStatus(dev, blk_id); if(status==-1) return -1; else if(status==0) { //read data from this block page = blk_id*PAGES2BLK; for( ; page<((blk_id+1)*PAGES2BLK); page++) { if(nand_read_page(dev, page, (uint8_t *)dst, PAGESIZE, 0)==-1) return -1; PI = (PageInfo *)(dst + DATASIZE); if(PI->status != 0xff) { continue ; } if(PI->sequence !=sequence) return -1; //if(PI->crctrans !=crc16((uint8_t *)dst, DATASIZE)) // return -1; if(imagesize==0) { hdr=(struct startup_header *)dst; imagesize = hdr->stored_size; if(imagesize<=0 ||imagesize>0x02000000) //image size not correct (no bigger than 32MB) return -1; } imagesize -=DATASIZE; if(imagesize<=0) return 0; dst+=DATASIZE; sequence++; } num_blks--; } blk_id++; if(blk_id>(start_block+8192)) //in case something bad happened, never go beyond 128MB return -1; } return 0;} unsigned nand_write_config(unsigned src) { PageInfo PI; int sequence=0; int blk_id=1; unsigned page; unsigned status; PI.status=0xFF; while(1) { //first, is this a good block status=GetBlockStatus(dev, blk_id); if(status==-1) return -1; else if(status==0) { //then erase this block if(nand_erase_blk(dev, blk_id)==-1) return -1; if(nand_read_status(dev, (uint8_t *)&status) !=0) return -1; if((status & 0xFF) != 0xC0) { return -1; } //write data to this block page = blk_id*PAGES2BLK; if(nand_write_page(dev, page, (uint8_t *)src, DATASIZE, 0)==-1) return -1; PI.erasesig = 0; PI.sequence =sequence; PI.crctrans = (uint16_t)crc16((uint8_t *) src, DATASIZE ); if(nand_write_page(dev, page, (uint8_t *)&PI, SPARESIZE, 1)==-1) return -1; if(nand_read_status(dev, (uint8_t *)&status) !=0) return -1; if(((status & 0xFF) & 0x01) != 0) { return -1; } return 0; } blk_id++; if(blk_id>(8192)) //in case something bad happened, never go beyond 128MB return -1; } return 0;}unsigned nand_read_config(unsigned dst){ PageInfo *PI; int sequence=0; int blk_id=1; unsigned page; unsigned status; while(1) { //first, is this a good block status=GetBlockStatus(dev, blk_id); if(status==-1) return -1; else if(status==0) { //read data from this block page = blk_id*PAGES2BLK; if(nand_read_page(dev, page, (uint8_t *)dst, PAGESIZE, 0)==-1) return -1; PI = (PageInfo *)(dst + DATASIZE); if(PI->status != 0xff) { continue ; } if(PI->sequence !=sequence) return -1; if(PI->crctrans !=crc16((uint8_t *)dst, DATASIZE)) return -1; return 0; } blk_id++; if(blk_id>(8192)) //in case something bad happened, never go beyond 128MB return -1; } return 0;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?