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

📄 usb.c

📁 QT2410的BOOTLOADER 特点 1.支援NAND FLASH读写 2.TFTP firmware upgrade 3.USB firmware upgrade 4.Fdisk
💻 C
📖 第 1 页 / 共 2 页
字号:
}

#define	USB_DOWN_DEV	0x200
#define	USB_DOWN_ATTR	((USB_DOWN_DEV<<16)|SRC_LOC_APB|SRC_ADDR_FIXED|DST_LOC_AHB|DST_ADDR_INC|REQ_USB_EP3)
#if USBDMA_DEMAND
#define	USB_DOWN_MODE	(DEMAND_MODE|SYNC_APB|DONE_GEN_INT|TSZ_UNIT|SINGLE_SVC|HW_TRIG|RELOAD_OFF|DSZ_8b)
#else
#define	USB_DOWN_MODE	(HANDSHAKE_MODE|SYNC_APB|DONE_GEN_INT|TSZ_UNIT|SINGLE_SVC|HW_TRIG|RELOAD_OFF|DSZ_8b)
#endif


u_short SetDMARun(u_int attr, u_int src_addr, u_int dst_addr, u_int len)
{
	u_short DevID, ReqSrc, ch;	
	
	DevID  = attr>>16;
	ReqSrc = attr&0xf;
	ch     = (attr&0xf0)>>4;		
#ifdef	DMA_CHECK_ATTR		
	if((ch>=MAX_DMA_CHANNEL)||(ReqSrc>4))
		return 1;
	if((DMAChannel[ch].used==DMA_IS_FREE)||(DMAChannel[ch].DevID!=DevID))
		return 1;
#endif
	DMAChannel[ch].pDMA->DISRC = src_addr;
	DMAChannel[ch].pDMA->DIDST = dst_addr;
	DMAChannel[ch].pDMA->DCON &= ~0xfffff;
	DMAChannel[ch].pDMA->DCON |= len&0xfffff;
	
	if(attr&DMA_START)
	{
		if(DMAChannel[ch].used==DMA_IS_HWTRIG)
			DMAChannel[ch].pDMA->DMASKTRIG = 2;		//channel on
		if(DMAChannel[ch].used==DMA_IS_SWTRIG)
			DMAChannel[ch].pDMA->DMASKTRIG = 3;		//sw_trig
	}
	
	return 0;
}

u_int RequestDMA(u_int attr, u_int mode)
{
	u_short DevID, ReqSrc, ch;
	u_int ret=REQUEST_DMA_FAIL;
	
	DevID   = attr>>16;	
	ReqSrc  = attr&0xff;	
	
	if(((ReqSrc>>4)>=MAX_DMA_CHANNEL)||((ReqSrc&0xf)>4))
		return ret;
		
//	EnterCritical(&r);
		
	if(DMAChannel[ReqSrc>>4].used!=DMA_IS_FREE)
	{
		u_char src = ReqSrc;			
		
		if(src==REQ_IISDI)
		{		
			if(DMAChannel[2].used!=DMA_IS_FREE)
				goto RequestDmaExit;
			else							
				ReqSrc = 0x21;											
		}
		else if(src==REQ_SDI)
		{
			if(DMAChannel[2].used!=DMA_IS_FREE)
			{
				if(DMAChannel[3].used!=DMA_IS_FREE)
					goto RequestDmaExit;
				else
					ReqSrc = 0x31;				
			}
			else
				ReqSrc = 0x22;					
		}
		else if(src==REQ_SPI)
		{
			if(DMAChannel[3].used!=DMA_IS_FREE)
				goto RequestDmaExit;
			else				
				ReqSrc = 0x32;				
		}
		else if(src==REQ_TIMER)
		{
			if(DMAChannel[2].used!=DMA_IS_FREE)
			{
				if(DMAChannel[3].used!=DMA_IS_FREE)
					goto RequestDmaExit;
				else				
					ReqSrc = 0x33;				
			}
			else				
				ReqSrc = 0x23;					
		}
		else
			goto RequestDmaExit;		
	}	
			
	ch = ReqSrc>>4;
	if(mode&HW_TRIG)
		DMAChannel[ch].used  = DMA_IS_HWTRIG;
	else
		DMAChannel[ch].used  = DMA_IS_SWTRIG;	
	DMAChannel[ch].DevID = DevID;
	DMAChannel[ch].pDMA  = (DMA *)(0x4b000000+(ch)*0x40);	
	DMAChannel[ch].pDMA->DMASKTRIG = 1<<2;	//stop dma
	DMAChannel[ch].pDMA->DISRCC = (attr>>8)&3;	
	DMAChannel[ch].pDMA->DIDSTC = (attr>>12)&3;	
	mode &= ~0x07000000;
	mode |= (ReqSrc&0x7)<<24;
	DMAChannel[ch].pDMA->DCON	= mode;	


	ret = (DevID<<16)|ReqSrc;
	
RequestDmaExit:
	//ExitCritical(&r);	
	return ret;			
}

