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

📄 nandflash.c

📁 优龙开发板YL2410的bios完整代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		
	return stat;	
}

static void NFMarkBadBlk(U32 addr)
{
	int i;
	addr &= ~0x1f;
	
	NFChipEn();
	
	NFWrCmd(READCMD2);	//point to area c
	
	NFWrCmd(PROGCMD0);
	NFWrAddr(0);		//mark offset 0~15
	NFWrAddr(addr);
	NFWrAddr(addr>>8);
	if(NandAddr)
		NFWrAddr(addr>>16);
	for(i=0; i<16; i++)
		NFWrDat(0);		//mark with 0	
	NFWrCmd(PROGCMD1);
	NFWaitBusy();		//needn't check return status
	
	NFWrCmd(READCMD0);	//point to area a
		
	NFChipDs();
}

static int NFChkBadBlk(U32 addr)
{
	U8 dat;
	
	addr &= ~0x1f;
	
	NFChipEn();
	
	NFWrCmd(READCMD2);	//point to area c
	NFWrAddr(5);		//mark offset 5
	NFWrAddr(addr);
	NFWrAddr(addr>>8);
	if(NandAddr)
		NFWrAddr(addr>>16);
	NFWaitBusy();
	dat = NFRdDat();
	
	NFWrCmd(READCMD0);	//point to area a
	
	NFChipDs();

	return (dat!=0xff);
}



static struct Partition *NFSelPart(char *info)
{
	int i, max_sel;

	printf("Please select Nand flash region to %s, Esc to abort\n", info);
	
	for(i=0; pNandPart[i].size; i++)
		printf("%d : start 0x%08x, size 0x%08x\t[Part%d]\n", i, pNandPart[i].offset, pNandPart[i].size, i/*pNandPart[i].name*/ );

	max_sel = i;	
	
	while(1) {
		char c = getch();
		
		if(c==0x1b)
			return 0;
		if((c>='0')&&(c<(max_sel+'0')))
			return &(pNandPart[c-'0']);
	}	
}

static void NFReadPart(struct Partition *part, U8 *buf)
{
	U32 i, start_page;
	U8 *ram_addr;
	int size;
	
	start_page = part->offset>>9;
	size = part->size;
	ram_addr = buf;
	
	for(i=0; size>0; ) {
		if(!(i&0x1f)) {
			if(NFChkBadBlk(i+start_page)) {
				printf("Skipped bad block at 0x%08x\n", i+start_page);
				i += 32;
				size -= 32<<9;
				continue;
			}
		}
		NFReadPage((i+start_page), ram_addr);
//			printf("Read page %d\n", i);
		i++;
		size -= 512;
		ram_addr += 512;
	}
}

/******************************************************/
int WrFileToNF(U32 src_addr, U32 w_size)
{
	struct Partition *part;
	U32 start_page, i, skip_blks;
	U8 *ram_addr;
	int size;	//must be int
	U32 start_addr;
	
	if(!support)
		return -1;
		
	part = NFSelPart("write");
	if(!part)
		return -1;
	
	if(w_size>part->size) {
		puts("File size is too long!\n");
		return -1;
	}

	start_page = part->offset>>9;
	
	printf("Are you sure to write nand flash from 0x%x with ram address 0x%x, size %d ?\n", part->offset, src_addr, w_size);
	if(!getyorn())
		return -1;
		
	skip_blks = 0;
	ram_addr = (U8 *)src_addr;
	start_addr = (U32)src_addr;
	size = w_size;
	printf("start address 0x%x\n", start_page);
	for(i=0; size>0; )	{
		if(!(i&0x1f)) {
			if(NFEraseBlock(i+start_page)) {
/*				part->size -= 32<<9;	//fail, partition available size - 1 block size
				if(FileSize>part->size) {
					puts("Program nand flash fail\n");
					return;
				}
				NFMarkBadBlk(i+start_page);
				skip_blks++;
				i += 32;			
				continue;*/
				goto WrFileToNFErr;
			}
		}
		if(NFWritePage(i+start_page, ram_addr, ((U32)ram_addr-start_addr)>>14)) {
			ram_addr -= (i&0x1f)<<9;
			size += (i&0x1f)<<9;
			i &= ~0x1f;
WrFileToNFErr:			
			part->size -= 32<<9;	//partition available size - 1 block size
			if(w_size>part->size) {
				puts("Program nand flash fail\n");
				return -1;
			}			
			NFMarkBadBlk(i+start_page);
			skip_blks++;			
			i += 32;		
			continue;
		}
		ram_addr += 512;
		size -= 512;
		i++;
	}
	printf("\nend address 0x%x\n", start_page+i);

	puts("Program nand flash partition success\n");
	if(skip_blks)
		printf("Skiped %d bad block(s)\n", skip_blks);
		
	return 0;	
}

