usb.c

来自「S3C24A0的完整BSP包,对开发此芯片的开发者很有用.」· C语言 代码 · 共 1,314 行 · 第 1/3 页

C
1,314
字号
			WrPktEp0((U8 *)descStr1+(ep0SubState*EP0_PKT_SIZE),
			sizeof(descStr1)-(ep0SubState*EP0_PKT_SIZE)); 
			SET_EP0_INPKTRDY_DATAEND();
			ep0State=EP0_STATE_INIT;     
			ep0SubState=0;
		}
		break;

	case EP0_STATE_GD_STR_I2:
		if( (ep0SubState*EP0_PKT_SIZE+EP0_PKT_SIZE)<sizeof(descStr2) )
		{
			WrPktEp0((U8 *)descStr2+(ep0SubState*EP0_PKT_SIZE),EP0_PKT_SIZE); 
			SET_EP0_IN_PKT_RDY();
			ep0State=EP0_STATE_GD_STR_I2;
			ep0SubState++;
		}
		else
		{
			WrPktEp0((U8 *)descStr2+(ep0SubState*EP0_PKT_SIZE),
			sizeof(descStr2)-(ep0SubState*EP0_PKT_SIZE)); 
			SET_EP0_INPKTRDY_DATAEND();
			ep0State=EP0_STATE_INIT;     
			ep0SubState=0;
		}
		break;

	case EP0_CONFIG_SET:
		WrPktEp0((U8 *)&ConfigSet+0,1); 
		SET_EP0_INPKTRDY_DATAEND();
		ep0State=EP0_STATE_INIT;      
		break;

	case EP0_GET_STATUS0:
		WrPktEp0((U8 *)&StatusGet+0,1);
		SET_EP0_INPKTRDY_DATAEND();
		ep0State=EP0_STATE_INIT;      
		break;

	case EP0_GET_STATUS1:
		WrPktEp0((U8 *)&StatusGet+1,1);
		SET_EP0_INPKTRDY_DATAEND();
		ep0State=EP0_STATE_INIT;      
		break;

	case EP0_GET_STATUS2:
		WrPktEp0((U8 *)&StatusGet+2,1);
		SET_EP0_INPKTRDY_DATAEND();
		ep0State=EP0_STATE_INIT;      
		break;

	case EP0_GET_STATUS3:
		WrPktEp0((U8 *)&StatusGet+3,1);
		SET_EP0_INPKTRDY_DATAEND();
		ep0State=EP0_STATE_INIT;      
		break;

	case EP0_GET_STATUS4:
		WrPktEp0((U8 *)&StatusGet+4,1);
		SET_EP0_INPKTRDY_DATAEND();
		ep0State=EP0_STATE_INIT;      
		break;

	default:
//		DbgPrintf("UE:G?D");
		EdbgOutputDebugString("[UE:G?D]\r\n");
		break;
	}
}

