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

📄 flash.c

📁 linux平台上的开放源代码的网络摄像机程序.实现视频捕捉,传输以及云台控制等.非常具有参考价值.
💻 C
📖 第 1 页 / 共 2 页
字号:
	flash->mfr = wide_read(flash, ADDR_MANUFACTURER * TYPE_X16 *				      flash->interleave);	/* read device id */	flash->dev_id = wide_read(flash, ADDR_DEVICE_ID * TYPE_X16 *					 flash->interleave);FDEBUG(safe_printk("mfr: ");)FDEBUG(send_serial_hex(flash->mfr, NL);)FDEBUG(safe_printk("dev_id: ");)FDEBUG(send_serial_hex(flash->dev_id, NL);)	if ((flash->interleave == 2) &&	    ((flash->mfr >> 16) == (flash->mfr & 0xffff)) &&	    ((flash->dev_id >> 16) == (flash->dev_id & 0xffff))) {		flash->mfr &= 0xffff;		flash->dev_id &= 0xffff;	}	/* reset */	flash_unlock(flash);	wide_cmd(flash, CMD_RESET_DATA, ADDR_UNLOCK_1);	/* check device type and fill in correct size */	flash->sector_size = 0x10000;	switch(flash->dev_id) {		case AM29LV160BT:		case TC58FVT160:		// case MBM29LV160TE: /* This is same id as AM29LV160BT */			message = "16Mb TB";			flash->size = 0x00200000;			flash->boot_sector = flash->base + flash->size -					    flash->sector_size;			flash->boot_sector_size[0] = 0x8000;			flash->boot_sector_size[1] = 0x2000;			flash->boot_sector_size[2] = 0x2000;			flash->boot_sector_size[3] = 0x4000;			break;		// case AM29LV160BB:		case TC58FVB160:		case MBM29LV160BE:			message = "16Mb BB";			flash->size = 0x00200000;			flash->boot_sector = flash->base;			flash->boot_sector_size[0] = 0x4000;			flash->boot_sector_size[1] = 0x2000;			flash->boot_sector_size[2] = 0x2000;			flash->boot_sector_size[3] = 0x8000;			break;		case AM29LV800BB:		case AM29F800BB:			message = "8Mb BB";			flash->size = 0x00100000;			flash->boot_sector = flash->base;			flash->boot_sector_size[0] = 0x4000;			flash->boot_sector_size[1] = 0x2000;			flash->boot_sector_size[2] = 0x2000;			flash->boot_sector_size[3] = 0x8000;			break;		case M29W800T:		case AM29LV800BT:		case AM29F800BT:		case TC58FVT800:			message = "8Mb TB";			flash->size = 0x00100000;			flash->boot_sector = flash->base + 				flash->size - flash->sector_size;			flash->boot_sector_size[0] = 0x8000;			flash->boot_sector_size[1] = 0x2000;			flash->boot_sector_size[2] = 0x2000;			flash->boot_sector_size[3] = 0x4000;			break;		// case AM29LV800BB:		default:			if (flash->interleave == 1) {				safe_printk(					"No single x16 at "); 			} else {				safe_printk(					"No interleaved x16 at "); 			}			send_serial_hex((udword)flash->base, NL);			return 0;	}	safe_printk("Found ");	if (flash->interleave == 1) {		safe_printk("1");	}	if (flash->interleave == 2) {		flash->size <<= 1;		flash->sector_size <<= 1;		flash->boot_sector =  flash->base +			((flash->boot_sector - flash->base) << 1);		flash->boot_sector_size[0] <<= 1;		flash->boot_sector_size[1] <<= 1;		flash->boot_sector_size[2] <<= 1;		flash->boot_sector_size[3] <<= 1;		safe_printk("2");	}	safe_printk(" x ");	safe_printk(message);	safe_printk(" at ");	send_serial_hex((udword)flash->base, NL);	return 1;#endif}/* Intel can erase only one at a time */static intflash_erase(flash_t *flash, unsigned char *ptr, unsigned int size)#ifdef MYINTEL{	unsigned int erased_size = 0;	int boot_sector_counter = 0;	unsigned char *verify_ptr, *end_ptr;	udword cmd,cmd_ul;	udword wrstat;	int	cur_sect_size;	unsigned char *block_verify_ptr, *block_end_ptr;	end_ptr = ptr + size;	for (verify_ptr = ptr;	     verify_ptr < end_ptr && *verify_ptr == 0xff;	     verify_ptr++) {		/* nothing */;	}	if (verify_ptr == end_ptr) {	        safe_printk("No need to erase flash at ");		send_serial_hex((udword)ptr, NL);           safe_printk("But we will still do it (to unlock all blocks)\r\n");		//		return 1;	}	/* Save ptr for verification below */	verify_ptr = ptr;		if (flash->interleave == 2){		cmd	= (CMDI_BLOCK_CONFIRM << 16)	| CMDI_BLOCK_CONFIRM;		cmd_ul	= (CMDI_UNLOCK << 16)		| CMDI_UNLOCK;	} else {		cmd	= CMDI_BLOCK_CONFIRM;		cmd_ul	= CMDI_UNLOCK;	}	safe_printk("Erasing ");	send_serial_hex(size, 0);	safe_printk(" bytes at ");	send_serial_hex((udword)ptr, 0);	safe_printk("...");	/* Init erasing of the number of sectors needed. */	/* Intel - Erase one at a time. */	while(erased_size < size) {		safe_printk(" bl: ");		send_serial_hex((udword)ptr, 0);	/* need to unlock block first - all are locked after reset*/		wide_cmd(flash, CMDI_LOCK_CONFIG, 0);		if (flash->interleave == 2) {			*(udword *)ptr = cmd_ul;		} else {			*(uword *)ptr = cmd_ul;		}// Wait ready (for strataflash?) - actully it unlocks all at once		if ((wrstat=wait_flash_ready(flash))) {	// could wait forever		        safe_printk("unlock failed, status: ");			send_serial_hex(wrstat, NL);			return 0; // erase failed		}	/* now try erase it */	/* we'll see if needed */		if (ptr < flash->boot_sector || 		    ptr >= (flash->boot_sector + flash->sector_size)) {			cur_sect_size= flash->sector_size;		} else {			cur_sect_size=flash->boot_sector_size[boot_sector_counter++];		}	/* switch to read array mode */		wide_cmd(flash, CMDI_READ_ARRAY, 0);		block_end_ptr=ptr+cur_sect_size;		for (block_verify_ptr = ptr;		     (block_verify_ptr < block_end_ptr) && *block_verify_ptr == 0xff;	 	    block_verify_ptr++) {; // nothing		}		if (block_verify_ptr < block_end_ptr) {			wide_cmd(flash, CMDI_BLOCK_ERASE, 0);				if (flash->interleave == 2) {				*(udword *)ptr = cmd;			} else {				*(uword *)ptr = cmd;			}			if ((wrstat=wait_flash_ready(flash))) {	// could wait forever			        safe_printk("erase failed, status: ");				send_serial_hex(wrstat, NL);				return 0; // erase failed			}		}		erased_size += cur_sect_size;		ptr += cur_sect_size;	}	/* switch to read array mode */	wide_cmd(flash, CMDI_READ_ARRAY, 0);	safe_printk("done, verifying...");	for (; verify_ptr < end_ptr && *verify_ptr == 0xff; verify_ptr++) {		/* nothing */;	}	if (verify_ptr != end_ptr) {	        safe_printk("error at ");		send_serial_hex((udword)verify_ptr, NL);		return 0;	}	safe_printk("OK\n");	return 1;}#else{	unsigned int erased_size = 0;	int boot_sector_counter = 0;	unsigned char *verify_ptr, *end_ptr;	udword cmd;	end_ptr = ptr + size;	for (verify_ptr = ptr;	     verify_ptr < end_ptr && *verify_ptr == 0xff;	     verify_ptr++) {		/* nothing */;	}	if (verify_ptr == end_ptr) {	        /* No need to erase */		return 1;	}	/* Save ptr for verification below */	verify_ptr = ptr;	if (flash->interleave == 2) {		cmd = (CMD_SECTOR_ERASE_UNLOCK_DATA_2 << 16) |		      CMD_SECTOR_ERASE_UNLOCK_DATA_2;	} else {		cmd = CMD_SECTOR_ERASE_UNLOCK_DATA_2;	}	send_serial_hex((udword)ptr, 0);	safe_printk(": Erasing ");	send_serial_hex(size, 0);	safe_printk(" bytes...");	/* Init erasing of the number of sectors needed. */	flash_unlock(flash);	wide_cmd(flash, CMD_SECTOR_ERASE_UNLOCK_DATA_1, ADDR_UNLOCK_1);	flash_unlock(flash);	while(erased_size < size) {		if (flash->interleave == 2) {			*(udword *)ptr = cmd;		} else {			*(uword *)ptr = cmd;		}		if (ptr < flash->boot_sector || 		    ptr >= (flash->boot_sector + flash->sector_size)) {			erased_size += flash->sector_size;			ptr += flash->sector_size;		} else {			erased_size +=				flash->boot_sector_size[boot_sector_counter];			ptr += flash->boot_sector_size[boot_sector_counter++];		}	}	/* give time for busy signal to be ready */	nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); 	while(flash_is_busy(flash, 0))		/* nothing */;	safe_printk("done, verifying...");	for (; verify_ptr < end_ptr && *verify_ptr == 0xff; verify_ptr++) {		/* nothing */;	}	if (verify_ptr != end_ptr) {	        safe_printk("error at ");		send_serial_hex((udword)verify_ptr, NL);		return 0;	}	safe_printk("OK\n");	return 1;}#endifintflash_write_part(flash_t *flash, const unsigned char *source, unsigned int offset, unsigned int size){#ifdef MYINTEL	int i;	udword  data32;#endif	int chunk_size;//	char retry_number[2] = "";	unsigned int end_offset = offset + size;	udword wrstat;	/* do the writing */	send_serial_hex((udword) (flash->base + offset), 0);	safe_printk(": Writing ");	send_serial_hex(size, 0);	safe_printk(" bytes...");#ifdef MYINTEL/* Write buffer support */	if ((flash->buffer_size) && (((end_offset-offset)>>((flash->buswidth>2)?2:1)) >= flash->buffer_size)) {	  safe_printk("BW");// Wait buffer ready	  while (((end_offset-offset)>>((flash->buswidth>2)?2:1)) >= flash->buffer_size) {//	    send_serial_hex(offset, 0);	    if (flash->interleave == 2) do {	      wide_cmd(flash, CMDI_WRITE_BUFFER, offset); //next read will be XSRB	    } while ((~(data32=wide_read(flash, offset))) & ((INTEL_XSRB_WBS) | (INTEL_XSRB_WBS << 16)));	    else do {	      wide_cmd(flash, CMDI_WRITE_BUFFER, offset);	    } while ((~(data32=wide_read(flash, offset))) & INTEL_XSRB_WBS);		    wide_cmd(flash, (flash->buffer_size)-1, offset);	    for (i=0;i<(flash->buffer_size);i++) {	      chunk_size = wide_write_chunk(flash, offset, source);	      offset += chunk_size;	      source += chunk_size;	    }	    wide_cmd(flash, CMDI_WRITE_BUFFER_CONFIRM, offset);	  } // while (((end_offset-offset)>>((flash->buswidth>2)?2:1)) >= flash->buffer_size)	  if ((wrstat=wait_flash_ready(flash))) {	// could wait forever	      	    safe_printk("write failed, status: ");	    send_serial_hex(wrstat, NL);	    return 0; // write failed	  }/* switch to read array mode */	wide_cmd(flash, CMDI_READ_ARRAY, 0);	}#endif	while (offset < end_offset) {		int retries = 0;		do {#ifdef MYINTEL			wide_cmd(flash, CMDI_PROGRAM, 0);			chunk_size = wide_write_chunk(flash, offset, source);			if ((wrstat=wait_flash_ready(flash))) {	// could wait forever		       	  safe_printk("write failed, status: ");			  send_serial_hex(wrstat, NL);			  return 0; // write failed			}		/* switch to read array mode */			wide_cmd(flash, CMDI_READ_ARRAY, 0);#else			int timeout;			flash_unlock(flash);			wide_cmd(flash, CMD_PROGRAM_UNLOCK_DATA, ADDR_UNLOCK_1);			chunk_size = wide_write_chunk(flash, offset, source);			/* give time for busy signal to be ready */			nop(); nop(); nop(); nop(); nop();			nop(); nop(); nop(); nop(); nop();			/* Wait for programming to finish.  */			timeout = 500000;			while(timeout-- && flash_is_busy(flash, offset)) {				/* nothing */;			}			if (!timeout) {				safe_printk("Timed out!\n");			}#endif			if ((flash->interleave == 1) &&			    (wide_read(flash, offset) == *((uword *)source))) {				break;			}			if ((flash->interleave == 2) &&			    (wide_read(flash, offset) == *((udword *)source))) {				break;			}			if (++retries < 10) {				safe_printk("Verify error at ");				send_serial_hex((udword)flash->base +						offset, NL);			}		} while (retries < 10);		if (retries >= 10) {			safe_printk("Fatal verify error.\n");			return 0;		}		offset += chunk_size;		source += chunk_size;	}	safe_printk("verified\n");	return 1;}#ifdef MYINTELintflash_verify_part(flash_t *flash, const unsigned char *source, unsigned int offset, unsigned int size){	unsigned int end_offset = offset + size;	int match=1;	/* do the comparing */	send_serial_hex((udword) (flash->base + offset), 0);	safe_printk(": Verifying ");	send_serial_hex(size, 0);	safe_printk(" bytes...");	/* switch to read array mode */	wide_cmd(flash, CMDI_READ_ARRAY, 0);	while (offset < end_offset) {		if (((flash->interleave == 1) &&		    (wide_read(flash, offset) != *((uword *)source))) |		    ((flash->interleave == 2) &&		    (wide_read(flash, offset) != *((udword *)source)))) {//			safe_printk("Mismatch at ");			send_serial_hex((udword)flash->base +					offset, 0);			safe_printk(" read:");			send_serial_hex(wide_read(flash, offset),0);			safe_printk(" expected:");			send_serial_hex( *((uword *)source) ,0);			safe_printk("\n");			match=0;		}		offset += (flash->buswidth);		source += (flash->buswidth);	}	if (match) safe_printk("match\n");	return match;}#else#endifvoidflash_write(const unsigned char *source, unsigned int offset, unsigned int size){	int flashes_found = 0;	unsigned int total_flash_size = 0;	int i = 0;	int verify_only=0;	if (size & 0x80000000) {	  size&=0x7fffffff;	  verify_only=1;	}	while (flashes_found < sizeof flashes / sizeof flashes[0]) {		flashes[flashes_found].type = TYPE_X16;		flashes[flashes_found].interleave = 1;		flashes[flashes_found].buswidth = 2;		if (!flash_probe(&flashes[flashes_found])) {			flashes[flashes_found].interleave = 2;			flashes[flashes_found].buswidth = 4;			if (!flash_probe(&flashes[flashes_found])) {				break;			}		}		total_flash_size += flashes[flashes_found].size;		flashes_found++;	}	if (offset + size > total_flash_size) {		safe_printk("flash too small\n");		return;	}	/* erase and write */	for (; i < flashes_found && size; i++) {		if (offset < flashes[i].size) {			unsigned int cur_size;			if (offset + size > flashes[i].size)				cur_size = flashes[i].size - offset;			else				cur_size = size;			if (!verify_only) {							  if (!flash_erase(&flashes[i],					 (unsigned char *)flashes[i].base + offset,					 cur_size)) {				return;			  }			  if (!flash_write_part(&flashes[i],					      source,					      offset,					      cur_size)) {				return;			  }			}#ifdef MYINTEL// for now verify chip-by-chip - better verify all later			if (!flash_verify_part(&flashes[i],					      source,					      offset,					      cur_size)) {				return;			}#endif			offset = 0;			size -= cur_size;			source += cur_size;		} else {			offset -= flashes[i].size;		}	}}

⌨️ 快捷键说明

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