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

📄 otg_drv.c

📁 8032底层驱动部分。因为可以移植 所以单独来拿出来
💻 C
📖 第 1 页 / 共 4 页
字号:
		OTG_Start_Timer(OTG_TIMER_B_ASE0_BRST, TB_ASE0_BRST);
	}
}

static void OTG_Process_B_Wait_ACon(void)
{
	/*
      	** After waiting long enough to insure that the D+ line 
      	** cannot be high due to the residual effect of the B-device 
      	** pull-up,(see Section 5.1.9), the B-device sees that the 
      	** D+ line is high and D- low, (i.e. J state). This indicates 
      	** that the A-device has recognized the HNP request from the 
      	** B-device. At this point, the B-device becomes Host and 
      	** asserts bus reset to start using the bus. The B-device 
      	** must assert the bus reset (SE0) within 1 ms (TB_ACON_BSE0 max) 
      	** of the time that the A-device turns on its
      	** pull-up.
      	*/
      	/* ATTACH_INT will be processed by the host ISR */
      	if (g_OtgInfo.b_detect_a_conn) 
      	{
      		OTG_Stop_Timer();
      		g_OtgInfo.b_suspend_req = KAL_FALSE;
      		g_OtgInfo.b_hnp_enable = KAL_FALSE;
      		g_OtgInfo.otg_state = OTG_STATE_B_HOST;
      		return;
      	} /* Endif */

      	/*
      	** While waiting in the b_wait_acon state, the B-device 
      	** may detect a K state on the bus. This indicates that the 
      	** A-device is signaling a resume condition and is retaining 
      	** control of the bus. In this case, the B-device will return 
      	** to the b_peripheral state.
      	*/
      	/* 
      	** b_detect_a_resume will be set by the host ISR when K state is 
      	** detected  if (b_detect_a_resume || b_ase0_brst_tmr) 
      	*/
      	else if ((g_OtgInfo.b_detect_a_resume==KAL_TRUE) || 
      		(OTG_Is_TimerOut(OTG_TIMER_B_ASE0_BRST) == KAL_TRUE)) 
      	{
		g_OtgInfo.b_detect_a_resume = KAL_FALSE;

		g_OtgInfo.b_hnp_enable = KAL_FALSE;

		
		/* HNP fail,  this is caused by A device dose not pull up D+*/
		/***********************************************************
      		OPT test 5.8 and 5.9 require that we must display a message
      		when a HNP fails. This event should allow the application
      		to know  that HNP failed with Host.            
      		***********************************************************/
      		if(OTG_Is_TimerOut(OTG_TIMER_B_ASE0_BRST) == KAL_TRUE)
		{
			/* time out */
			g_OtgInfo.b_hnp_fail_hdlr();
		}

      		/* stop the timer */
      		OTG_Stop_Timer();
		
		/* start up device*/
      		if((g_OtgInfo.host_up!=KAL_TRUE) || (g_OtgInfo.device_up!=KAL_FALSE))
      			EXT_ASSERT(0, (kal_uint32)g_OtgInfo.host_up, (kal_uint32)g_OtgInfo.device_up, 0);

		g_OtgInfo.host_up = KAL_FALSE;
		g_OtgInfo.host_down_hdlr();
      		g_OtgInfo.device_up = KAL_TRUE;
		g_OtgInfo.device_up_hdlr();

		DRV_WriteReg8(OTG_CTRL, DRV_Reg8(OTG_CTRL)&(~(OTG_CTL_DM_HIGH | OTG_CTL_DP_LOW)));

		g_OtgInfo.otg_state = OTG_STATE_B_PERIPHERAL;
      	} 
}

static void OTG_Process_B_Host(void)
{
	/* 
      	** If the B-device at any time detects more than 3.125 ms of SE0 
      	** (TB_ASE0_BRST min), then this is an indication that the 
      	** A-device is remaining Host and is resetting the bus. In this 
      	** case the B-device shall return to the b_peripheral state 
      	** and start to process the bus reset before TB_ASE0_BRST max.
      	*/

	if((g_OtgInfo.b_suspend_req==KAL_TRUE) || (g_OtgInfo.b_detect_a_conn==KAL_FALSE))
	{
      		/* start up device*/
      		if((g_OtgInfo.host_up!=KAL_TRUE) || (g_OtgInfo.device_up!=KAL_FALSE))
      			EXT_ASSERT(0, (kal_uint32)g_OtgInfo.host_up, (kal_uint32)g_OtgInfo.device_up, 0);

		g_OtgInfo.host_up = KAL_FALSE;
		g_OtgInfo.host_down_hdlr();
      		g_OtgInfo.device_up = KAL_TRUE;
		g_OtgInfo.device_up_hdlr();

		DRV_WriteReg8(OTG_CTRL, DRV_Reg8(OTG_CTRL)&(~(OTG_CTL_DM_HIGH | OTG_CTL_DP_LOW)));

		g_OtgInfo.otg_state = OTG_STATE_B_PERIPHERAL;		
	}	
}