int RdFileFrNF(U32 dst_addr, U32 load_part)
{
	U32 i;
	struct Partition *part;
	
	if(!support)
		return -1;

	for(i=0; pNandPart[i].size; i++);
	if(i>load_part)
		part = pNandPart+load_part;
	else {
		part = NFSelPart("read");
		if(!part)
			return -1;
	}
	
	puts("Loading...\n");
	
	NFReadPart(part, (U8 *)dst_addr);
	
	puts("end\n");
	
	return 0;
}

int EraseNandPart(void)
{
	struct Partition *part;
	U32 start_page, blk_cnt;
	int i, err = 0;	

	if(!support)
		return -1;
		
	part = NFSelPart("erase");
	if(!part)
		return -1;

	start_page = part->offset>>9;
	blk_cnt  = part->size>>14;

	printf("Are you sure to erase nand flash from page 0x%x, block count 0x%x ?", start_page, blk_cnt);
	if(!getyorn())
		return -1;
	
	printf("start address 0x%x\n", start_page);
	for(i=0; blk_cnt; blk_cnt--, i+=32) {
		if(NFEraseBlock(i+start_page)) {
			err ++;
			puts("Press any key to continue...\n");
			getch();
		}
	}
	printf("\nend address 0x%x\n", start_page+i-32);
	
	puts("Erase Nand partition completed ");
	if(err)
		printf("with %d bad block(s)\n", err);
	else
		puts("success\n");
	
	return 0;
}

#ifdef	SAVE_ENV_IN_NAND
U32 NFSaveParams(char *pEnv)
{
	char dat[512];
	U32 addr;
	
	if(support) {
		memcpy(dat, pEnv, sizeof(EnvParams));
		for(addr=SIZE_64K>>9; addr<(0x30000>>9); addr++) {
			NFEraseBlock(addr);
			if(!NFWritePage(addr, (U8 *)dat, 0))
				return 0;
		}
	}
	return -1;
}

U32 NFSearchParams(char *pEnv)
{
	char dat[512];
	U32 addr;
	
	if(support) {
		for(addr=SIZE_64K>>9; addr<(0x30000>>9); addr++) {
			NFReadPage(addr, (U8 *)dat);		
			if(!strncmp(dat, "params", 7)) {
				memcpy(pEnv, dat, sizeof(EnvParams));			
				return 0;
			}
		}
	}
	return -1;	
}
#endif

static U32 nand_id;

void NandFlashInit(void)
{
	int i;	
	
	support = 0;
	nand_id = NFReadID();
	
	for(i=0; NandFlashChip[i].id!=0; i++)
		if(NandFlashChip[i].id==nand_id) {			
			nand_id = i;
			NandFlashSize = NandFlashChip[i].size;
			support  = 1;
			NandAddr = NandFlashSize>SIZE_32M;
			if(!pNandPart[0].size) {
				pNandPart[0].offset = 0;
				pNandPart[0].size   = NandFlashSize;
				pNandPart[1].size   = 0;				
			}			
			return;
		}
	
}

void NandFlashStatusRep(void)
{
	if(support) {
		printf("Nand Flash ID is 0x%x, Size = %dM, Status = 0x%x\n", NandFlashChip[nand_id].id, NandFlashChip[nand_id].size>>20, NFReadStat());
	} else {
		printf("No supported Nand Flash Found!\n");
	}
}

