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

📄 otg_drv.c

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

OTG_STATE OTG_Get_State(void)
{
	return g_OtgInfo.otg_state;
}

void OTG_Enable_Device(void)
{
	DRV_WriteReg8(OTG_CTRL, DRV_Reg8(OTG_CTRL)|(OTG_CTL_DP_HIGH | OTG_CTL_DM_LOW));	
}


/************************************************************
	ADC  functions
*************************************************************/
static kal_uint32 OTG_Get_VBUS_Volt(void)
{
	kal_uint8 adc_channel;
	bmt_customized_struct  *charing_para;
	kal_uint16 adc;
	kal_int32 volt;

	adc_channel = custom_adc_get_channel(otg_vbus_adc_channel);

	charing_para=bmt_get_customized_chr_para();

	adc = ADC_GetData(adc_channel);
	volt = (kal_int32)((adc_adc2vol(adc_channel, (double)adc)/100)*charing_para->adc_volt_factor[adc_channel]);

	return volt;
}

static kal_bool OTG_Is_A_Bus_Valid(void)
{
	kal_bool ret = KAL_FALSE;
	kal_uint32 volt;

	volt = OTG_Get_VBUS_Volt();

	if(volt>=4400000)
		ret = KAL_TRUE;

	return ret;
}

static kal_bool OTG_Is_B_Session_Valid(void)
{
	kal_bool ret = KAL_FALSE;
	kal_uint32 volt;

	volt = OTG_Get_VBUS_Volt();

	if(volt>=2100000)
		ret = KAL_TRUE;

	return ret;
}

static kal_bool OTG_Is_B_Session_End(void)
{
	kal_bool ret = KAL_FALSE;
	kal_uint32 volt;

	volt = OTG_Get_VBUS_Volt();

	if(volt<=800000)
		ret = KAL_TRUE;

	return ret;
}


/************************************************************
	Timer  functions
*************************************************************/

/* GPT timeout handler */
static void OTG_Timeout_Hdlr(void *parameter)
{
	kal_bool	b_process_state_machine = KAL_FALSE;
	kal_uint32 savedMask;
	kal_bool b_dev_unmask_irq = KAL_TRUE;

	GPTI_StopItem(g_OtgInfo.gpt_handle);

	/* process OTG state machine*/
	savedMask = SaveAndSetIRQMask();
	g_OtgInfo.timer_out = KAL_TRUE;

	if(g_OtgInfo.b_processing == KAL_FALSE)
	{	
		g_OtgInfo.b_processing = KAL_TRUE;
		b_process_state_machine = KAL_TRUE;
		IRQMask(IRQ_USB_CODE);
	}
	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)
			b_dev_unmask_irq = USB_HCD_Get_UnMask_Irq();
		else if(g_OtgInfo.device_up==KAL_TRUE)
			b_dev_unmask_irq = USB_Get_UnMask_Irq();
		if((g_OtgInfo.b_unmask_irq==KAL_TRUE) && (b_dev_unmask_irq == KAL_TRUE))
		   	IRQUnmask(IRQ_USB_CODE);
	}
}


/* The tick uint is ms*/
static void OTG_Start_Timer(OTG_TIMER_TYPE type, kal_uint32 ticks)
{
	if(g_OtgInfo.timer_on==KAL_TRUE)
		EXT_ASSERT(0, (kal_uint32)g_OtgInfo.timer_on, (kal_uint32)g_OtgInfo.timer_type, (kal_uint32)g_OtgInfo.timer_out);

	g_OtgInfo.timer_type = type;
	g_OtgInfo.timer_on = KAL_TRUE;
	g_OtgInfo.timer_out = KAL_FALSE;

	/* If timer is longer than 20 ms, use GPT timer interrupt*/
	if(ticks<20)
	{
		GPT_Start(3);
		/* determine the time out value*/
		g_OtgInfo.timeout_tick = (kal_uint32)GPT_return_current_count();
		g_OtgInfo.timeout_tick+=ticks;
		g_OtgInfo.timeout_tick = g_OtgInfo.timeout_tick&0xffff;
		DRV_WriteReg8(OTG_INT_EN, DRV_Reg8(OTG_INT_EN)|OTG_INT_ENABLE_1_MSEC);
	}
	else
	{
		GPTI_StartItem(g_OtgInfo.gpt_handle, (ticks/10), OTG_Timeout_Hdlr, &g_OtgInfo);
	}	
}

/* stop the timer */
static void OTG_Stop_Timer(void)
{
	DRV_WriteReg8(OTG_INT_EN, DRV_Reg8(OTG_INT_EN)&(~OTG_INT_ENABLE_1_MSEC));	
	GPT_Stop(3);
	GPTI_StopItem(g_OtgInfo.gpt_handle);
	
	g_OtgInfo.timer_on = KAL_FALSE;
	g_OtgInfo.timer_out = KAL_FALSE;	
	g_OtgInfo.timer_type = OTG_TIMER_NONE;	
}

