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

📄 flash.c

📁 U-BOOT,著名的Bootloader程序
💻 C
📖 第 1 页 / 共 3 页
字号:
					if ((rc =					     write_data_block(info,							      (ulong) src,							      wp)) != 0)						return (rc);					wp += WR_BLOCK;					src += WR_BLOCK;					cnt -= WR_BLOCK;					if (count++ > 0x800) {						spin_wheel();						count = 0;					}				}			}			/* handle word aligned part */			if (cnt < WR_BLOCK) {				/*				 * handle word aligned part				 */				count = 0;				while (cnt >= port_width) {					data = 0;					for (i = 0; i < port_width; ++i)						data = (data << 8) | *src++;					if ((rc =					     write_data(info,							(ulong) ((FPWV *) wp),							(FPW) (data))) != 0)						return (rc);					wp += port_width;					cnt -= port_width;					if (count++ > 0x800) {						spin_wheel();						count = 0;					}				}			}			if (cnt == 0)				return ERR_OK;			/*			 * handle unaligned tail bytes			 */			data = 0;			for (i = 0, cp = wp; i < port_width && cnt > 0;			     ++i, ++cp) {				data = (data << 8) | (*src++);				--cnt;			}			for (; i < port_width; ++i, ++cp) {				data = (data << 8) | (*(uchar *) cp);			}			return write_data(info, (ulong) ((FPWV *) wp),					  (FPW) data);		}		/* case FLASH_MAN_INTEL */#if defined(CONFIG_SERIAL_FLASH) && defined(CONFIG_CF_DSPI)	case FLASH_MAN_STM:		{			ulong wp;			u8 *data = (u8 *) src;			int left;	/* number of bytes left to program */			wp = addr;			/* page align, each page is 256 bytes */			if ((wp % 0x100) != 0) {				left = (0x100 - (wp & 0xFF));				write_ser_data(info, wp, data, left);				cnt -= left;				wp += left;				data += left;			}			/* page program - 256 bytes at a time */			if (cnt > 255) {				count = 0;				while (cnt >= 0x100) {					write_ser_data(info, wp, data, 0x100);					cnt -= 0x100;					wp += 0x100;					data += 0x100;					if (count++ > 0x400) {						spin_wheel();						count = 0;					}				}			}			/* remainint bytes */			if (cnt && (cnt < 256)) {				write_ser_data(info, wp, data, cnt);				wp += cnt;				data += cnt;				cnt -= cnt;			}			printf("\b.");		}#endif	}			/* switch */	return ERR_OK;}/*----------------------------------------------------------------------- * Write a word or halfword to Flash, returns: * 0 - OK * 1 - write timeout * 2 - Flash not erased */int write_data_block(flash_info_t * info, ulong src, ulong dest){	FPWV *srcaddr = (FPWV *) src;	FPWV *dstaddr = (FPWV *) dest;	ulong start;	int flag, i;	/* Check if Flash is (sufficiently) erased */	for (i = 0; i < WR_BLOCK; i++)		if ((*dstaddr++ & 0xff) != 0xff) {			printf("not erased at %08lx (%lx)\n",			       (ulong) dstaddr, *dstaddr);			return (2);		}	dstaddr = (FPWV *) dest;	/* Disable interrupts which might cause a timeout here */	flag = disable_interrupts();	*dstaddr = (FPW) INTEL_WRBLK;	/* write block setup */	if (flag)		enable_interrupts();	/* arm simple, non interrupt dependent timer */	start = get_timer(0);	/* wait while polling the status register */	while ((*dstaddr & (FPW) INTEL_FINISHED) != (FPW) INTEL_OK) {		if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {			*dstaddr = (FPW) INTEL_RESET;	/* restore read mode */			return (1);		}	}	*dstaddr = (FPW) WR_BLOCK - 1;	/* write 32 to buffer */	for (i = 0; i < WR_BLOCK; i++)		*dstaddr++ = *srcaddr++;	dstaddr -= 1;	*dstaddr = (FPW) INTEL_CONFIRM;	/* write 32 to buffer */	/* arm simple, non interrupt dependent timer */	start = get_timer(0);	/* wait while polling the status register */	while ((*dstaddr & (FPW) INTEL_FINISHED) != (FPW) INTEL_OK) {		if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {			*dstaddr = (FPW) INTEL_RESET;	/* restore read mode */			return (1);		}	}	*dstaddr = (FPW) INTEL_RESET;	/* restore read mode */	return (0);}/*----------------------------------------------------------------------- * Write a word or halfword to Flash, returns: * 0 - OK * 1 - write timeout * 2 - Flash not erased */int write_data(flash_info_t * info, ulong dest, FPW data){	FPWV *addr = (FPWV *) dest;	ulong start;	int flag;	/* Check if Flash is (sufficiently) erased */	if ((*addr & data) != data) {		printf("not erased at %08lx (%lx)\n", (ulong) addr,		       (ulong) * addr);		return (2);	}	/* Disable interrupts which might cause a timeout here */	flag = (int)disable_interrupts();	*addr = (FPW) INTEL_CLEAR;	*addr = (FPW) INTEL_RESET;	*addr = (FPW) INTEL_WRSETUP;	/* write setup */	*addr = data;	if (flag)		enable_interrupts();	/* arm simple, non interrupt dependent timer */	start = get_timer(0);	/* wait while polling the status register */	while ((*addr & (FPW) INTEL_OK) != (FPW) INTEL_OK) {		if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {			*addr = (FPW) INTEL_SUSERASE;	/* suspend mode */			*addr = (FPW) INTEL_CLEAR;	/* clear status */			*addr = (FPW) INTEL_RESET;	/* reset */			return (1);		}	}	*addr = (FPW) INTEL_CLEAR;	/* clear status */	*addr = (FPW) INTEL_RESET;	/* restore read mode */	return (0);}#if defined(CONFIG_SERIAL_FLASH) && defined(CONFIG_CF_DSPI)int write_ser_data(flash_info_t * info, ulong dest, uchar * data, ulong cnt){	ulong start;	int status, i;	u8 flashdata;	/* Check if Flash is (sufficiently) erased */	dspi_tx(ser_flash_cs, 0x80, SER_READ);	dspi_tx(ser_flash_cs, 0x80, (dest >> 16) & 0xFF);	dspi_tx(ser_flash_cs, 0x80, (dest >> 8) & 0xFF);	dspi_tx(ser_flash_cs, 0x80, dest & 0xFF);	dspi_rx();	dspi_rx();	dspi_rx();	dspi_rx();	dspi_tx(ser_flash_cs, 0x80, 0);	flashdata = dspi_rx();	dspi_tx(ser_flash_cs, 0x00, 0);	dspi_rx();	if ((flashdata & *data) != *data) {		printf("not erased at %08lx (%lx)\n", (ulong) dest,		       (ulong) flashdata);		return (2);	}	dspi_tx(ser_flash_cs, 0x00, SER_WREN);	dspi_rx();	status = serial_flash_read_status(ser_flash_cs);	if (((status & 0x9C) != 0) && ((status & 0x02) != 0x02)) {		printf("Error Programming\n");		return 1;	}	start = get_timer(0);	dspi_tx(ser_flash_cs, 0x80, SER_PAGE_PROG);	dspi_tx(ser_flash_cs, 0x80, ((dest & 0xFF0000) >> 16));	dspi_tx(ser_flash_cs, 0x80, ((dest & 0xFF00) >> 8));	dspi_tx(ser_flash_cs, 0x80, (dest & 0xFF));	dspi_rx();	dspi_rx();	dspi_rx();	dspi_rx();	for (i = 0; i < (cnt - 1); i++) {		dspi_tx(ser_flash_cs, 0x80, *data);		dspi_rx();		data++;	}	dspi_tx(ser_flash_cs, 0x00, *data);	dspi_rx();	do {		status = serial_flash_read_status(ser_flash_cs);		if (get_timer(start) > CFG_FLASH_ERASE_TOUT) {			printf("Timeout\n");			return 1;		}	} while (status & 0x01);	return (0);}#endif/*----------------------------------------------------------------------- * Write a word to Flash for ATMEL FLASH * A word is 16 bits, whichever the bus width of the flash bank * (not an individual chip) is. * * returns: * 0 - OK * 1 - write timeout * 2 - Flash not erased */int write_word_atm(flash_info_t * info, volatile u8 * dest, u16 data){	ulong start;	int flag, i;	int res = 0;		/* result, assume success */	FPWV *base;		/* first address in flash bank */	/* Check if Flash is (sufficiently) erased */	if ((*((volatile u16 *)dest) & data) != data) {		return (2);	}	base = (FPWV *) (CFG_ATMEL_BASE);	for (i = 0; i < sizeof(u16); i++) {		/* Disable interrupts which might cause a timeout here */		flag = disable_interrupts();		base[FLASH_CYCLE1] = (u8) 0x00AA00AA;	/* unlock */		base[FLASH_CYCLE2] = (u8) 0x00550055;	/* unlock */		base[FLASH_CYCLE1] = (u8) 0x00A000A0;	/* selects program mode */		*dest = data;	/* start programming the data */		/* re-enable interrupts if necessary */		if (flag)			enable_interrupts();		start = get_timer(0);		/* data polling for D7 */		while (res == 0		       && (*dest & (u8) 0x00800080) !=		       (data & (u8) 0x00800080)) {			if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {				*dest = (u8) 0x00F000F0;	/* reset bank */				res = 1;			}		}		*dest++ = (u8) 0x00F000F0;	/* reset bank */		data >>= 8;	}	return (res);}void inline spin_wheel(void){	static int p = 0;	static char w[] = "\\/-";	printf("\010%c", w[p]);	(++p == 3) ? (p = 0) : 0;}#ifdef CFG_FLASH_PROTECTION/*----------------------------------------------------------------------- */int flash_real_protect(flash_info_t * info, long sector, int prot){	int rcode = 0;		/* assume success */	FPWV *addr;		/* address of sector */	FPW value;	addr = (FPWV *) (info->start[sector]);	switch (info->flash_id & FLASH_TYPEMASK) {	case FLASH_28F160C3B:	case FLASH_28F160C3T:	case FLASH_28F320C3B:	case FLASH_28F320C3T:	case FLASH_28F640C3B:	case FLASH_28F640C3T:		*addr = (FPW) INTEL_RESET;	/* make sure in read mode */		*addr = (FPW) INTEL_LOCKBIT;	/* lock command setup */		if (prot)			*addr = (FPW) INTEL_PROTECT;	/* lock sector */		else			*addr = (FPW) INTEL_CONFIRM;	/* unlock sector */		/* now see if it really is locked/unlocked as requested */		*addr = (FPW) INTEL_READID;		/* read sector protection at sector address, (A7 .. A0) = 0x02.		 * D0 = 1 for each device if protected.		 * If at least one device is protected the sector is marked		 * protected, but return failure. Mixed protected and		 * unprotected devices within a sector should never happen.		 */		value = addr[2] & (FPW) INTEL_PROTECT;		if (value == 0)			info->protect[sector] = 0;		else if (value == (FPW) INTEL_PROTECT)			info->protect[sector] = 1;		else {			/* error, mixed protected and unprotected */			rcode = 1;			info->protect[sector] = 1;		}		if (info->protect[sector] != prot)			rcode = 1;	/* failed to protect/unprotect as requested */		/* reload all protection bits from hardware for now */		flash_sync_real_protect(info);		break;	default:		/* no hardware protect that we support */		info->protect[sector] = prot;		break;	}	return rcode;}#endif#endif

⌨️ 快捷键说明

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