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

📄 cmd_usb_down.c.svn-base

📁 u-boot loader common files, like cpu, clock, environment...etc...
💻 SVN-BASE
📖 第 1 页 / 共 3 页
字号:
    for(i=0;i<num;i++)
    {
        buf[i]=(u8)rEP3_FIFO;
        checkSum+=buf[i];
    }
}

void ClearEp3OutPktReady(void)
{
	u8 out_csr3;
    rINDEX_REG=3;
    out_csr3=rOUT_CSR1_REG;
    CLR_EP3_OUT_PKT_READY();
}

void ConfigEp3DmaMode(u32 bufAddr,u32 count)
{
    int i;

    rINDEX_REG=3;
    count=count&0xfffff; //transfer size should be <1MB
    
    rDISRCC2=(1<<1)|(1<<0);
    rDISRC2=ADDR_EP3_FIFO; //src=APB,fixed,src=EP3_FIFO 
    rDIDSTC2=(0<<1)|(0<<0);
    rDIDST2=bufAddr;       //dst=AHB,increase,dst=bufAddr

    rDCON2=(count)|(1<<31)|(0<<30)|(1<<29)|(0<<28)|(0<<27)|(4<<24)|(1<<23)|(0<<22)|(0<<20); 
	//handshake,requestor=APB,CURR_TC int enable,unit transfer,
	//single service,src=USBD,H/W request,autoreload,byte,CURR_TC

    rDMASKTRIG2= (1<<1); 
	//DMA 2 on

    //rEP3_DMA_FIFO=0x40; //not needed for OUT operation. 	

    rEP3_DMA_TTC_L=0xff;
    rEP3_DMA_TTC_M=0xff;
    rEP3_DMA_TTC_H=0x0f;

    rOUT_CSR2_REG=rOUT_CSR2_REG|EPO_AUTO_CLR|EPO_OUT_DMA_INT_MASK; 
	//AUTO_CLR(OUT_PKT_READY is cleared automatically), interrupt_masking.

    rEP3_DMA_UNIT=0x01; //DMA transfer unit=1byte
    rEP3_DMA_CON=UDMA_OUT_DMA_RUN|UDMA_DMA_MODE_EN;
	// deamnd disable,out_dma_run=run,in_dma_run=stop,DMA mode enable

    //wait until DMA_CON is effective.
    rEP3_DMA_CON;
    for(i=0;i<10;i++);    	
}

void ConfigEp3IntMode(void)
{
    rINDEX_REG=3;
    
    rDMASKTRIG2= (0<<1);  // EP3=DMA ch 2
    //DMA channel off
    rOUT_CSR2_REG=rOUT_CSR2_REG&~(EPO_AUTO_CLR/*|EPO_OUT_DMA_INT_MASK*/); 
    //AUTOCLEAR off,interrupt_enabled (???)
    rEP3_DMA_UNIT=1;	
    rEP3_DMA_CON=0; 
    // deamnd disable,out_dma_run=stop,in_dma_run=stop,DMA mode disable
    //wait until DMA_CON is effective.
    rEP3_DMA_CON;
    
}


void Ep3Handler(void)
{
    u8 out_csr3;
    int fifoCnt;
    rINDEX_REG=3;

    out_csr3=rOUT_CSR1_REG;

//	dbgprintf("<3:%x]",out_csr3);

    if(out_csr3 & EPO_OUT_PKT_READY){	//1
	    fifoCnt=rOUT_FIFO_CNT1_REG; 
//		RdPktEp3(ep3Buf,fifoCnt);
//		PrintEpoPkt(ep3Buf,fifoCnt);

		if(downloadFileSize==0){
	   	    RdPktEp3((u8 *)downPt, 8);
//	   	    USBdownloadAddress = *((u32 *)(downPt));
			USBdownloadAddress = tempDownloadAddress;
		    downloadFileSize= *((u32 *)(downPt+4));

		    checkSum=0;
		    downPt=(u8 *)USBdownloadAddress;

			RdPktEp3_CheckSum((u8 *)downPt,fifoCnt-8); //The first 8-bytes are deleted.
			downPt+=fifoCnt-8;

			//CLR_EP3_OUT_PKT_READY() is not executed. 
			//So, USBD may generate NAK until DMA2 is configured for USB_EP3;
   		    mask_irq(INT_USBD);
   		    return;	
		}else{
			dbgprintf("<ERROR>");
		    RdPktEp3_CheckSum((u8 *)downPt,fifoCnt); 	    
		    downPt+=fifoCnt;  //fifoCnt=64
		}
		
		CLR_EP3_OUT_PKT_READY();
		if(((rOUT_CSR1_REG&0x1)==1) && ((rEP_INT_REG & 0x8)==0)){
			fifoCnt=rOUT_FIFO_CNT1_REG;
			RdPktEp3_CheckSum((u8 *)downPt,fifoCnt);
			downPt+=fifoCnt;
			CLR_EP3_OUT_PKT_READY();
		}

		return;
    }
    
    //I think that EPO_SENT_STALL will not be set to 1.
    if(out_csr3 & EPO_SENT_STALL){   // 0x40
		dbgprintf("[STALL]");
	   	CLR_EP3_SENT_STALL();
	   	return;
	}
	
	unmask_irq(INT_USBD);
}




