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