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

📄 otg_drv.c

📁 8032底层驱动部分。因为可以移植 所以单独来拿出来
💻 C
📖 第 1 页 / 共 4 页
字号:
	/* HNP failed */
	if(OTG_Is_TimerOut(OTG_TIMER_A_IDLE_BDIS)==KAL_TRUE)
	{
		OTG_Stop_Timer();

		if(g_OtgInfo.a_process_hnp!=KAL_TRUE)
		{
			ASSERT(0);
		}

		g_OtgInfo.a_process_hnp = KAL_FALSE;

		g_OtgInfo.a_hnp_fail_hdlr();
			
		/* B device done not response for HNP, turn off VBUS at this time*/
		g_OtgInfo.otg_state = OTG_STATE_A_WAIT_VFALL;
		/* Turn off VBUS*/
		DRV_WriteReg8(OTG_CTRL, DRV_Reg8(OTG_CTRL)&(~OTG_CTL_VBUS_ON));
	}
	
	/* a_detect_b_conn = FALSE if a RESET interrupt happens and it will set by
      	** the application; a_set_b_hnp_en is false as default and set to
      	** if the request is not stalled
      	*/
	else if((g_OtgInfo.a_detect_b_conn==KAL_FALSE)&&(g_OtgInfo.a_set_b_hnp_enable==KAL_FALSE))
	{
      		g_OtgInfo.otg_state = OTG_STATE_A_WAIT_BCON;

//      	USB_Ms_Dbg_Trace(OTG_STATE_A_SUSPEND_WAIT_B_CON, 0);
	}
      		
      	/*
      	** If the B-device disconnects after the bus has been suspended, 
      	** then this is an indication that the B-device is attempting 
      	** to become Host. When the A-device detects the disconnect 
      	** from the B-device, it shall turn on its D+ pull-up resistor 
      	** within 3 ms (TA_BDIS_ACON max) to acknowledge
      	** the request from the B-device.
      	*/
      	else if((g_OtgInfo.a_detect_b_conn==KAL_FALSE)&&(g_OtgInfo.a_set_b_hnp_enable==KAL_TRUE))
      	{
      		/* stop OTG_TIMER_A_IDLE_BDIS 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_DP_HIGH | OTG_CTL_DM_LOW));
		DRV_WriteReg8(OTG_CTRL, DRV_Reg8(OTG_CTRL)&(~(OTG_CTL_DM_HIGH | OTG_CTL_DP_LOW)));

		g_OtgInfo.otg_state = OTG_STATE_A_PERIPHERAL;
      		g_OtgInfo.a_set_b_hnp_enable = KAL_FALSE;
      		g_OtgInfo.a_process_hnp = KAL_FALSE;
      		g_OtgInfo.a_hnp_stop_hdlr();
      	} /* Endif */

      	else if (g_OtgInfo.a_resume_req==KAL_TRUE) 
      	{
      		/* stop OTG_TIMER_A_IDLE_BDIS timer */
      		OTG_Stop_Timer();
	
      		if(g_OtgInfo.a_process_hnp==KAL_TRUE)
		{
			g_OtgInfo.a_process_hnp = KAL_FALSE;

			g_OtgInfo.a_hnp_fail_hdlr();
		}
      		
      		g_OtgInfo.otg_state = OTG_STATE_A_HOST;
      		USB_HCD_Bus_Control(USB_HCD_BUS_RESUME_SOF);
      		g_OtgInfo.a_resume_req = KAL_FALSE;
      	} 
      	/* OPT remote wakeup*/
      	else if(g_OtgInfo.a_detect_b_resume == KAL_TRUE)
      	{
      		/* stop OTG_TIMER_A_IDLE_BDIS timer */
      		OTG_Stop_Timer();

      		if(g_OtgInfo.a_process_hnp==KAL_TRUE)
		{
			g_OtgInfo.a_process_hnp = KAL_FALSE;

			g_OtgInfo.a_hnp_fail_hdlr();
		}

      		g_OtgInfo.otg_state = OTG_STATE_A_HOST;
      		g_OtgInfo.a_set_b_hnp_enable = KAL_FALSE;
		OTG_Start_Timer(OTG_TIMER_A_REMOTE_WAKEUP, TA_REMOTE_WAKEUP);
      	}

      	/* Activate check VBUS timer */
	if(OTG_Is_TimerActive()==KAL_FALSE)
	{
		OTG_Start_Timer(OTG_TIMER_A_CHECK_VBUS, TA_CHECK_VBUS);
	}
}