void ConfigEp3DmaMode(u_int bufAddr,u_int count)
{ 

	count=count&0xfffff; //transfer size should be <1MB        
    
	UsbDevReq = RequestDMA(USB_DOWN_ATTR, USB_DOWN_MODE);
	if(UsbDevReq==REQUEST_DMA_FAIL)
	{
		printf("Request DMA fail!\n");
		return;
	}		
	SetDMARun(UsbDevReq|DMA_START, ADDR_EP3_FIFO, bufAddr, count);	
	

	rINDEX_REG=3;	
    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; 
	
#if USBDMA_DEMAND
	rEP3_DMA_UNIT=EP3_PKT_SIZE; //DMA transfer unit=64 bytes
	rEP3_DMA_CON=UDMA_DEMAND_MODE|UDMA_OUT_DMA_RUN|UDMA_DMA_MODE_EN; 
	
#else        
	rEP3_DMA_UNIT=0x01; //DMA transfer unit=1byte
	rEP3_DMA_CON=UDMA_OUT_DMA_RUN|UDMA_DMA_MODE_EN;
	
#endif  
	
	//wait until DMA_CON is effective.
	{
		register i = rEP3_DMA_CON;
		for(i=0;i<10;i++);
	}    	
}



int USBDownload()
{
	u_char tempMem[16];
	u_short dnCS,cs; 
	u_int i,j,temp;
	
	checkSum = 0;    
	downPt   = tempMem;	//This address is used for receiving first 8 byte.
	download_addr  =0; //_RAM_STARTADDRESS;
	download_len = 0;
	
	printf("Wait for USB connection\n\r");
	while(!isUSBSet);
    printf("USB Connected\n\r");
    while(download_len==0);
    
    #if USBDMA     
    ClearEp3OutPktReady();	//clear first out packet

    if(download_len>EP3_PKT_SIZE)
    {
        if(download_len<=(0x80000))
      	    ConfigEp3DmaMode(download_addr+EP3_PKT_SIZE-8,download_len-EP3_PKT_SIZE);		
      	else
			ConfigEp3DmaMode(download_addr+EP3_PKT_SIZE-8,0x80000-EP3_PKT_SIZE);		
 		totalDmaCount=0;
    }
    else					// download_len < EP3_PKT_SIZE    
		totalDmaCount=download_len;		    
	#endif
    
    printf("Now, Downloading [ADDRESS:%xh,TOTAL:%d]\n\r",download_addr, download_len);	
    
    j=0x80000;
	
	#if USBDMA    
    while(1)
    {
    	if((rDCDST2-(u_int)download_addr+8)>=j)
		{
		    	
   	    	j+=0x80000;
   	    	printf("\b\b\b\b\b\b\b\b%8d",totalDmaCount);
		}
		//printf("\b\b\b\b\b\b\b\b%8d",totalDmaCount);
		if (totalDmaCount>=download_len) break;		
    }
    //printf("DMA Count:%d\n\r",totalDmaCount);
	#endif
    
    #if USBDMA    
    /*******************************/
    /*     Verify check sum        */
    /*******************************/

    printf("Now, Checksum calculation\n\r");

    cs=0;    
    i=(download_addr);
    j=(download_addr+download_len-10)&0xfffffffc;
    while(i<j)
    {
    	temp=*((u_int *)i);
    	i+=4;
    	cs+=(u_short)(temp&0xff);
    	cs+=(u_short)((temp&0xff00)>>8);
    	cs+=(u_short)((temp&0xff0000)>>16);
    	cs+=(u_short)((temp&0xff000000)>>24);
    }

    i=(download_addr+download_len-10)&0xfffffffc;
    j=(download_addr+download_len-10);
    while(i<j)
    {
	  	cs+=*((u_char *)i++);
    }
    
    checkSum = cs;
    
    #endif
	
	dnCS=*((unsigned char *)(download_addr+download_len-8-2))+(*((unsigned char *)(download_addr+download_len-8-1))<<8);

    if(checkSum!=dnCS)
    {
		printf("Error!!! MEM:%x DN:%x\n\r", checkSum, dnCS);
		return 0;
    }
	
	printf("USB Image Checksum Ok\n\r");
	download_len-=10;
	//rGPGCON &= 0xfff3ffff;	//GPG9 input
	return download_len;
}