void ReconfigUsbd(void)
{
// *** End point information ***
//   EP0: control
//   EP1: bulk in end point
//   EP2: not used
//   EP3: bulk out end point
//   EP4: not used
    
	pUSBCtrlAddr->PMR.sus_en = 0;
	pUSBCtrlAddr->PMR.sus_mo = 0;
	pUSBCtrlAddr->PMR.muc_res = 0;
	pUSBCtrlAddr->PMR.usb_re = 0;
	pUSBCtrlAddr->PMR.iso_up = 0;

	pUSBCtrlAddr->INDEX.index = 0;
	pUSBCtrlAddr->MAXP.maxp = 0x01;	//EP0 max packit size = 8 
	pUSBCtrlAddr->EP0ICSR1.sopr_cdt = 1;
	pUSBCtrlAddr->EP0ICSR1.sse_ = 1;
	//EP0:clear OUT_PKT_RDY & SETUP_END

	pUSBCtrlAddr->INDEX.index = 1;
	pUSBCtrlAddr->MAXP.maxp = 0x08;	//EP1 max packit size = 64 
	pUSBCtrlAddr->EP0ICSR1.de_ff = 1;
	pUSBCtrlAddr->EP0ICSR1.sopr_cdt = 1;
	pUSBCtrlAddr->ICSR2.mode_in = 1;
	pUSBCtrlAddr->ICSR2.in_dma_int_en = 1;
	pUSBCtrlAddr->ICSR2.iso = 0;
	pUSBCtrlAddr->OCSR1.clr_data_tog = 1;
	pUSBCtrlAddr->OCSR2.iso = 0;
	pUSBCtrlAddr->OCSR2.out_dma_int_en = 1;

	pUSBCtrlAddr->INDEX.index = 2;
	pUSBCtrlAddr->MAXP.maxp = 0x08;	//EP2 max packit size = 64 
	pUSBCtrlAddr->EP0ICSR1.de_ff = 1;
	pUSBCtrlAddr->EP0ICSR1.sopr_cdt = 1;
	pUSBCtrlAddr->ICSR2.mode_in = 1;
	pUSBCtrlAddr->ICSR2.in_dma_int_en = 1;
	pUSBCtrlAddr->ICSR2.iso = 0;
	pUSBCtrlAddr->OCSR1.clr_data_tog = 1;
	pUSBCtrlAddr->OCSR2.iso = 0;
	pUSBCtrlAddr->OCSR2.out_dma_int_en = 1;

	pUSBCtrlAddr->INDEX.index = 3;
	pUSBCtrlAddr->MAXP.maxp = 0x08;	//EP3 max packit size = 64 
	pUSBCtrlAddr->EP0ICSR1.de_ff = 1;
	pUSBCtrlAddr->EP0ICSR1.sopr_cdt = 1;
	pUSBCtrlAddr->ICSR2.mode_in = 0;
	pUSBCtrlAddr->ICSR2.in_dma_int_en = 0;
	pUSBCtrlAddr->ICSR2.iso = 0;
	pUSBCtrlAddr->OCSR1.clr_data_tog = 1;
	//clear OUT_PKT_RDY, data_toggle_bit.
	//The data toggle bit should be cleared when initialization.
	pUSBCtrlAddr->OCSR2.iso = 0;
	pUSBCtrlAddr->OCSR2.out_dma_int_en = 1;

	pUSBCtrlAddr->INDEX.index = 4;
	pUSBCtrlAddr->MAXP.maxp = 0x08;	//EP4 max packit size = 64 
	pUSBCtrlAddr->EP0ICSR1.de_ff = 1;
	pUSBCtrlAddr->EP0ICSR1.sopr_cdt = 1;
	pUSBCtrlAddr->ICSR2.mode_in = 0;
	pUSBCtrlAddr->ICSR2.in_dma_int_en = 1;
	pUSBCtrlAddr->ICSR2.iso = 0;
	pUSBCtrlAddr->OCSR1.clr_data_tog = 1;
	//clear OUT_PKT_RDY, data_toggle_bit.
	//The data toggle bit should be cleared when initialization.
	pUSBCtrlAddr->OCSR2.iso = 0;
	pUSBCtrlAddr->OCSR2.out_dma_int_en = 1;

	pUSBCtrlAddr->EIR.ep0_int=1;
	pUSBCtrlAddr->EIR.ep1_int=1;
	pUSBCtrlAddr->EIR.ep2_int=1;
	pUSBCtrlAddr->EIR.ep3_int=1;
	pUSBCtrlAddr->EIR.ep4_int=1;
	pUSBCtrlAddr->UIR.reset_int = 1;
	pUSBCtrlAddr->UIR.sus_int = 1;
	pUSBCtrlAddr->UIR.resume_int = 1;

	//Clear all usbd pending bits

	//EP0,1,3 & reset interrupt are enabled
	pUSBCtrlAddr->EIER.ep0_int_en = 1;
	pUSBCtrlAddr->EIER.ep1_int_en = 1;
	pUSBCtrlAddr->EIER.ep3_int_en = 1;

	pUSBCtrlAddr->UIER.reset_int_en = 1;
	ep0State=EP0_STATE_INIT;

}

