前面写了一篇从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就可以完成烧写.