//void (*pNandFlashInit)(void) = NandFlashInit;

#endif	/* NAND_SUPPORT */

#ifdef	NAND_FLASH_SUPPORT

int NandProg(int argc, char *argv[])
{
	unsigned int size = ~0;
	unsigned int data_begin = ~0;

	data_begin = download_addr;
	size       = download_len;
	
	if(argc>1)
		data_begin = strtoul((char *)argv[1]);
	if(argc>2)	
		size       = strtoul((char *)argv[2]);	
	if((size==-1)||(data_begin==-1)) {
		printf("Arguments error\n");
		goto err_exit;
	}
	
	if(size==0) {
		printf("Write 0 Bytes!\n");
		return -1;
	}
	else
		return WrFileToNF(data_begin, size);
	
err_exit:
	printf("Usage:	nfprog addr size\naddr = data pointer to ram\nsize = program size(Bytes)\n");
	return -1;
}

int NandLoad(int argc, char *argv[])
{
	U32 load_part = -1;
	download_addr = DFT_DOWNLOAD_ADDR;
	
	if(argc>1) {
		download_addr = strtoul((char *)argv[1]);
		if(download_addr==-1)
			download_addr = DFT_DOWNLOAD_ADDR;
		if(argc>2)
			load_part = strtoul(argv[2]);
	}
	
	printf("Load data form nand flash to 0x%x\n", download_addr);
	return RdFileFrNF(download_addr, load_part);
}

int NandErase(int argc, char *argv[])
{
	return EraseNandPart();
}

int NandPart(int argc, char*argv[])
{
	unsigned long i, addr[8];
	
	if(!NandFlashSize)
		return -1;
	if((argc<=1)||(argc>9))
		goto err_exit;

	addr[0] = 0;
	for(i=1; i<argc; i++) {
		addr[i] = strtoul((char *)argv[i]);		
		if((addr[i]==-1)||(addr[i]<=addr[i-1])||(addr[i]&0x3fff)||(addr[i]>NandFlashSize))
			goto err_exit;
	}
	
	printf("Set %d partition(s) :\n", argc-1);
	for(i=0; i<argc-1; i++) {
		pNandPart[i].offset = addr[i];
		pNandPart[i].size   = addr[i+1]-addr[i];
		pNandPart[i].name   = " ";
		pNandPart[i+1].size = 0;
		printf("part%d : start address 0x%-8x, size 0x%-8x\n", i, pNandPart[i].offset, pNandPart[i].size);
	}

	return 0;
	
err_exit:
	puts("Usage : nfpart a1 a2 ... an\na1 = part1 end address, an = partn end address, n<=8, address must be 16KB align and don't excess the size of nand flash \n");
	return -1;
}

#endif


#define SAVE_ENV_IN_NAND
#ifdef	SAVE_ENV_IN_NAND

U32 NFSaveParams(char *pEnv)
{	
	char dat[512];
	U32 addr;
	InitNandFlash();
	if(1) {
		memcpy(dat, pEnv, sizeof(EnvParams));
		for(addr=SIZE_128K>>9; addr<(0x30000>>9); addr++) {
			//NFEraseBlock(addr);
			 EraseBlock(addr);
			//if(!NFWritePage(addr, (U8 *)dat, 0))
			 if(!WritePage(addr, (U8 *)dat))
			 {
				//printf("wite succes\n");
				return 0;
			 }
		}
	}
	return -1;
	
}


U32 NFSearchParams(char *pEnv)
{
	char dat[512];
	U32 addr;
	InitNandFlash();
	if(1) {
		for(addr=SIZE_128K>>9; addr<(0x30000>>9); addr++) {
			ReadPage(addr, (U8 *)dat);		
			//if(!strncmp(dat, "params", 7)) {
			memcpy(pEnv, dat, sizeof(EnvParams));			
			return 0;	
		}
	}
	return -1;	
}

#endif

⌨️ 快捷键说明

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