void Isr_Init(void)
{
	volatile S3C24A0_INTR_REG *s24A0INT = (S3C24A0_INTR_REG *)INT_BASE;

	s24A0INT->INTMOD=0x0;	  // All=IRQ mode
	s24A0INT->INTMSK=BIT_ALLMSK;	  // All interrupt is masked.
	s24A0INT->INTSUBMSK=BIT_ALLMSK;	  // All interrupt is masked.
	
	// make value to assemble code "b IsrHandler"
	pISR =(unsigned)(0xEA000000)+(((unsigned)IsrHandler - (0x80000000 + 0x18 + 0x8) )>>2);
	

	s24A0INT->SRCPND  = BIT_USBD;
	if (s24A0INT->INTPND & BIT_USBD) s24A0INT->INTPND = BIT_USBD;
	s24A0INT->INTMSK &= ~BIT_USBD;		// USB Interrupt enable.

	s24A0INT->SUBSRCPND  = BIT_SUB_DMA2;
	s24A0INT->SRCPND  = BIT_DMA_SBUS;
	if (s24A0INT->INTPND & BIT_DMA_SBUS) s24A0INT->INTPND = BIT_DMA_SBUS;
	s24A0INT->INTSUBMSK &= ~BIT_SUB_DMA2;		// DMA2 sub Interrupt enable.
	s24A0INT->INTMSK &= ~BIT_DMA_SBUS;		// DMA Interrupt enable.
}

void IsrUsbd(unsigned int val)
{
  U8 saveIndexReg=pUSBCtrlAddr->INDEX.index;
	volatile S3C24A0_INTR_REG *s24A0INT = (S3C24A0_INTR_REG *)INT_BASE;


	if (s24A0INT->INTPND & BIT_DMA_SBUS)
	{
		DMA2Handler();
		goto Exit;
	}

    if(pUSBCtrlAddr->UIR.sus_int)
    {
		pUSBCtrlAddr->UIR.sus_int = 1;
		EdbgOutputDebugString("<SUS]\r\n");
    }
    if(pUSBCtrlAddr->UIR.resume_int)
    {
		pUSBCtrlAddr->UIR.resume_int = 1;
		EdbgOutputDebugString("<RSM]\r\n");
    }
    if(pUSBCtrlAddr->UIR.reset_int)
    {
		EdbgOutputDebugString("<RSET]\r\n");
    		ReconfigUsbd();
		pUSBCtrlAddr->UIR.reset_int = 1;
        	PrepareEp1Fifo(); 
    }

    if(pUSBCtrlAddr->EIR.ep0_int)
    {
		EdbgOutputDebugString("EP0 Interrupt\r\n");
		pUSBCtrlAddr->EIR.ep0_int=1;
    		Ep0Handler();
    }
    if(pUSBCtrlAddr->EIR.ep1_int)
    {
		EdbgOutputDebugString("<1:TBD]\r\n");
		pUSBCtrlAddr->EIR.ep1_int=1;
    		Ep1Handler();
    }

    if(pUSBCtrlAddr->EIR.ep2_int)
    {
		pUSBCtrlAddr->EIR.ep2_int=1;
		EdbgOutputDebugString("<2:TBD]\r\n");
    }

    if(pUSBCtrlAddr->EIR.ep3_int)
    {
    		Ep3Handler();
		pUSBCtrlAddr->EIR.ep3_int=1;
    }

    if(pUSBCtrlAddr->EIR.ep4_int)
    {
		pUSBCtrlAddr->EIR.ep4_int=1;
		EdbgOutputDebugString("<4:TBD]\r\n");
    }

	if (s24A0INT->INTPND & BIT_USBD)
	{
	  EdbgOutputDebugString("< bit usb clear>\r\n");      
		s24A0INT->SRCPND  = BIT_USBD;
		
		if (s24A0INT->INTPND & BIT_USBD) s24A0INT->INTPND = BIT_USBD;
	}

Exit:
    pUSBCtrlAddr->INDEX.index=saveIndexReg;
}