void USB_Download(void)
{
	int first = 1, i, j;
	u8 key = 0;
	u16 cs, dnCS, checkSum = 0;
	u32 temp;
	u8 tempMem[16];
	
	USBdownloadAddress = (u32)tempMem;
	downPt = (u8 *)USBdownloadAddress;
	downloadFileSize = 0;
	
	printf("\n\nUSB host is connected\n");
	printf("Select the file you wanna download in 'USB Port->Transmit' menu of DNW\n");
	printf("Waiting a download... \n");

	while(downloadFileSize == 0){
		if(ctrlc()){
			printf("\ndownload file size is 0 byte.\nusbdown command stopped!!\n\n\n");
			in_USB_Download = 0;
			return;
		}
	}
	
	unmask_irq(INT_DMA2);
	ClearEp3OutPktReady();
	// indicate the first packet is processed.
	// has been delayed for DMA2 cofiguration.
	
	if(downloadFileSize > EP3_PKT_SIZE)
	{
		if(downloadFileSize <= 0x80000)
		{
			ConfigEp3DmaMode(USBdownloadAddress+EP3_PKT_SIZE-8,downloadFileSize-EP3_PKT_SIZE);
		}else{
			ConfigEp3DmaMode(USBdownloadAddress+EP3_PKT_SIZE-8,0x80000-EP3_PKT_SIZE);
			
			if(downloadFileSize>(0x80000*2))//for 1st autoreload
			{
				rDIDST2=(USBdownloadAddress+0x80000-8);	//for 1st autoreload.
				rDIDSTC2=(1<<2)|(0<<1)|(0<<0);
				rDCON2=rDCON2&~(0xfffff)|(0x80000);
				
				while(rEP3_DMA_TTC<0xfffff)
				{
					rEP3_DMA_TTC_L=0xff;
					rEP3_DMA_TTC_M=0xff;
					rEP3_DMA_TTC_H=0xf;
				}
			}else{
				rDIDST2=(USBdownloadAddress+0x80000-8);
				rDIDSTC2=(1<<2)|(0<<1)|(0<<0);
				rDCON2=rDCON2&~(0xfffff)|(downloadFileSize-0x80000);
				
				while(rEP3_DMA_TTC<0xfffff)
				{
					rEP3_DMA_TTC_L=0xff;
					rEP3_DMA_TTC_M=0xff;
					rEP3_DMA_TTC_H=0xf;
				}
			}
		}
		
		totalDmaCount = 0;
	}else{
		totalDmaCount=downloadFileSize;	
	}

	printf("\nNow, Downloading [ADDRESS:0x%x ,TOTAL:%d(0x%x) bytes]\n",
		USBdownloadAddress, downloadFileSize, downloadFileSize);
	printf("Downloading file ... ");
	
	j = 0x10000;
	
	while(1)
	{
		if( (rDCDST2-(u32)USBdownloadAddress+8) >= j)	j += 0x10000;
		
		if(totalDmaCount >= downloadFileSize)		break;
	}

	printf("\n\nRECEIVED FILE SIZE: %d bytes", totalDmaCount);
	
	// Verify check sum
	printf("\nNow, Checksum calculation\n");
	
	cs = 0;
	i = USBdownloadAddress;
	j = (USBdownloadAddress + downloadFileSize-10) & 0xfffffffc;
	
	while(i<j)
	{
		temp = *((u32 *)i);
		i += 4;
		cs += (u16)(temp&0xff);	
		cs += (u16)((temp&0xff00)>>8);
		cs += (u16)((temp&0xff0000)>>16);
		cs += (u16)((temp&0xff000000)>>24);
	}
	
	i = (USBdownloadAddress + downloadFileSize-10) & 0xfffffffc;
	j = (USBdownloadAddress + downloadFileSize-10);
	
	while(i<j)		cs += *((u8 *)i++);
	
	checkSum = cs;
	
	dnCS = *((unsigned char *)(USBdownloadAddress + downloadFileSize-8-2))+
		(*( (unsigned char *)(USBdownloadAddress + downloadFileSize-8-1))<<8);
		
	if(checkSum!=dnCS)
	{
		printf("Checksum Error!!! MEM:%x DN:%x\n",checkSum,dnCS);
		return;
	
	}
	
	printf("Download O.K.\n\n\n");

	in_USB_Download = 0;
}