/* used by OTG HISR to chek if timer is timeout or not */
static kal_bool OTG_Check_Timer(void)
{
	kal_uint32 cur_timer_tick;
	kal_bool ret = KAL_FALSE;

	if(g_OtgInfo.timer_on==KAL_FALSE)
		EXT_ASSERT(0, (kal_uint32)g_OtgInfo.timer_on, (kal_uint32)g_OtgInfo.timer_type, (kal_uint32)g_OtgInfo.timer_out);
		
	cur_timer_tick = (kal_uint32)GPT_return_current_count();
	if(cur_timer_tick>=g_OtgInfo.timeout_tick)
	{
		g_OtgInfo.timer_out = KAL_TRUE;
		ret = KAL_TRUE;
	}
	else

	{
		ret = KAL_FALSE;
	}

	return ret;
}

/* return KAL_TRUE if "type" timer is timeout */
static kal_bool OTG_Is_TimerOut(OTG_TIMER_TYPE type)
{
	kal_bool ret = KAL_FALSE;
	
	if((g_OtgInfo.timer_out==KAL_TRUE)&&(g_OtgInfo.timer_type==type))
		ret = KAL_TRUE;

	return ret;
}

/* return if any timer is active*/
static kal_bool OTG_Is_TimerActive(void)
{
	kal_bool	ret = KAL_FALSE;
	
	if((g_OtgInfo.timer_on == KAL_TRUE) || (g_OtgInfo.timer_out == KAL_TRUE))
		ret = KAL_TRUE;

	return ret;
}

/* return active timer type */
static OTG_TIMER_TYPE OTG_Get_TimerType(void)
{
	return g_OtgInfo.timer_type;		
}

/************************************************************
	state machine functions
*************************************************************/
static void OTG_Process_A_Vbus_Fail(void)
{
	/* Restore interrupt. Enable Attach interrupt only */            
	DRV_WriteReg8(USB_INT_ENB, VUSB_INT_ENB_ATTACH);	
			
	g_OtgInfo.otg_state = OTG_STATE_A_WAIT_VFALL;

	/* Turn off VBUS*/
	DRV_WriteReg8(OTG_CTRL, DRV_Reg8(OTG_CTRL)&(~OTG_CTL_VBUS_ON));

	if(g_OtgInfo.host_up==KAL_TRUE)
	{
		g_OtgInfo.host_up = KAL_FALSE;
		g_OtgInfo.a_host_stop_hdlr();
		g_OtgInfo.host_down_hdlr();
	}
	if(g_OtgInfo.device_up==KAL_TRUE)
	{
		g_OtgInfo.device_up = KAL_FALSE;
		g_OtgInfo.device_down_hdlr();
	}	

	/* Notify MMI device draws too much current */
	g_OtgInfo.a_vrise_fail_hdlr();
}

static void OTG_Process_A_Idle(void)
{
	if(OTG_Get_Plug_Type()==OTG_PLUG_B)
      	{
      		g_OtgInfo.otg_state = OTG_STATE_B_IDLE;
      		OTG_Process_B_Idle();
      		return;
      	}

	if(g_OtgInfo.a_detect_b_data_pls==KAL_TRUE)
	{
		g_OtgInfo.a_detect_b_data_pls = KAL_FALSE;
		g_OtgInfo.a_process_srp = KAL_TRUE;
		OTG_Start_Timer(OTG_TIMER_A_DATA_PLS, TA_DATA_PLS);
	}
	else if(OTG_Is_TimerOut(OTG_TIMER_A_DATA_PLS)==KAL_TRUE)	
	{
		OTG_Stop_Timer();
		g_OtgInfo.a_process_srp = KAL_FALSE;

		if((DRV_Reg8(USB_CTL)&VUSB_CTL_JSTATE) && (DRV_Reg8(OTG_STATUS)&OTG_STATUS_LINE_STATE_CHANGE))
   		{
   			g_OtgInfo.a_detect_b_srp = KAL_TRUE;

   			g_OtgInfo.a_bus_req = KAL_TRUE;
   		} /* Endif  */
		
	}

	if((g_OtgInfo.a_bus_req==KAL_TRUE) || (g_OtgInfo.a_detect_b_srp==KAL_TRUE))
	{
		/* In case go here and SRP timer is still on*/
		OTG_Stop_Timer();
      		
		g_OtgInfo.a_detect_b_srp = KAL_FALSE;
		
		/* If device is up, pull it down*/
		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)) );
		}	

		/* mask all interrupt in case interrupt happens during wating Vrise 
		interrupt will be unmasked when Vrise timer expiers*/
		DRV_WriteReg8(USB_INT_ENB, 0);

		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)));	

		/* Do not detect SRP because this system always provide power*/
		/* Turn on VBUS*/
		g_OtgInfo.otg_state = OTG_STATE_A_WAIT_VRISE;
		DRV_WriteReg8(OTG_CTRL, DRV_Reg8(OTG_CTRL)|OTG_CTL_VBUS_ON);

		OTG_Start_Timer(OTG_TIMER_A_WAIT_VRISE, TA_WAIT_VRISE);
	
		OTG_Process_A_Wait_VRise();
	}	
}