void Ep3Handler(void)
{
    int fifoCnt;
    volatile S3C24A0_INTR_REG *s24A0INT = (S3C24A0_INTR_REG *)INT_BASE;


    pUSBCtrlAddr->INDEX.index=3;


    if(pUSBCtrlAddr->OCSR1.out_pkt_rdy)
    {
      
  		fifoCnt=pUSBCtrlAddr->OFCR1.out_cnt_low;
	  	downPt = (LPBYTE)(downPtIndex);
		  RdPktEp3((U8 *)downPt,fifoCnt);
		  downPtIndex += fifoCnt; //64
//		downPtIndex += 64; 
		  s24A0INT->INTMSK |= BIT_USBD;		// USB Interrupt disable.
		
		return;
    }

    //I think that EPO_SENT_STALL will not be set to 1.
    if(pUSBCtrlAddr->OCSR1.sent_stall)
    {
	   	CLR_EP3_SENT_STALL();
   		return;
    }
}

void DMA2Handler(void)
{
	volatile S3C24A0_INTR_REG *s24A0INT = (S3C24A0_INTR_REG *)INT_BASE;
	volatile S3C24A0_DMA_REG *v_pDMAregs = (S3C24A0_DMA_REG *)DMA2_BASE;

	s24A0INT->SUBSRCPND  = BIT_SUB_DMA2;
	s24A0INT->SRCPND  = BIT_DMA_SBUS;
	if (s24A0INT->INTPND & BIT_DMA_SBUS) s24A0INT->INTPND = BIT_DMA_SBUS;

	downPtIndex += DMA_SIZE;

	v_pDMAregs->DIDST=((U32)downPtIndex+DMA_SIZE);
	v_pDMAregs->DIDSTC=(1<<2)|(0<<1)|(0<<0);  
	v_pDMAregs->DCON=v_pDMAregs->DCON&~(0xfffff)|(DMA_SIZE); 

	while(rEP3_DMA_TTC<0xfffff)
	{
		pUSBCtrlAddr->EP3DTL.ep3_ttl_l = 0xff;
		pUSBCtrlAddr->EP3DTM.ep3_ttl_m = 0xff;
		pUSBCtrlAddr->EP3DTH.ep3_ttl_h = 0x0f;
	}
}

