s3c2416解决无法下载大于60M文件系统(二)USB下载

前面写了一篇从TF卡下载解决无法下载大于60M文件系统的,这两天把USB下载也改了下。

主要修改文件如下:

common/cmd_usbd.c

cpu/s3c24xx/usbd-hs.h

cpu/s3c24xx/usbd-ctl-hs.c

首先增加文件大小变量

在usbd-hs.h里增加:extern unsigned int gzsd_read_size;

在cmd_usbd.c里do_usbd_dnw 函数里增加

gzsd_read_size = 0;

这两个函数基本就不用改了,主要修改usbd-ctl-hs.c

首先在文件前面增加这些声明:

#define BUF_SIZE (2112*1024*16)
static int rsetflags = 0;
static long rnandaddr = 0x700000;
static long memaddr=0xc0000000;
static long tmpsize = 0;
static long read_tmp_size = 0;
static int times = 0;

__u32 gzsd_read_size;

BUF_SIZE为读多少后开始写,首先文件系统是yaffs格式按照2112字节对齐,同时USB读取是每次读取16个字节所以这里后面*16方便对齐。

下面的修改主要涉及到以下几个 函数,具体的执行过程我这里就不分析了

download_start,download_continue,read_epbuf

我把代码贴出来:

void gzsd_read_epbuf(__u16 *buf, int num)
{
	int i;
	__u16 read_data;

	for(i=0;i<num;i+=2) {
		read_data = (__u16)UD_EP3_BUF_REG;
		*buf = read_data;
		buf++;
		gzsd_read_size += 2;
		read_tmp_size += 2;
		if(read_tmp_size == BUF_SIZE) {
			download_ptr = (__u16 *)0xc0000000;
			buf = download_ptr;
			rsetflags = i;
			read_tmp_size = 0;
			char cmd_buf[200];
			sprintf(cmd_buf, "nand write.yaffs 0x%x 0x%x 0x%x", memaddr, rnandaddr, BUF_SIZE);
			run_command(cmd_buf, 0);
			rnandaddr += BUF_SIZE;
			times++;
		}
	}
	if(rsetflags != 0) {
		download_ptr += ((num - (rsetflags + 2))>>1);
		rsetflags = 0;
	}
	else
		download_ptr += (num>>1);
}

void download_start(__u32 ep_status)
{
	__u16 fifo_data[5];
	__u32 fifo_count;
	__u32 fifo_byte_cnt;
	__u32 upload_addr;
	__u16 temp;
	__u32 dn_filesize;

	fifo_count = UD_BYTE_READ_CNT_REG;
	LOG("fifocnt: %x\n", fifo_count);

	if (fifo_count == 5) {
		read_epbuf(fifo_data, 10);
		temp = fifo_data[4];
		LOG("temp: 0x%x\n", temp);

		if (temp==0x1) {
			upload_addr = fifo_data[0] + (fifo_data[1]<<16);
			upload_size = fifo_data[2] + (fifo_data[3]<<16);
			upload_ptr = (__u16 *)upload_addr;

			printf("UploadAddress : 0x%x, UploadSize: 0x%x\n",
				upload_ptr, upload_size);

			if (op_mode == USB_CPU_MODE) {
				LOG("CPU_MODE Bulk In Function\n");
				upload_start();
			} else {
				LOG("DMA_MODE Bulk In Function\n");
				UD_FIFO_CON_REG		= UD_DMA_ENABLE;
				UD_INDEX_REG		= UD_INDEX_EP1;
				UD_DMA_IF_CON_REG	= UD_MAX_BURST_INCR16;
				UD_BYTE_WRITE_CNT_REG	= ep1_maxpktsize;
				UD_MAX_PKT_REG		= ep1_maxpktsize;
				UD_DMA_FIFO_CNT_REG	= ep1_maxpktsize;
				UD_DMA_CNT_REG		= ep1_maxpktsize;
				UD_DMA_MEM_BASE_ADDR_REG = upload_addr;
				UD_DMA_TOTAL_CNT1_REG	= upload_size;
				UD_DMA_TOTAL_CNT2_REG	= upload_size>>16;
				UD_DMA_CON_REG		= UD_DMA_FLY_ENABLE|UD_DMA_TX_START|USB_DMA_MODE;
			}
		}
		download_filesize=0;
		return;
	} else {
		download_addr = s3c_usbd_dn_addr;
		read_epbuf(fifo_data, 8);
		if (ep_status&(0x1<<4))
			fifo_byte_cnt = fifo_count * 2 -1;
		else
			fifo_byte_cnt = fifo_count * 2;

		LOG("downloadFileSize==0, 1'st fifo_byte_cnt : 0x%x\n",
			fifo_byte_cnt);

		download_filesize = fifo_data[2] + (fifo_data[3]<<16);
		download_ptr = (__u16 *)download_addr;

		if(download_filesize > BUF_SIZE) {
			char cmd_buf[200];
			strcpy(cmd_buf, "nand erase 0x700000 0xF8D0000");
			run_command(cmd_buf, 0);
			rsetflags = 0;
			rnandaddr = 0x700000;
			memaddr=0xc0000000;
			tmpsize = 0;
			read_tmp_size = 0;
			times = 0;
		}
		/*
		 * The first 8-bytes are deleted.
		 * USB format : addr(4)+size(4)+data(n)+cs(2)
		 */
		gzsd_read_epbuf(download_ptr, fifo_byte_cnt-8);

		if (op_mode == USB_CPU_MODE) {
			if (ep_status & (0x2<<2)) {
				fifo_count = UD_BYTE_READ_CNT_REG;

				if (ep_status&(0x1<<4))
					fifo_byte_cnt = fifo_count * 2 -1;
				else
					fifo_byte_cnt = fifo_count * 2;

				LOG("2'd fifo_byte_cnt : %x\n", fifo_byte_cnt);
				read_epbuf(download_ptr, fifo_byte_cnt);
			}
		} else {
			dn_filesize = download_filesize-fifo_byte_cnt;
			if (dn_filesize > ep3_maxpktsize) {
				UD_FIFO_CON_REG		= UD_DMA_ENABLE;
				UD_INDEX_REG		= UD_INDEX_EP3;
				UD_DMA_IF_CON_REG	= UD_MAX_BURST_INCR16;
				UD_MAX_PKT_REG		= ep3_maxpktsize;
				UD_DMA_FIFO_CNT_REG	= ep3_maxpktsize;
				UD_DMA_CNT_REG		= ep3_maxpktsize;
				UD_DMA_MEM_BASE_ADDR_REG= download_addr+fifo_byte_cnt-8;
				dn_filesize		= (dn_filesize/ep3_maxpktsize)*ep3_maxpktsize;
				UD_DMA_TOTAL_CNT1_REG	= (__u16)(dn_filesize);
				UD_DMA_TOTAL_CNT2_REG	= (__u16)(dn_filesize>>16);
				UD_DMA_CON_REG		= UD_DMA_FLY_ENABLE|UD_DMA_RX_START|UD_USB_DMA_MODE;

				LOG("Out Direction DMA RX Start\n");
				LOG("download_ptr : 0x%x, UD_DMA_MEM_BASE_ADDR_REG : 0x%x, dn_filesize : 0x%x\n",
					download_ptr, UD_DMA_MEM_BASE_ADDR_REG, dn_filesize);
			}
			else
				op_mode = USB_CPU_MODE;
		}
	}
}