u_short ReleaseDMA(u_int attr)
{
	u_short DevID, ReqSrc, ch;	
	
	DevID  = attr>>16;
	ReqSrc = attr&0xf;
	ch     = (attr&0xf0)>>4;
	
#if	DMA_CHECK_ATTR					
	if((ch>=MAX_DMA_CHANNEL)||(ReqSrc>4))
		return 1;
	if((DMAChannel[ch].used==DMA_IS_FREE)||(DMAChannel[ch].DevID!=DevID))
		return 1;
#endif	
		
	DMAChannel[ch].pDMA->DMASKTRIG = 0;//4;	//stop dma and channel off 
	DMAChannel[ch].used = DMA_IS_FREE;
	
	return 0;					
}


void ConfigEp3IntMode(void)
{
	ReleaseDMA(UsbDevReq);	//release and stop dma
    
    rINDEX_REG=3;    
    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.
	{
		register i = rEP3_DMA_CON;
		for(i=0;i<10;i++);
	}
}

void ReConfigEp3Dma(u_int bufAddr, u_int count)
{
    SetDMARun(UsbDevReq|DMA_START, ADDR_EP3_FIFO, bufAddr, count); 
}


void IsrForUSBDma2(void)
{
    u_char out_csr3;    
    u_char saveIndexReg = rINDEX_REG;    		
    		

   
    rINDEX_REG = 3;
    out_csr3 = rOUT_CSR1_REG;
    
    ClearPending(BIT_DMA2);	  
    totalDmaCount += 0x80000;

    if(totalDmaCount>=download_len)// is last?
    {
    	totalDmaCount = download_len;
			
    	ConfigEp3IntMode();	
    	if(out_csr3& EPO_OUT_PKT_READY)
    	{
   	    	CLR_EP3_OUT_PKT_READY();
		}
        Disable_Int(nDMA2_INT);//
        Enable_Int(nUSBD_INT);//rINTMSK&=~(BIT_USBD);

    }
    else
    {
	    ReConfigEp3Dma(download_addr+totalDmaCount-8, ((download_len-totalDmaCount)>0x80000)?0x80000:(download_len-totalDmaCount));
    	while(rEP3_DMA_TTC<0xfffff)
   	    {
   	        rEP3_DMA_TTC_L = 0xff;
   	        rEP3_DMA_TTC_M = 0xff;
   	        rEP3_DMA_TTC_H = 0xf;	    //0xfffff;
   	    }
    	
    }
    rINDEX_REG = saveIndexReg;
}

⌨️ 快捷键说明

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