static void OTG_Process_A_Peripheral(void)
{
	/* check whether VBUS is maintained above VBUS threshold */
	if(OTG_Is_TimerOut(OTG_TIMER_A_CHECK_VBUS)==KAL_TRUE)
	{
		OTG_Stop_Timer();
		if(OTG_Is_A_Bus_Valid()==KAL_FALSE)
		{
			OTG_Process_A_Vbus_Fail();
			return;
		}
	}
	
#if 1	/* In the curent design, do not allow host init again*/
	/*
      	** A-device detects lack of bus activity for more than 3 ms 
      	** (TA_BIDL_ADIS min) and turns off its D+ pull-up.Alternatively, 
      	** if the A-device has no further need to communicate with the 
      	** B-device, the A-device may turn off VBUS and end the session.
      	** Sleep INT will be processed by the  device ISR a_detect_b_suspend
      	** variable will be set by the application
      	** The following will be done when this happens:
      	**   
      	**   - disconnect its pull up
      	**   - allow time for the data line to discharge
      	**   - check if the B-device has connected its pull up
      	*/
      	if((g_OtgInfo.a_detect_b_suspend) && ((OTG_Is_TimerActive()==KAL_FALSE) || (OTG_Get_TimerType()==OTG_TIMER_A_CHECK_VBUS)))
      	{
      		OTG_Stop_Timer();
      		/* debounce for OPT4.5-2.9ms */
      		OTG_Start_Timer(OTG_TIMER_A_BIDLE_ADIS, TA_BIDL_ADIS);
      	}
      	else if( (g_OtgInfo.a_detect_b_suspend==KAL_FALSE) && (OTG_Is_TimerOut(OTG_TIMER_A_BIDLE_ADIS)==KAL_TRUE))
      	{
		/* resume or reset during debounce time */
		/* stop OTG_TIMER_A_BIDLE_ADIS timer */
		OTG_Stop_Timer();
      	}
      	else if(OTG_Is_TimerOut(OTG_TIMER_A_BIDLE_ADIS) == KAL_TRUE)
      	{
      		OTG_Stop_Timer();
      		
		/* start up host */
      		if((g_OtgInfo.device_up!=KAL_TRUE) || (g_OtgInfo.host_up!=KAL_FALSE))
      			EXT_ASSERT(0, (kal_uint32)g_OtgInfo.device_up, (kal_uint32)g_OtgInfo.host_up, 0);
		
      		g_OtgInfo.device_up = KAL_FALSE;
		g_OtgInfo.device_down_hdlr();
		g_OtgInfo.host_up = KAL_TRUE;
		g_OtgInfo.host_up_hdlr();
		
		DRV_WriteReg8(OTG_CTRL, DRV_Reg8(OTG_CTRL)|(OTG_CTL_DP_LOW | OTG_CTL_DM_LOW));
		DRV_WriteReg8(OTG_CTRL, DRV_Reg8(OTG_CTRL)&(~(OTG_CTL_DP_HIGH | OTG_CTL_DM_HIGH)));

		g_OtgInfo.otg_state = OTG_STATE_A_WAIT_BCON;

//		USB_Ms_Dbg_Trace(OTG_STATE_A_PERIPHERAL_WAIT_B_CON, 0);
      	}
#endif

	/* Activate check VBUS timer */
	if(OTG_Is_TimerActive()==KAL_FALSE)
	{
		OTG_Start_Timer(OTG_TIMER_A_CHECK_VBUS, TA_CHECK_VBUS);
	}

// official should be this , but not suitable for OPT test
#if 0
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
#endif	
}