void download_continue(__u32 ep_status)
{
	__u32 fifo_count;
	__u32 fifo_byte_cnt;

	fifo_count = UD_BYTE_READ_CNT_REG;
	if (ep_status&(0x1<<4))
		fifo_byte_cnt = fifo_count * 2 -1;
	else
		fifo_byte_cnt = fifo_count * 2;
	LOG("downloadFileSize!=0, 1'st fifo_byte_cnt : %x\n", fifo_byte_cnt);
	gzsd_read_epbuf(download_ptr, fifo_byte_cnt);

	if (ep_status & (0x2<<2)) {
		fifo_count = UD_BYTE_READ_CNT_REG;

		if (ep_status&(0x1<<4))
			fifo_byte_cnt = fifo_count * 2 -1;
		else
			fifo_byte_cnt = fifo_count * 2;
		LOG("2'd fifo_byte_cnt : %x\n", fifo_byte_cnt);
		gzsd_read_epbuf(download_ptr, fifo_byte_cnt);
	}

	/* USB format : addr(4)+size(4)+data(n)+cs(2) */
	if((download_filesize - 10) < 10*1024*1024) {
		if (((__u32)download_ptr - download_addr) >= (download_filesize - 8)) {
			printf("Download Done!! Download Address: 0x%x, Download Filesize:0x%x\n",
				download_addr, (download_filesize-10));
			verify_checksum();
			s3c_receive_done = 1;
			char cmd_buf[200];
			unsigned long wsize;
			unsigned long tmpmem,tmpnand;
			wsize = download_filesize - 10;
			tmpmem = 0xc0000000;
			if(wsize < 1*1024*1024) {
				tmpnand = 0x0;
				if(wsize % (2*1024) != 0)
					wsize = ((wsize/(2*1024)) + 1)*(2*1024);
				strcpy(cmd_buf, "nand erase 0x0 0x80000");
				run_command(cmd_buf, 0);
				sprintf(cmd_buf, "nand write.jffs2 0x%x 0x%x 0x%x", tmpmem, tmpnand, wsize);
				run_command(cmd_buf, 0);
			}
			else {
				tmpnand = 0x300000;
				if(wsize % (2*1024) != 0)
					wsize = ((wsize/(2*1024)) + 1)*(2*1024);
				strcpy(cmd_buf, "nand erase 0x300000 0x400000");
				run_command(cmd_buf, 0);
				sprintf(cmd_buf, "nand write.jffs2 0x%x 0x%x 0x%x", tmpmem, tmpnand, wsize);
				run_command(cmd_buf, 0);
			}
		}
	}
	else {
		if (gzsd_read_size >= (download_filesize - 10)) {
			int size;
			char cmd_buf[200];
			size = gzsd_read_size - (times * BUF_SIZE) - 2;
			sprintf(cmd_buf, "nand write.yaffs 0x%x 0x%x 0x%x", memaddr, rnandaddr, size);
			run_command(cmd_buf, 0);
			s3c_receive_done = 1;
			printf("Download Done!! Download Filesize:0x%x\n",(gzsd_read_size -2));
		}
	}
}
修改完成后,只需要执行dnw 0xc0000000就可以完成烧写.

你可能感兴趣的:(s3c2416解决无法下载大于60M文件系统(二)USB下载)