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 + -
显示快捷键?