void ISR_int_usbd(void)
{
	u8 usbdIntpnd, epIntpnd;
    u8 saveIndexReg = rINDEX_REG;
    
    mask_irq(INT_USBD);
    
    usbdIntpnd = rUSB_INT_REG;
    epIntpnd = rEP_INT_REG;
//	printf("[INT:EP_I=%x,USBI=%x]\n",epIntpnd,usbdIntpnd);

    if(usbdIntpnd & SUSPEND_INT)	// 1
    {
    	rUSB_INT_REG = SUSPEND_INT;
//		printf( "<SUS]");
    }
    if(usbdIntpnd & RESUME_INT)		// 2
    {
    	rUSB_INT_REG=RESUME_INT;
//		printf("<RSM]");
    }
    if(usbdIntpnd & RESET_INT)		// 4
    {
//		printf( "<RST]");
    	config_usbd();
		//RESET_INT should be cleared after ResetUsbd()
    	rUSB_INT_REG=RESET_INT;   	

        PrepareEp1Fifo(); 
    }
    
    unmask_irq(INT_USBD);

	if(epIntpnd & EP0_INT)	//1
	{
		isUsbdSetConfiguration = 1;
		rEP_INT_REG=EP0_INT;  
		Ep0Handler();
	}
	if(epIntpnd & EP1_INT)	//2
	{
		rEP_INT_REG=EP1_INT;  
		Ep1Handler();
	}

	if(epIntpnd & EP3_INT)	//8
	{
		rEP_INT_REG=EP3_INT;
		Ep3Handler();
	}
    
    rINDEX_REG=saveIndexReg;
    
    clear_irq_pnd(INT_USBD);
}

void ISR_int_dma2(void)
{
	u8 out_csr3;
    u32 nextTotalDmaCount;
    u8 saveIndexReg = rINDEX_REG;
    
    mask_irq(INT_DMA2);
    
    rINDEX_REG = 3;
    out_csr3 = rOUT_CSR1_REG;
    
    clear_irq_pnd(INT_DMA2);
    
    totalDmaCount += 0x80000;

    if(totalDmaCount >= downloadFileSize)// is last?
    {
    	totalDmaCount = downloadFileSize;
    	ConfigEp3IntMode();	
    	if(out_csr3& EPO_OUT_PKT_READY)		CLR_EP3_OUT_PKT_READY();

        mask_irq(INT_DMA2);
		unmask_irq(INT_USBD);
    }else{
    	if((totalDmaCount+0x80000)<downloadFileSize){
	    	nextTotalDmaCount=totalDmaCount+0x80000;

    	    if((nextTotalDmaCount+0x80000)<downloadFileSize){
        		//for (2~n)th autoreload.	 
				while((rDSTAT2&0xfffff)==0); //wait until autoreload occurs.
				rDIDST2=((u32)USBdownloadAddress+nextTotalDmaCount-8);  
				rDIDSTC2=(0<<1)|(0<<0);  
    	    	rDCON2=rDCON2&~(0xfffff)|(0x80000); 
    	    	
    	    	while(rEP3_DMA_TTC<0xfffff)
    	    	{
    	    	    rEP3_DMA_TTC_L=0xff;
    	    	    rEP3_DMA_TTC_M=0xff;
    	    	    rEP3_DMA_TTC_H=0xf;
    	    	    //0xfffff;
    	    	}
    	    }else{
				while((rDSTAT2&0xfffff)==0); //wait until autoreload occurs.
   		        rDIDST2=((u32)USBdownloadAddress+nextTotalDmaCount-8);  
      	        rDIDSTC2=(0<<1)|(0<<0);  
      	        rDCON2=rDCON2&~(0xfffff)|(downloadFileSize-nextTotalDmaCount);
    	    	while(rEP3_DMA_TTC<0xfffff)
    	    	{
    	    	    rEP3_DMA_TTC_L=0xff;
    	    	    rEP3_DMA_TTC_M=0xff;
    	    	    rEP3_DMA_TTC_H=0xf;
    	    	    //0xfffff;
    	    	}
			}
		}else{
		    while((rDSTAT2&0xfffff)==0); //wait until autoreload occurs.
  		    rDIDST2=((u32)USBdownloadAddress+downloadFileSize-8);  //for next autoreload.	    		
  		    rDIDSTC2=(0<<1)|(0<<0);
  		    rDCON2=rDCON2&~(0xfffff)|(0); 		
			//There is no 2nd autoreload. This will not be used.  	    
		    //rDMA_TX+=0x0; //USBD register		
		}
		unmask_irq(INT_DMA2);
    }
    
    rINDEX_REG = saveIndexReg;
}