kal_bool  OTG_Process_Exceptions(void)
{
	OTG_STATE previous_state = g_OtgInfo.otg_state;

	/* Check exception for A device */
	if ((g_OtgInfo.otg_state < OTG_STATE_B_IDLE)) 
	{
		/* 
		** Exceptions are as follows.
		** 1. Transition to B_IDLE when id = TRUE.
		** 2. Transition to A_WAIT_VFALL when V_BUS is voltage is fallen below 
		** 3. 4 VDC or not able to set the V_BUS voltage.
		*/ 
		if((OTG_Get_Plug_Type()==OTG_PLUG_B) ||
			(OTG_Is_A_Bus_Valid()==KAL_FALSE))
		{
			/* stop any active timers*/
			/* stop the timer */
			OTG_Stop_Timer();

			if ((g_OtgInfo.otg_state== OTG_STATE_A_IDLE) && 
				(OTG_Get_Plug_Type()==OTG_PLUG_B))
			{
				g_OtgInfo.otg_state = OTG_STATE_B_IDLE;
				if(g_OtgInfo.b_srp_request==KAL_TRUE)
					g_OtgInfo.b_srp_stop_hdlr();
				g_OtgInfo.b_srp_request = KAL_FALSE;
				OTG_Process_B_Idle();
			}
			else if((g_OtgInfo.otg_state!=OTG_STATE_A_IDLE) && (g_OtgInfo.otg_state!=OTG_STATE_A_WAIT_VFALL))
			{
				if(g_OtgInfo.a_process_hnp==KAL_TRUE)
					g_OtgInfo.a_hnp_stop_hdlr();	
				g_OtgInfo.a_process_hnp = KAL_FALSE;
				
				g_OtgInfo.otg_state = OTG_STATE_A_WAIT_VFALL;
				/* Turn off VBUS*/
				DRV_WriteReg8(OTG_CTRL, DRV_Reg8(OTG_CTRL)&(~OTG_CTL_VBUS_ON));	
				
				OTG_Process_A_Wait_VFall();
			}
		}
	}
	else 
	{
		/*
		** Process B- device exceptions
		*/
		if((OTG_Get_Plug_Type()==OTG_PLUG_A)||
			((g_OtgInfo.b_session_valid==KAL_FALSE)&&(g_OtgInfo.otg_state!=OTG_STATE_B_SRP_INIT)))	
		{
			if(g_OtgInfo.b_srp_request==KAL_TRUE)
				g_OtgInfo.b_srp_stop_hdlr();
			g_OtgInfo.b_srp_request = KAL_FALSE;
	
			if(OTG_Get_Plug_Type()==OTG_PLUG_B)
			{
				g_OtgInfo.otg_state = OTG_STATE_B_IDLE;
				OTG_Process_B_Idle();
			}
			else
			{
				g_OtgInfo.otg_state = OTG_STATE_A_IDLE;
				g_OtgInfo.a_bus_req = KAL_TRUE;
				OTG_Process_A_Idle();
			}
		} 
	}

	if (g_OtgInfo.otg_state!= previous_state)
	{
		/* state changed, exception is processed*/
		return KAL_TRUE;
	}
	else 
	{
		/* state not changed, exception is not processed*/
		return KAL_FALSE;
	}
}