static void OTG_Process_A_Wait_VRise(void)
{
	if(OTG_Is_A_Bus_Valid()==KAL_TRUE)
	{
		OTG_Stop_Timer();
	
		/* wait for B connect forever*/
      		g_OtgInfo.otg_state = OTG_STATE_A_WAIT_BCON;

		if(g_OtgInfo.host_up==KAL_FALSE)
		{
			g_OtgInfo.host_up = KAL_TRUE;
			g_OtgInfo.host_up_hdlr();	
		}	

		/* Restore interrupt. Enable Attach interrupt only */            
		DRV_WriteReg8(USB_INT_ENB, VUSB_INT_ENB_ATTACH);	
	
//		USB_Ms_Dbg_Trace(OTG_STATE_A_VRISE_WAIT_B_CON, 0);
	} 
	else
	{
		if(OTG_Is_TimerOut(OTG_TIMER_A_WAIT_VRISE)==KAL_TRUE)
		{
			OTG_Stop_Timer();
			
			OTG_Process_A_Vbus_Fail();
			return;
		}
	}

	/* 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_Wait_BCon(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 (g_OtgInfo.a_detect_b_conn==KAL_TRUE) 
      	{
 //     	USB_Ms_Dbg_Trace(OTG_STATE_A_WAIT_B_CON_HOST, 0);
      		g_OtgInfo.otg_state = OTG_STATE_A_HOST;
      	}

	/* 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_Host(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 mini B plug is removed RESET (DETACH) interrupt will 
      	** happen on A-Device.The DETACH will processed by the host 
      	** ISR  and set a_detect_b_conn to  FALSE 
      	*/
      	if ((g_OtgInfo.a_detect_b_conn==KAL_FALSE) && (g_OtgInfo.a_detect_b_resume ==KAL_FALSE))
      	{
		g_OtgInfo.otg_state = OTG_STATE_A_WAIT_BCON;
		if(g_OtgInfo.a_host_stop_hdlr!=NULL)
			g_OtgInfo.a_host_stop_hdlr();
//		USB_Ms_Dbg_Trace(OTG_STATE_A_HOST_WAIT_B_CON, 0);
      	}
      	/************   Starting HNP **************************************
      	** When the A-device is in the a_host state and has set the dual-role 
      	** B-device's HNP enable bit (b_hnp_enable = TRUE ie, a_suspend_req
      	** = TRUE) the A-device shall place the connection to the B-device into 
      	** Suspend when it is finished using the bus.  We can go to the 
      	** suspend state also if user want to power down.
      	*/
      	else if((g_OtgInfo.a_set_b_hnp_enable==KAL_TRUE) && (g_OtgInfo.a_detect_b_resume ==KAL_FALSE))
      	{
		g_OtgInfo.otg_state = OTG_STATE_A_SUSPEND;
		USB_HCD_Bus_Control(USB_HCD_BUS_SUSPEND_SOF);

		/* stop the regilar check Vbus timer before activate another timer */
		if(OTG_Get_TimerType()==OTG_TIMER_A_CHECK_VBUS)
			OTG_Stop_Timer();
		
		OTG_Start_Timer(OTG_TIMER_A_IDLE_BDIS, TA_AIDL_BDIS);

		g_OtgInfo.a_process_hnp = KAL_TRUE;
      	}
	/* A request to suspend the bus */
      	else if(g_OtgInfo.a_suspend_req==KAL_TRUE)
      	{
		g_OtgInfo.otg_state = OTG_STATE_A_SUSPEND;
		USB_HCD_Bus_Control(USB_HCD_BUS_SUSPEND_SOF);
		g_OtgInfo.a_suspend_req = KAL_FALSE;
      	}
      	/* This may be because of B device is not supported by this A device */
      	else if(g_OtgInfo.a_bus_req==KAL_FALSE)
      	{
		g_OtgInfo.otg_state = OTG_STATE_A_WAIT_VFALL;

		USB_HCD_Bus_Control(USB_HCD_BUS_SUSPEND_SOF);
		
		/* Turn off VBUS*/
		DRV_WriteReg8(OTG_CTRL, DRV_Reg8(OTG_CTRL)&(~OTG_CTL_VBUS_ON));
      	}
      	/* OPT remote wakeup timeout*/
	else if(OTG_Is_TimerOut(OTG_TIMER_A_REMOTE_WAKEUP) == KAL_TRUE)
	{
		OTG_Stop_Timer();

		g_OtgInfo.a_detect_b_resume = KAL_FALSE;
		
//		USB_Ms_Dbg_Trace(OTG_HOST_DEASSERT_RESUME, 0);

		USB_HCD_Bus_Control(USB_HCD_BUS_DEASSERT_RESUME);
	}

	/* 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_Suspend(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;
		}
	}
	

⌨️ 快捷键说明

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