static void OTG_Process_A_Wait_VFall(void)
{
	if((OTG_Is_B_Session_Valid()==KAL_FALSE)
		||(OTG_Get_Plug_Type()==OTG_PLUG_B))
	{
		g_OtgInfo.otg_state = OTG_STATE_A_IDLE;
		OTG_Stop_Timer();

		/* In current design, conditions that may go here are 
		    1. B device draws too much current
		    2. A device dose not recognize B device and B device dose not take HNP
		    3. B device return from HNP host
		*/
		g_OtgInfo.a_bus_req = KAL_FALSE;

		OTG_Process_A_Idle();
	} /* Endif */
}

static void OTG_Process_B_Idle(void)
{
	/* reset HNP enabled state */
	g_OtgInfo.b_hnp_enable = KAL_FALSE;
	
	/* If host or device is up, pull it down*/
	if(g_OtgInfo.host_up==KAL_TRUE)
	{
		g_OtgInfo.host_up = KAL_FALSE;
		g_OtgInfo.host_down_hdlr();
	}
	if(g_OtgInfo.device_up==KAL_TRUE)
	{
		g_OtgInfo.device_up = KAL_FALSE;
		g_OtgInfo.device_down_hdlr();
	}	
	DRV_WriteReg8(OTG_CTRL, DRV_Reg8(OTG_CTRL)&
				(~(OTG_CTL_DP_HIGH | OTG_CTL_DM_HIGH | OTG_CTL_DP_LOW |OTG_CTL_DM_LOW)) );

	/*
	** When a B-device detects that the voltage on VBUS is greater 
	** than the B-Device Session Valid threshold (VSESS_VLD), 
	** then the B-device shall consider a session to be in progress. 
	** After the VBUS voltage crosses this threshold, the B-device 
	** shall assert either the D+ or D- data-line within 100 ms.
	*/
	if(g_OtgInfo.b_session_valid==KAL_TRUE)
	{
		OTG_Process_B_Session_Valid();
	}
	else if(g_OtgInfo.b_srp_request==KAL_TRUE)
	{
		/*  ********* Starting  SRP *****************************************
		** When the B-device detects that VBUS has gone below its Session End 
		** threshold and detects that both D+ and D- have been low (SE0) for 
		** at least 2 ms (TB_SE0_SRP min), then any previous session on the 
		** A-device is over and a new session may start. The B-device may 
		** initiate the SRP any time the initial conditions of Section 5.3.2 
		** are met.
		*/
		/* activate the timer only if we want to do SRP */
		if(OTG_Is_TimerActive() == KAL_FALSE)
		{
			OTG_Start_Timer(OTG_TIMER_B_SE0_SRP, TB_SE0_SRP);

			/* mask all interrupt in case interrupt happens during SRP 
			    The only interrupt tat be be taken is session valid interrupt (by EINT)*/
			DRV_WriteReg8(USB_INT_ENB, 0);
		}

		/* timeout and below session end*/
		if((OTG_Is_TimerOut(OTG_TIMER_B_SE0_SRP)) &&
			(OTG_Is_B_Session_End()==KAL_TRUE))
		{
			OTG_Stop_Timer();

			/*
			** initial conditions are met as described above and then turns 
			** on its data line pull-up resistor (either D+ or D-) for a 
			** period of 5 ms to 10 ms (TB_DATA_PLS). A dual-role B-device is 
			** only allowed to initiate SRP at full-speed, and thus shall 
			** only pull up D+. The duration of such a data line pulse is 
			** sufficient to allow the A-device to reject spurious voltage 
			** transients on the data lines.
			*/
			DRV_WriteReg8(OTG_CTRL, DRV_Reg8(OTG_CTRL)|OTG_CTL_DP_HIGH);

			OTG_Start_Timer(OTG_TIMER_B_DATA_PLS, TB_DATA_PLS);
			
			g_OtgInfo.otg_state = OTG_STATE_B_SRP_INIT;			
			g_OtgInfo.b_check_session = KAL_TRUE;
		}	
	}
}