static void OTG_State_Machine(void)
{
	static kal_bool	b_processing = KAL_FALSE;

	if(b_processing==KAL_TRUE)
		ASSERT(0);
	b_processing = KAL_TRUE;

	switch (g_OtgInfo.otg_state) 
	{
	case OTG_STATE_START:
		if(OTG_Get_Plug_Type()==OTG_PLUG_B)
      		{
      			g_OtgInfo.otg_state = OTG_STATE_B_IDLE;
      			OTG_Process_B_Idle();
      		}
      		else 
      		{
      			/* ID is false when A device is identified */
      			g_OtgInfo.a_bus_req = KAL_TRUE;
      			g_OtgInfo.otg_state = OTG_STATE_A_IDLE;
      			OTG_Process_A_Idle();
      		}
		break;
	case OTG_STATE_A_IDLE:
		OTG_Process_A_Idle();
		break;
	case OTG_STATE_A_WAIT_VRISE:
		OTG_Process_A_Wait_VRise();
		break;
	case OTG_STATE_A_WAIT_BCON:
		OTG_Process_A_Wait_BCon();
		break;
	case OTG_STATE_A_HOST:
		OTG_Process_A_Host();
		break;
	case OTG_STATE_A_SUSPEND:
		OTG_Process_A_Suspend();
		break;
	case OTG_STATE_A_PERIPHERAL:
		OTG_Process_A_Peripheral();
		break;
	case OTG_STATE_A_WAIT_VFALL:
		OTG_Process_A_Wait_VFall();
		break;
	case OTG_STATE_B_IDLE:
		OTG_Process_B_Idle();
		break;
	case OTG_STATE_B_SRP_INIT:
		OTG_Process_B_SRP_Init();
		break;
	case OTG_STATE_B_PERIPHERAL:
		OTG_Process_B_Peripheral();
		break;
	case OTG_STATE_B_WAIT_ACON:
		OTG_Process_B_Wait_ACon();
		break;
	case OTG_STATE_B_HOST:
		OTG_Process_B_Host();
		break;
	default:
		ASSERT(0);
		break;
	}

	b_processing = KAL_FALSE;
}



static void OTG_HISR(void)
{
	kal_bool	b_dev_unmask_irq = KAL_TRUE;
	kal_bool	b_process_state_machine = KAL_FALSE;
	kal_uint32 savedMask;
	volatile kal_uint8	IntrStatus;

	g_OtgInfo.otg_intr_status = DRV_Reg8(OTG_INT_STAT)&DRV_Reg8(OTG_INT_EN);
	IntrStatus = DRV_Reg8(USB_INT_STAT)&DRV_Reg8(USB_INT_ENB);
	
	/* process OTG state machine*/
	if( g_OtgInfo.otg_intr_status)
	{
		if(g_OtgInfo.otg_intr_status&OTG_INT_STATUS_1_MSEC)
			OTG_Check_Timer();
		savedMask = SaveAndSetIRQMask();
		if(g_OtgInfo.b_processing == KAL_FALSE)
		{
			g_OtgInfo.b_processing = KAL_TRUE;
			b_process_state_machine = KAL_TRUE;
		}
		RestoreIRQMask(savedMask);

		if(b_process_state_machine==KAL_TRUE)
		{
			OTG_State_Machine();
			g_OtgInfo.b_processing = KAL_FALSE;
		}
	} 

	if(g_OtgInfo.host_up==KAL_TRUE)
	{
		/* Check data line pulsing by B device */
		if ((g_OtgInfo.otg_state == OTG_STATE_A_IDLE) && (g_OtgInfo.a_bus_req==KAL_FALSE) &&  
			(IntrStatus & VUSB_INT_STAT_ATTACH) && (g_OtgInfo.a_process_srp == KAL_FALSE)) 
		{
			OTG_Set_Status(OTG_STATUS_A_DETECT_B_DATA_PLS, KAL_TRUE);
			/* clear interrupt and unmask interrupt*/
		   	IRQClearInt(IRQ_USB_CODE);
			if((g_OtgInfo.b_unmask_irq==KAL_TRUE) && (USB_HCD_Get_UnMask_Irq()==KAL_TRUE))
	   			IRQUnmask(IRQ_USB_CODE);
			return ;
		} /* Endif */
			
		USB_HCD_HISR();
		b_dev_unmask_irq = USB_HCD_Get_UnMask_Irq();
	}
	else if(g_OtgInfo.device_up==KAL_TRUE)
	{
		USB_HISR();
		b_dev_unmask_irq = USB_Get_UnMask_Irq();
	}
	else
	{
		DRV_Reg8(USB_INT_STAT) = IntrStatus;
	}


	DRV_Reg8(OTG_INT_STAT) = g_OtgInfo.otg_intr_status;
	/* clear interrupt and unmask interrupt*/
   	IRQClearInt(IRQ_USB_CODE);
   	g_OtgInfo.is_ProOTGHISR = KAL_FALSE;
	if((g_OtgInfo.b_unmask_irq==KAL_TRUE) && (b_dev_unmask_irq == KAL_TRUE))
	   	IRQUnmask(IRQ_USB_CODE);
}

static void OTG_LISR(void)
{
	IRQMask(IRQ_USB_CODE);
	g_OtgInfo.is_ProOTGHISR = KAL_TRUE;
	drv_active_hisr(DRV_USB_HISR_ID);
}



/************************************************************
	A plug detection functions
*************************************************************/

