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

📄 nandflash.c

📁 arm9.rar
💻 C
📖 第 1 页 / 共 2 页
字号:
		
	for(i=0; i<sizeof(oob_info); i++)
		oob_info[i] = 0xff;
	
	nand_calculate_ecc(buf, ecc_code);
	oob_info[eccpos[0]] = ecc_code[0];
	oob_info[eccpos[1]] = ecc_code[1];
	oob_info[eccpos[2]] = ecc_code[2];
	nand_calculate_ecc(buf+256, ecc_code);
	oob_info[eccpos[3]] = ecc_code[0];
	oob_info[eccpos[4]] = ecc_code[1];
	oob_info[eccpos[5]] = ecc_code[2];
	oob_info[BLK_IDXL]  = blk_idx;
	oob_info[BLK_IDXH]  = blk_idx>>8;
	oob_info[FMT_TAG]   = format_tags[addr&0x1f];
	
	NFChipEn();
	NFWrCmd(PROGCMD0);
	NFWrAddr(0);
	NFWrAddr(addr);
	NFWrAddr(addr>>8);
	if(NandAddr)
		NFWrAddr(addr>>16);
//	InitEcc();	
	for(i=0; i<512; i++)
		NFWrDat(buf[i]);
		
	if(!addr) {
		NFWrDat('b');
		NFWrDat('o');
		NFWrDat('o');
		NFWrDat('t');		
	} else {		
		for(i=0; i<sizeof(oob_info); i++)
			NFWrDat(oob_info[i]);
	}
		
/*	tmp[0] = rNFECC0;
    tmp[1] = rNFECC1;
    tmp[2] = rNFECC2;
    	
	NFWrDat(tmp[0]);
    NFWrDat(tmp[1]);
    NFWrDat(tmp[2]);*/
    	
	NFWrCmd(PROGCMD1);
	stat = NFWaitBusy();
	NFChipDs();
	
#ifdef	WR_BAD_BLK_TEST
	if((addr&0xff)==0x17) stat = 1;	//just for test bad block
#endif
	
	if(stat)
		printf("Write nand flash 0x%x fail\n", addr);
	else {	
		U8 RdDat[512];
		
		NFReadPage(addr, RdDat);
		for(i=0; i<512; i++)
			if(RdDat[i]!=buf[i]) {
				printf("Check data at page 0x%x, offset 0x%x fail\n", addr, i);
				stat = 1;
				break;
			}
	}
		
	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 */

⌨️ 快捷键说明

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