static void OTG_Process_B_Session_Valid(void)
{	
	if(g_OtgInfo.otg_state==OTG_STATE_B_SRP_INIT)
	{
		/* This section is executed in USB task context*/
		OTG_Stop_Timer();

      		/* DP High off*/
      		DRV_WriteReg8(OTG_CTRL, DRV_Reg8(OTG_CTRL)&(~OTG_CTL_DP_HIGH));
      		/* VBUS charge off */
		DRV_WriteReg8(OTG_CTRL, DRV_Reg8(OTG_CTRL)&(~OTG_CTL_VBUS_CHG));
		/* VBUS discharge off*/
		DRV_WriteReg8(OTG_CTRL, DRV_Reg8(OTG_CTRL)&(~OTG_CTL_VBUS_DSCHG));

		/* restore the interrupt masked during SRP */
		DRV_WriteReg8(USB_INT_ENB, 0xff&(~(VUSB_INT_ENB_SOF|VUSB_INT_ENB_RESUME)));
	}
	else if(g_OtgInfo.b_srp_request==KAL_TRUE )
	{
		/* In case still measure B session end */
		/* This section is executed in USB task context*/
		OTG_Stop_Timer();

		/* restore the interrupt masked during SRP */
		DRV_WriteReg8(USB_INT_ENB, 0xff&(~(VUSB_INT_ENB_SOF|VUSB_INT_ENB_RESUME)));

		g_OtgInfo.b_srp_stop_hdlr();
	}	

	/* init device */
	if(g_OtgInfo.device_up!=KAL_FALSE)
		EXT_ASSERT(0, (kal_uint32)g_OtgInfo.device_up, 0, 0);

	g_OtgInfo.device_up = KAL_TRUE;
	g_OtgInfo.device_up_hdlr();	
	//DRV_WriteReg8(OTG_CTRL, DRV_Reg8(OTG_CTRL)|(OTG_CTL_DP_HIGH | OTG_CTL_DM_LOW));
	DRV_WriteReg8(OTG_CTRL, DRV_Reg8(OTG_CTRL)&(~(OTG_CTL_DM_HIGH | OTG_CTL_DP_LOW)));

	g_OtgInfo.b_srp_request = KAL_FALSE;
	g_OtgInfo.otg_state = OTG_STATE_B_PERIPHERAL;
}