/* Detect whether A plug is plug in when power on */
kal_bool OTG_PowerOn_Is_A_Plug(void)
{
	volatile kal_uint32 delay;
	kal_uint32 nfiq_status;
	
    #ifndef __CUST_NEW__
	/*GPIO mode setting as NFIQ*/
	GPIO_ModeSetup(63, 0x01);
    #endif /* __CUST_NEW__ */
	
	/*level trigger*/
	IRQSensitivity(IRQ_GPI_CODE,KAL_FALSE);
	//level=DRV_Reg32(IRQ_SENSL);	   	   		
	//DRV_WriteReg32(IRQ_SENSL, (level|0x00020000));	   	
	
	IRQUnmask(IRQ_GPI_CODE);	
	for(delay=0;delay<300;delay++);
	nfiq_status=DRV_Reg32(IRQ_STS2);
	IRQMask(IRQ_GPI_CODE);
	
	/* A-plug detect */
	if(nfiq_status&IRQCode2Line[IRQ_GPI_CODE])  
	{   
		*IRQ_EOI2 = nfiq_status; 
		return KAL_TRUE;
	}
	else
	{
		return KAL_FALSE;
	}	   
}

void OTG_Init_A_Plug_Detect(void)
{
	/* ID pin detection*/
	nFIQ_Init(OTG_A_Plug_HISR, KAL_TRUE, KAL_FALSE, LEVEL_SENSITIVE); /* not auto unmask*/	

	if (g_OtgInfo.a_plug_gpt_handle == 0)
		GPTI_GetHandle(&g_OtgInfo.a_plug_gpt_handle);

	g_OtgInfo.a_plug_intr_allow = KAL_FALSE;
	g_OtgInfo.plug_type = OTG_PLUG_B;
}

static void OTG_A_Plug_Timer_Callback(void *data)
{
	GPTI_StopItem(g_OtgInfo.a_plug_gpt_handle);

	g_OtgInfo.a_plug_intr_allow = (g_OtgInfo.a_plug_intr_allow == KAL_TRUE)? KAL_FALSE: KAL_TRUE;

   /*
    * This timer is to avoid if interrupt status is changed but 
    * sw_debounce->eint_intr_allow is still in KAL_TRUE state
    * because of no interrupt
    */
	if (g_OtgInfo.a_plug_intr_allow) 
	{
		GPTI_StartItem(g_OtgInfo.a_plug_gpt_handle, 5,  OTG_A_Plug_Timer_Callback, data);
	}

	IRQUnmask(IRQ_GPI_CODE);  	
}

static void OTG_A_Plug_HISR(void)
{
	ilm_struct *mfiq_ilm;

	GPTI_StopItem(g_OtgInfo.a_plug_gpt_handle);
       if ( g_OtgInfo.a_plug_intr_allow == KAL_FALSE)
       {
		 GPTI_StartItem(g_OtgInfo.a_plug_gpt_handle, 5, OTG_A_Plug_Timer_Callback, &g_OtgInfo.a_plug_gpt_handle);
		 IRQClearInt(IRQ_GPI_CODE);
       }
       else
       {
       	g_OtgInfo.a_plug_intr_allow = KAL_FALSE;
       
		if(DRV_Reg(GPIO_DINV4)&0x8000)
		{
			/* inverse */
            #ifdef __CUST_NEW__
			GPIO_DinvSetup(63, KAL_FALSE);
            #else /* __CUST_NEW__ */
			DRV_WriteReg(GPIO_DINV4, DRV_Reg(GPIO_DINV4)&(~0x8000));
            #endif /* __CUST_NEW__ */
			OTG_Set_Plug_Type(OTG_PLUG_B);
			DRV_BuildPrimitive(mfiq_ilm,
							MOD_DRV_HISR,
							MOD_USB,
							MSG_ID_USB_A_PLUGOUT_IND,
							NULL);
			msg_send_ext_queue(mfiq_ilm);
		}
		else
		{
			/* inverse */
            #ifdef __CUST_NEW__
			GPIO_DinvSetup(63, KAL_TRUE);
            #else /* __CUST_NEW__ */
			DRV_WriteReg(GPIO_DINV4, DRV_Reg(GPIO_DINV4)|0x8000);
            #endif /* __CUST_NEW__ */
			OTG_Set_Plug_Type(OTG_PLUG_A);
			DRV_BuildPrimitive(mfiq_ilm,
							MOD_DRV_HISR,
							MOD_USB,
							MSG_ID_USB_A_PLUGIN_IND,
							NULL);
			msg_send_ext_queue(mfiq_ilm);
		}

		IRQClearInt(IRQ_GPI_CODE);
	   	IRQUnmask(IRQ_GPI_CODE);  	
       }	 	
}

#endif

 

⌨️ 快捷键说明

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