void ConfigEp3DmaMode(U32 bufAddr,U32 count)
{
	volatile S3C24A0_INTR_REG *s2A40INT = (S3C24A0_INTR_REG *)INT_BASE;
	volatile S3C24A0_DMA_REG *v_pDMAregs = (S3C24A0_DMA_REG *)DMA2_BASE;
	int i;

	pUSBCtrlAddr->INDEX.index=3;
	count=count&0xfffff; //transfer size should be <1MB
	v_pDMAregs->DISRCC=(1<<1)|(1<<0);
	v_pDMAregs->DISRC=REAL_PHYSICAL_ADDR_EP3_FIFO; //src=APB,fixed,src=EP3_FIFO
	v_pDMAregs->DIDSTC=(0<<2)|(0<<1)|(0<<0);
	v_pDMAregs->DIDST=bufAddr;       //dst=AHB,increase,dst=bufAddr
	v_pDMAregs->DCON=(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

	v_pDMAregs->DMASKTRIG = (1<<1);
	//DMA 2 on

	pUSBCtrlAddr->EP3DTL.ep3_ttl_l = 0xff;
	pUSBCtrlAddr->EP3DTM.ep3_ttl_m = 0xff;
	pUSBCtrlAddr->EP3DTH.ep3_ttl_h = 0x0f;

	pUSBCtrlAddr->OCSR2.auto_clr = 1;
	pUSBCtrlAddr->OCSR2.out_dma_int_en = 1;
	//AUTO_CLR(OUT_PKT_READY is cleared automatically), interrupt_masking.
	pUSBCtrlAddr->EP3DU.ep3_unit_cnt = 1;

	*(volatile BYTE *)&pUSBCtrlAddr->EP3DC=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.
	*(volatile BYTE *)&pUSBCtrlAddr->EP3DC;
	for(i=0;i<10000;i++);
}

void ConfigEp3IntMode(void)
{
	volatile S3C24A0_DMA_REG  *v_pDMAregs = (S3C24A0_DMA_REG *)DMA2_BASE;
    pUSBCtrlAddr->INDEX.index=3;
    
    v_pDMAregs->DMASKTRIG= (0<<1);  // EP3=DMA ch 2
        //DMA channel off
	pUSBCtrlAddr->OCSR2.auto_clr = 0;

	//AUTOCLEAR off,interrupt_enabled (???)
	pUSBCtrlAddr->EP3DU.ep3_unit_cnt = 1;
	*(volatile BYTE *)&pUSBCtrlAddr->EP3DC=0x0;
    //wait until DMA_CON is effective.
    *(volatile BYTE *)&pUSBCtrlAddr->EP3DC;
}

#pragma optimize ("",off)
BOOL UbootReadData(DWORD cbData, LPBYTE pbData)
{
//	volatile USBD_GLOBALS *usbdShMem = (USBD_GLOBALS *)(DRIVER_GLOBALS_PHYSICAL_MEMORY_START);
	volatile S3C24A0_INTR_REG *s24A0INT = (S3C24A0_INTR_REG *)INT_BASE;
	volatile S3C24A0_DMA_REG *v_pDMAregs = (S3C24A0_DMA_REG *)DMA2_BASE;
	unsigned int temp;
	unsigned int i;

Loop:
	if ( downPtIndex > readPtIndex + cbData )
	{
		memcpy(pbData, readPtIndex, cbData);
		readPtIndex += cbData;
	}
	else if (downPtIndex == DMABUFFER)
	{
		while (downPtIndex == DMABUFFER) {};	// first 64 bytes, get interrupt mode.

		if ( readPtIndex == DMABUFFER )
		{
			memcpy(pbData, readPtIndex, cbData);
			readPtIndex += cbData;
		}

		s24A0INT->SRCPND  = BIT_USBD;
		if (s24A0INT->INTPND & BIT_USBD) s24A0INT->INTPND = BIT_USBD;
		s24A0INT->INTMSK |= BIT_USBD;		// USB Interrupt disable.

		// read data with DMA operation.
		s24A0INT->SUBSRCPND  = BIT_SUB_DMA2;
		s24A0INT->SRCPND  = BIT_DMA_SBUS;
		if (s24A0INT->INTPND & BIT_DMA_SBUS) s24A0INT->INTPND = BIT_DMA_SBUS;
		s24A0INT->INTSUBMSK &= ~BIT_SUB_DMA2;		// DMA Interrupt enable.
		s24A0INT->INTMSK &= ~BIT_DMA_SBUS;		// DMA Interrupt enable.
	
		pUSBCtrlAddr->INDEX.index=3;
		CLR_EP3_OUT_PKT_READY();

		ConfigEp3DmaMode(downPtIndex,DMA_SIZE);

		v_pDMAregs->DIDST=(downPtIndex+DMA_SIZE);	//for 1st autoreload.
		v_pDMAregs->DIDSTC=(1<<2)|(0<<1)|(0<<0);
		v_pDMAregs->DCON=v_pDMAregs->DCON&~(0xfffff)|(DMA_SIZE);


		while((rEP3_DMA_TTC)<0xfffff)
//    if((rEP3_DMA_TTC)<0xfffff)
		{
		  
			pUSBCtrlAddr->EP3DTL.ep3_ttl_l = 0xff;
			pUSBCtrlAddr->EP3DTM.ep3_ttl_m = 0xff;
			pUSBCtrlAddr->EP3DTH.ep3_ttl_h = 0x0f;
			
		}
	}
	else
	{
		i=0;
		temp = rEP3_DMA_TTC;
		while(temp == rEP3_DMA_TTC){
			i++;
			if(i>60000) break;
		}
		if ( (temp == rEP3_DMA_TTC) && (i >60000))
		{
			EdbgOutputDebugString("INFO : UbootReadData : downPtIndex(0x%x) - readPtIndex(0x%x) = 0x%x\r\n", downPtIndex, readPtIndex, downPtIndex - readPtIndex);
			downPtIndex += ((unsigned int)0xfffff - (unsigned int)rEP3_DMA_TTC);
			EdbgOutputDebugString("INFO : UbootReadData : rEP3_DMA_TTC = 0x%x\r\n", rEP3_DMA_TTC);
		}

		goto Loop;
	}

	return TRUE;
}
#pragma optimize ("",on)

⌨️ 快捷键说明

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