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

📄 flash.c

📁 UBOOT 源码
💻 C
📖 第 1 页 / 共 2 页
字号:
					while ((*addr16 & ready) != ready) {						if((*addr16 & erase_err_status)== erase_err_status){							printf("Error in Block Erase - Lock Bit may be set!\n");							printf("Status Register = 0x%X\n", (uint)*addr16);							*addr16 = 0xFFFF;	/* reset bank */							asm("sync");							return 1;						}						if ((now=get_timer(start)) > CFG_FLASH_ERASE_TOUT) {							printf ("Timeout\n");							*addr16 = 0xFFFF;	/* reset bank */							asm("sync");							return 1;						}						/* show that we're waiting */						if ((now - last) > 1000) {	/* every second */							putc ('.');							last = now;						}					}					/* reset to read mode */					*addr16 = 0xFFFF;					asm("sync");					break;				case FLASH_CFI_32BIT:					asm("sync");					last = start = get_timer (0);					/* Disable interrupts which might cause a timeout here */					flag = disable_interrupts();					/* Reset Array */					*addr = 0xffffffff;					asm("sync");					/* Clear Status Register */					*addr = 0x50505050;					asm("sync");					/* Single Block Erase Command */					*addr = 0x20202020;					asm("sync");					/* Confirm */					*addr = 0xD0D0D0D0;					asm("sync");					if((info->flash_id & FLASH_TYPEMASK) != FLASH_LH28F016SCT) {					    /* Resume Command, as per errata update */					    *addr = 0xD0D0D0D0;					    asm("sync");					}					/* re-enable interrupts if necessary */					if (flag)						enable_interrupts();					/* wait at least 80us - let's wait 1 ms */					*addr = 0x70707070;					udelay (1000);					while ((*addr & ready) != ready) {						if((*addr & erase_err_status)==erase_err_status){							printf("Error in Block Erase - Lock Bit may be set!\n");							printf("Status Register = 0x%X\n", (uint)*addr);							*addr = 0xFFFFFFFF;	/* reset bank */							asm("sync");							return 1;						}						if ((now=get_timer(start)) > CFG_FLASH_ERASE_TOUT) {							printf ("Timeout\n");							*addr = 0xFFFFFFFF;	/* reset bank */							asm("sync");							return 1;						}						/* show that we're waiting */						if ((now - last) > 1000) {	/* every second */							putc ('.');							last = now;						}					}					/* reset to read mode */					*addr = 0xFFFFFFFF;					asm("sync");					break;			}	/* end switch */		}		/* end if */	}			/* end for */	printf ("flash erase done\n");	return 0;}/*----------------------------------------------------------------------- * Copy memory to flash, returns: * 0 - OK * 1 - write timeout * 2 - Flash not erased */#define FLASH_BLOCK_SIZE 32int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt){	ulong cp, wp, data, count, temp;/*	ulong temp[FLASH_BLOCK_SIZE/4];*/	int i, l, rc;	count = cnt;	wp = (addr & ~3);	/* get lower word aligned address */	/*	 * handle unaligned start bytes	 */	if ((l = addr - wp) != 0) {		data = 0;		for (i=0, cp=wp; i<l; ++i, ++cp) {			data = (data << 8) | (*(uchar *)cp);		}		for (; i<4 && cnt>0; ++i) {			data = (data << 8) | *src++;			--cnt;			++cp;		}		for (; cnt==0 && i<4; ++i, ++cp) {			data = (data << 8) | (*(uchar *)cp);		}		if ((rc = write_word(info, wp, data)) != 0) {			return (rc);		}		wp += 4;	}	cp = wp;	/* handle unaligned block bytes , flash block size = 16bytes */	wp = (cp+FLASH_BLOCK_SIZE-1) & ~(FLASH_BLOCK_SIZE-1);	if ((wp-cp)>=cnt) {		if ((rc = write_block(info,src,cp,wp-cp)) !=0)			return (rc);		src += wp-cp;		cnt -= wp-cp;	}	/* handle aligned block bytes */	temp = 0;	printf("\n");	while ( cnt >= FLASH_BLOCK_SIZE) {		if ((rc = write_block(info,src,cp,FLASH_BLOCK_SIZE)) !=0) {			return (rc);		}		src += FLASH_BLOCK_SIZE;		cp += FLASH_BLOCK_SIZE;		cnt -= FLASH_BLOCK_SIZE;		if (((count-cnt)>>10)>temp) {			temp=(count-cnt)>>10;			printf("\r%d KB",temp);		}	}	printf("\n");	wp = cp;	/*	 * handle word aligned part	 */	while (cnt >= 4) {		data = 0;		for (i=0; i<4; ++i) {			data = (data << 8) | *src++;		}		if ((rc = write_word(info, wp, data)) != 0) {			return (rc);		}		wp  += 4;		cnt -= 4;	}	if (cnt == 0) {		return (0);	}	/*	 * handle unaligned tail bytes	 */	data = 0;	for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {		data = (data << 8) | *src++;		--cnt;	}	for (; i<4; ++i, ++cp) {		data = (data << 8) | (*(uchar *)cp);	}	return (write_word(info, wp, data));}#undef FLASH_BLOCK_SIZE/*----------------------------------------------------------------------- * Write block to Flash, returns: * 0 - OK * 1 - write timeout * 2 - Flash not erased * -1  Error */static int write_block(flash_info_t *info, uchar * src, ulong dest, ulong cnt){	vu_short *baddr, *addr = (vu_short *)dest;	ushort data;	ulong start, now, xsr,csr, ready;	int flag;	if (cnt==0) return 0;	else if(cnt != (cnt& ~1)) return -1;	/* Check if Flash is (sufficiently) erased */	data = * src;	data = (data<<8) | *(src+1);	if ((*addr & data) != data) {		return (2);	}	if (big_endian == 1) {		ready = 0x0080;	}	else {		ready = 0x8000;	}	/* Disable interrupts which might cause a timeout here */	flag = disable_interrupts();		do {			/* Write Command */			*addr = 0xe8e8;			asm("sync");			xsr = *addr;			asm("sync");		} while (!(xsr & ready));	/*wait until read */		/*write count=BLOCK SIZE -1 */		data=(cnt>>1)-1;		data=(data<<8)|data;		*addr = data;		/* word mode, cnt/2 */		asm("sync");		baddr = addr;		while(cnt) {			data = * src++;			data = (data<<8) | *src++;			asm("sync");			*baddr = data;			asm("sync");			++baddr;			cnt = cnt -2;		}		*addr = 0xd0d0;			/* confirm write */		start = get_timer(0);		asm("sync");		if (flag)			enable_interrupts();		/* data polling for D7 */		flag  = 0;		while (((csr = *addr) & ready) != ready) {			if ((now=get_timer(start)) > CFG_FLASH_WRITE_TOUT) {				flag = 1;				break;			}		}		if (csr & 0x4040) {			printf ("CSR indicates write error (%04x) at %08lx\n", csr, (ulong)addr);			flag = 1;		}		/* Clear Status Registers Command */		*addr = 0x5050;		asm("sync");		/* Reset to read array mode */		*addr = 0xFFFF;		asm("sync");	return (flag);}/*----------------------------------------------------------------------- * Write a short word to Flash, returns: * 0 - OK * 1 - write timeout * 2 - Flash not erased */static int write_short (flash_info_t *info, ulong dest, ushort data){	vu_short *addr = (vu_short *)dest;	ulong start, now, csr, ready;	int flag;	/* Check if Flash is (sufficiently) erased */	if ((*addr & data) != data) {		return (2);	}	/* Disable interrupts which might cause a timeout here */	flag = disable_interrupts();		/* Write Command */		*addr = 0x1010;		start = get_timer (0);		asm("sync");		/* Write Data */		*addr = data;		asm("sync");		/* re-enable interrupts if necessary */		if (flag)			enable_interrupts();		if (big_endian == 1) {			ready = 0x0080;		}		else {			ready = 0x8000;		}		/* data polling for D7 */		flag  = 0;		while (((csr = *addr) & ready) != ready) {			if ((now=get_timer(start)) > CFG_FLASH_WRITE_TOUT) {				flag = 1;				break;			}		}		if (csr & 0x4040) {			printf ("CSR indicates write error (%04x) at %08lx\n", csr, (ulong)addr);			flag = 1;		}		/* Clear Status Registers Command */		*addr = 0x5050;		asm("sync");		/* Reset to read array mode */		*addr = 0xFFFF;		asm("sync");	return (flag);}/*----------------------------------------------------------------------- * Write a word to Flash, returns: * 0 - OK * 1 - write timeout * 2 - Flash not erased */static int write_word (flash_info_t *info, ulong dest, ulong data){	vu_long *addr = (vu_long *)dest;	ulong start, csr, ready;	int flag=0;	switch (info->portwidth) {	case FLASH_CFI_32BIT:		/* Check if Flash is (sufficiently) erased */		if ((*addr & data) != data) {			return (2);		}		/* Disable interrupts which might cause a timeout here */		flag = disable_interrupts();		if (big_endian == 1) {			ready = 0x0080;		}		else {			ready = 0x8000;		}		if ((info->portwidth / info->chipwidth)==2) {			ready += (ready <<16);		}		else {			ready = ready << 16;		}		/* Write Command */		*addr = 0x10101010;		asm("sync");		/* Write Data */		*addr = data;		/* re-enable interrupts if necessary */		if (flag)			enable_interrupts();		/* data polling for D7 */		start = get_timer (0);		flag  = 0;		while (((csr = *addr) & ready) != ready) {			if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {				flag = 1;				break;			}		}		if (csr & 0x40404040) {			printf ("CSR indicates write error (%08lx) at %08lx\n", csr, (ulong)addr);			flag = 1;		}		/* Clear Status Registers Command */		*addr = 0x50505050;		asm("sync");		/* Reset to read array mode */		*addr = 0xFFFFFFFF;		asm("sync");		break;	case FLASH_CFI_16BIT:		flag = write_short (info, dest,  (unsigned short) (data>>16));		if (flag == 0)			flag = write_short (info, dest+2,  (unsigned short) (data));		break;	}	return (flag);}/*----------------------------------------------------------------------- * Clear Block Lock Bit, returns: * 0 - OK * 1 - Timeout */static int clear_block_lock_bit(flash_info_t * info, vu_long  * addr){	ulong start, now, ready;	/* Reset Array */	*addr = 0xffffffff;	asm("sync");	/* Clear Status Register */	*addr = 0x50505050;	asm("sync");	*addr = 0x60606060;	asm("sync");	*addr = 0xd0d0d0d0;	asm("sync");	if (big_endian == 1) {		ready = 0x0080;	}	else {		ready = 0x8000;	}	if ((info->portwidth / info->chipwidth)==2) {		ready += (ready <<16);	}	else {		ready = ready << 16;	}#ifdef DEBUG	printf ("%s: Ready flag is 0x%8lx\n", __FUNCTION__, ready);#endif	*addr = 0x70707070;	/* read status */	start = get_timer (0);	while((*addr & ready) != ready){		if ((now=get_timer(start)) > CFG_FLASH_ERASE_TOUT) {			printf ("Timeout on clearing Block Lock Bit\n");			*addr = 0xFFFFFFFF;	/* reset bank */			asm("sync");			return 1;		}	}	return 0;}#endif /* !CFG_NO_FLASH */

⌨️ 快捷键说明

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