static void OTG_Process_B_SRP_Init(void)
{
	if(OTG_Is_B_Session_Valid()==KAL_TRUE)
		g_OtgInfo.b_session_valid = KAL_TRUE;
	
	/*
	** When a B-device detects that the voltage on VBUS is greater than the 
	** B-Device Session Valid threshold (VSESS_VLD), then the B-device 
	** shall consider a session to be in progress. After the VBUS voltage
	** crosses this threshold, the B-device shall assert either the D+ or 
	** D- data-line within 100 ms(TB_SVLD_BCON max).
	*/
	//if((DRV_Reg8(OTG_STATUS)&OTG_STATUS_SESS_VLD) && (g_OtgInfo.b_check_session==KAL_TRUE))
	if((g_OtgInfo.b_session_valid==KAL_TRUE) && (g_OtgInfo.b_check_session==KAL_TRUE))
	{
		OTG_Process_B_Session_Valid();
	}
	else 
	{
		/* check_srp_activity */
		if(OTG_Is_TimerOut(OTG_TIMER_B_DATA_PLS)==KAL_TRUE)
		{
			OTG_Stop_Timer();
	
			/* DP High off*/
      			DRV_WriteReg8(OTG_CTRL, DRV_Reg8(OTG_CTRL)&(~OTG_CTL_DP_HIGH));

			/* An A-device is only required to respond to one of the two 
			** SRP signaling methods. A B-device shall use both methods 
			** when initiating SRP to insure that the A-device responds.
			*/
			g_OtgInfo.b_check_session = KAL_FALSE;

			/* VBUS charge */
			DRV_WriteReg8(OTG_CTRL, DRV_Reg8(OTG_CTRL)|OTG_CTL_VBUS_CHG);
			
			/* Turn on the timer so as to keep VBUS pusling ON for 8 ms */
			OTG_Start_Timer(OTG_TIMER_B_VBUS_PLS, TB_VBUS_PLS);
		}
		else if(OTG_Is_TimerOut(OTG_TIMER_B_VBUS_PLS)==KAL_TRUE)
		{
			OTG_Stop_Timer();

			/* VBUS charge off */
			DRV_WriteReg8(OTG_CTRL, DRV_Reg8(OTG_CTRL)&(~OTG_CTL_VBUS_CHG));

			/* VBUS discharge */
			//DRV_WriteReg8(OTG_CTRL, DRV_Reg8(OTG_CTRL)|OTG_CTL_VBUS_DSCHG);

			OTG_Start_Timer(OTG_TIMER_B_VBUS_DSCHG, TB_VBUS_DSCHRG);
		}
		else if(OTG_Is_TimerOut(OTG_TIMER_B_VBUS_DSCHG)==KAL_TRUE)
		{
			OTG_Stop_Timer();

			/* VBUS discharge off*/
			DRV_WriteReg8(OTG_CTRL, DRV_Reg8(OTG_CTRL)&(~OTG_CTL_VBUS_DSCHG));
			g_OtgInfo.b_check_session = KAL_TRUE;

			/* If session is valid then proceed */
			if(g_OtgInfo.b_session_valid==KAL_TRUE)
			{
				OTG_Process_B_Session_Valid();
			}
			else
			{
				/* start the fail timer*/
				OTG_Start_Timer(OTG_TIMER_B_SRP_FAIL, TB_SRP_FAIL);
			}
		}

		/*
		** The error call back have the following requirement:
		** After initiating SRP, the B-device is required to wait at least 
		** 5 seconds (TB_TB_SRP_FAIL min) for the A-device to respond, 
		** before informing the user that the communication attempt 
		** has failed.
		**
		*/
		else if (OTG_Is_TimerOut(OTG_TIMER_B_SRP_FAIL) == KAL_TRUE)
		{
			OTG_Stop_Timer();

			g_OtgInfo.b_srp_request = KAL_FALSE;
			
			g_OtgInfo.otg_state = OTG_STATE_B_IDLE;

			g_OtgInfo.b_srp_fail_hdlr();

			OTG_Process_B_Idle();

			/* restore the interrupt masked during SRP */
			DRV_WriteReg8(USB_INT_ENB, 0xff&(~(VUSB_INT_ENB_SOF|VUSB_INT_ENB_RESUME)));		
		}
	} 
}

static void OTG_Process_B_Peripheral(void)
{
	/* b_detect_a_suspend (SLEEP_INT) will be processed by the DEVICE ISR */
      	/*
      	** B-device detects that bus is idle for more than 3 ms 
      	** (TB_AIDL_BDIS min) and begins HNP by turning off pull-up on D+. 
      	** This allows the bus to discharge to the SE0 state. 
      	** The following will be done when this happens:
      	**   
      	**   disconnect its pull up
      	**   allow time for the data line to discharge
      	**   check if the A-device has connected its pull up
      	*/
	if((g_OtgInfo.b_hnp_enable==KAL_TRUE) && (g_OtgInfo.b_detect_a_suspend==KAL_TRUE) && 
		(OTG_Is_TimerActive()==KAL_FALSE))
	{
		OTG_Start_Timer(OTG_TIMER_A_BUS_SUSPEND, TB_A_SUSPEND);
	}
	else if(OTG_Is_TimerOut(OTG_TIMER_A_BUS_SUSPEND)==KAL_TRUE)	
	{
		OTG_Stop_Timer();

		g_OtgInfo.b_detect_a_suspend = KAL_FALSE;
		
		/* start up host */
      		if((g_OtgInfo.device_up!=KAL_TRUE) || (g_OtgInfo.host_up!=KAL_FALSE))
      			EXT_ASSERT(0, (kal_uint32)g_OtgInfo.device_up, (kal_uint32)g_OtgInfo.host_up, 0);
		
      		g_OtgInfo.device_up = KAL_FALSE;
		g_OtgInfo.device_down_hdlr();
		g_OtgInfo.host_up = KAL_TRUE;
		g_OtgInfo.host_up_hdlr();

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

		g_OtgInfo.otg_state = OTG_STATE_B_WAIT_ACON;
		
      		/* start timer to wait A connect*/		

⌨️ 快捷键说明

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