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

📄 flash.c

📁 Linux2.4.27在AT91RM9200下的U-BOOT代码。可以在Redhat9等版本下使用。适合ARM学习者使用。
💻 C
📖 第 1 页 / 共 2 页
字号:
			printf ("- missing\n");		} else {			printf ("- no sectors to erase\n");		}		return 1;	}	if ((info->flash_id & FLASH_VENDMASK) != (INTEL_MANUFACT & FLASH_VENDMASK)) {		printf ("Can't erase unknown flash type %08lx - aborted\n",			info->flash_id);		return 1;	}	prot = 0;	for (sect=s_first; sect<=s_last; ++sect) {		if (info->protect[sect]) {			prot++;		}	}	if (prot) {		printf ("- Warning: %d protected sectors will not be erased!\n",			prot);	} else {		printf ("\n");	}	start = get_timer (0);	/* Start erase on unprotected sectors */	for (sect = s_first; sect<=s_last; sect++) {		char tmp;		if (info->protect[sect] == 0) {	/* not protected */			addr = (vu_short *)(info->start[sect]);			/* Disable interrupts which might cause a timeout here */			flag = disable_interrupts();			/* Single Block Erase Command */			*addr = 0x0020;			/* Confirm */			*addr = 0x00D0;			/* Resume Command, as per errata update */			*addr = 0x00D0;			/* re-enable interrupts if necessary */			if (flag)				enable_interrupts();			*addr = 0x70; /*Read status register command*/			tmp = (short)*addr & 0x00FF; /* Read the status */			while (!(tmp & INTEL_FLASH_STATUS_WSMS)) {				if ((now=get_timer(start)) > CFG_FLASH_ERASE_TOUT) {					*addr = 0x0050; /* Reset the status register */					*addr = 0xffff;					printf ("Timeout\n");					return 1;				}				/* show that we're waiting */				if ((now - start) > 1000) {	/* every second */					putc ('.');				}				udelay(100000); /* 100 ms */				*addr = 0x0070; /*Read status register command*/				tmp = (short)*addr & 0x00FF; /* Read status */				start = get_timer(0);			}			if( tmp & INTEL_FLASH_STATUS_ES )				flash_decode_status_bits(tmp);			*addr = 0x0050; /* Reset the status register */			*addr = 0xffff; /* Reset to read mode */		}	}	printf (" done\n");	return rcode;}void flash_unprotect (flash_info_t *info){	/*We can only unprotect the whole flash at once*/	/*Therefore we must prevent the _flash_real_protect()*/	/*from re-protecting sectors, that ware protected before */	/*we called flash_real_protect();*/	int i;	for(i = 0; i < info->sector_count; i++)		info->protect[i] = 0;#ifdef CFG_FLASH_PROTECTION		_flash_real_protect(info, 0, 0);#endif}/*----------------------------------------------------------------------- * Copy memory to flash, returns: * 0 - OK * 1 - write timeout * 2 - Flash not erased */int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt){	ulong cp, wp, data;	int i, l, rc;	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;	}	/*	 * 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));}/*----------------------------------------------------------------------- * Write a word to Flash, returns: * 0 - OK * 1 - write timeout * 2 - Flash not erased */int write_word (flash_info_t *info, ulong dest, ulong da){	vu_short *addr = (vu_short *)dest;	ulong start;	char csr;	int flag;	ushort * d = (ushort*)&da;	int i;	/* Check if Flash is (sufficiently) erased */	if (((*addr & d[0]) != d[0]) || ((*(addr+1) & d[1]) != d[1])) {		return (2);	}	/* Disable interrupts which might cause a timeout here */	flag = disable_interrupts();	for(i = 0; i < 2; i++)	{		/* Write Command */		*addr = 0x0010;		/* Write Data */		*addr = d[i];		/* re-enable interrupts if necessary */		if (flag)			enable_interrupts();		/* data polling for D7 */		start = get_timer (0);		flag  = 0;		*addr = 0x0070; /*Read statusregister command */		while (((csr = *addr) & INTEL_FLASH_STATUS_WSMS)!=INTEL_FLASH_STATUS_WSMS) {			if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {				flag = 1;				break;			}			*addr = 0x0070; /*Read statusregister command */		}		if (csr & INTEL_FLASH_STATUS_PSS) {			printf ("CSR indicates write error (%0x) at %08lx\n",					csr, (ulong)addr);			flag = 1;		}		/* Clear Status Registers Command */		*addr = 0x0050;		/* Reset to read array mode */		*addr = 0xffff;		addr++;	}	return (flag);}int flash_real_protect(flash_info_t *info, long offset, int prot){	int i, idx;	for(idx = 0; idx < info->sector_count; idx++)		if(info->start[idx] == offset)			break;	if(idx==info->sector_count)		return -1;	if(prot == 0) {		/* Unprotect one sector, which means unprotect all flash		 * and reprotect the other protected sectors.		 */		_flash_real_protect(info, 0, 0); /* Unprotects the whole flash*/		info->protect[idx] = 0;		for(i = 0; i < info->sector_count; i++)			if(info->protect[i])				_flash_real_protect(info, i, 1);		}	else {		/* We can protect individual sectors */		_flash_real_protect(info, idx, 1);	}	for( i = 0; i < info->sector_count; i++)		info->protect[i] = flash_get_protect_status(info, i);	return 0;}int _flash_real_protect(flash_info_t *info, long idx, int prot){	vu_short *addr;	int flag;	ushort cmd;	ushort tmp;	ulong now, start;	if ((info->flash_id & FLASH_VENDMASK) != (INTEL_MANUFACT & FLASH_VENDMASK)) {		printf ("Can't change protection for unknown flash type %08lx - aborted\n",			info->flash_id);		return -1;	}	if(prot == 0) {		/*Unlock the sector*/		cmd = 0x00D0;	}	else {		/*Lock the sector*/		cmd = 0x0001;	}	addr = (vu_short *)(info->start[idx]);	/* If chip is busy, wait for it */	start = get_timer(0);	*addr = 0x0070; /*Read status register command*/	tmp = ((ushort)(*addr))&0x00ff; /*Read the status*/	while(!(tmp & INTEL_FLASH_STATUS_WSMS)) {		/*Write State Machine Busy*/		/*Wait untill done or timeout.*/		if ((now=get_timer(start)) > CFG_FLASH_WRITE_TOUT) {			*addr = 0x0050; /* Reset the status register */			*addr = 0xffff; /* Reset the chip */			printf ("TTimeout\n");			return 1;		}		*addr = 0x0070;		tmp = ((ushort)(*addr))&0x00ff; /*Read the status*/		start = get_timer(0);	}	/* Disable interrupts which might cause a timeout here */	flag = disable_interrupts();	/* Unlock block*/	*addr = 0x0060;	*addr = cmd;	/* re-enable interrupts if necessary */	if (flag)		enable_interrupts();	start = get_timer(0);	*addr = 0x0070; /*Read status register command*/	tmp = ((ushort)(*addr)) & 0x00FF; /* Read the status */	while (!(tmp & INTEL_FLASH_STATUS_WSMS)) {		/* Write State Machine Busy */		if ((now=get_timer(start)) > CFG_FLASH_WRITE_TOUT) {			*addr = 0x0050; /* Reset the status register */			*addr = 0xffff;			printf ("Timeout\n");			return 1;		}		/* show that we're waiting */		if ((now - start) > 1000) {	/* every second */			putc ('.');		}		udelay(100000); /* 100 ms */		*addr = 0x70; /*Read status register command*/		tmp = (short)*addr & 0x00FF; /* Read status */		start = get_timer(0);	}	if( tmp & INTEL_FLASH_STATUS_PS )		flash_decode_status_bits(tmp);	*addr =0x0050; /*Clear status register*/	/* reset to read mode */	*addr = 0xffff;	return 0;}

⌨️ 快捷键说明

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