void usb_slave_port_init(void)
{
	// USB device detection control
	rGPGCON &= ~(3<<24);
	rGPGCON |=  (1<<24); // output
	rGPGUP  |=  (1<<12); // pullup disable
	rGPGDAT |=  (1<<12); // output
	
	rMISCCR &= ~(1<<3);		// USBD is selected instead of USBH1 
	rMISCCR &= ~(1<<13);	// USB port 1 is enabled.
	
	return;
}

void usbdown_init(void)
{
	// USB device detection control
	rGPGCON &= ~(3<<24);
	rGPGCON |=  (1<<24); // output
	rGPGUP  |=  (1<<12); // pullup disable
	rGPGDAT |=  (1<<12); // output
	
	// Interrupt initialization
	irq_install_handler(INT_USBD, ISR_int_usbd, NULL);
	irq_install_handler(INT_DMA2, ISR_int_dma2, NULL);
	mask_irq(INT_USBD);
	mask_irq(INT_DMA2);
	
	rMISCCR &= ~(1<<3);		// USBD is selected instead of USBH1 
	rMISCCR &= ~(1<<13);	// USB port 1 is enabled.
	
	InitDescriptorTable();
	config_usbd();
	unmask_irq(INT_USBD);
	PrepareEp1Fifo();
	
	Clk0_Disable();
	Clk1_Disable();
	
	return;
}


void do_usb_down (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	if ((argc <  2) || (argc > 3)){
		printf ("inadquate argument count\nUsage:\n%s\n", cmdtp->help);
		return -1;
	}
	
	tempDownloadAddress = simple_strtoul(argv[1], NULL, 16);
	
	if((tempDownloadAddress<CFG_MEMTEST_START) || (tempDownloadAddress>=CFG_MEMTEST_END)){
		printf("memory address must be within the range of 0x%x ~ 0x%x\n", 
			CFG_MEMTEST_START, CFG_MEMTEST_END);
		return -1;
	}

	if(isUsbdSetConfiguration == 0){
		printf("\n\nUSB host is not connected yet.\n");
		printf("Connect USB cable to MBA2440 USB slave port and try again!!\n\n\n");
		return;
	}

	unmask_irq(INT_USBD);

	in_USB_Download = 1;
	while(in_USB_Download == 1)	USB_Download();

	mask_irq(INT_USBD);
	mask_irq(INT_DMA2);

	return;
}

U_BOOT_CMD(
	usbdown,	2,	1,	do_usb_down,
	"usbdown      - data download using USB slave port.\n",
	" - MBA2440 USB download command\n" 
	"    this command is only for DNW\n" 
	"    Connect USB cable, before executing usbdown\n"
	"usbdown [download memory address(hex)]\n");


#endif //(CONFIG_COMMANDS & CONFIG_USE_IRQ)

⌨️ 快捷键说明

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