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

📄 otgsvc.c

📁 使用ISP1362芯片的USB_OTG参考设计源代码比较新的版本
💻 C
📖 第 1 页 / 共 2 页
字号:
					OtgTcb.TimeOut = 0;
					OtgTcb.err_code = OTG_ERR_A_WAIT_BCON_TMOUT;
				}
				OtgTcb.bus_req = 0;   //this bit should be cleared by application
				OTG_StopTimer();
				OtgTcb.FSM = A_WAIT_VFALL;
			}
			else if ( 0 == OtgTcb.a_vbus_vld )
			{
				OtgTcb.FSM = A_VBUS_ERR;
				OtgTcb.err_code = OTG_ERR_A_OVERCURRENT;
			}
			else if (1 == OtgTcb.b_conn)
			{
				if(A_BCON_LDBC_TIMER_ID != OtgTcb.TimerID)
					OTG_StartTimer(A_BCON_LDBC_TIMER,A_BCON_LDBC_TIMER_ID);
				else if (1 == OtgTcb.TimeOut)
				{
					OtgTcb.TimeOut = 0;
					OtgTcb.a_host_done = 0;	//A_HOST starts to use the bus
					OtgTcb.FSM = A_HOST;
				}
			}
			break;

		case A_HOST:

			OTGCtrl_LocalVBus(TRUE);
			OTGCtrl_LocalPullup(FALSE);
			OTGCtrl_LocalSOF(TRUE);
			Hal4OTG_HC_DC_Sel(FALSE);

			if(1==OtgTcb.id || 1==OtgTcb.bus_drop || 0==OtgTcb.b_conn)
			{

#ifdef WASABI
				OTG_exit_from_host_state();
#endif

				OTG_StartTimer(A_WAIT_BCON_TIMER,A_WAIT_BCON_TIMER_ID);
				OtgTcb.FSM = A_WAIT_BCON;
			}
			else if(0==OtgTcb.a_vbus_vld)
			{

#ifdef WASABI
				OTG_exit_from_host_state();
#endif

				OtgTcb.FSM = A_VBUS_ERR;
				OtgTcb.err_code = OTG_ERR_A_OVERCURRENT;
			}
			else if( 0==OtgTcb.bus_req && 1==OtgTcb.a_host_done)
			{

#ifdef WASABI
				OTG_exit_from_host_state();
#endif

				if(1 == OtgTcb.a_set_b_hnp_en)
					Hal4OTG_RdisLcon_En(TRUE); 	// if B-device disconnected, then A-device assert pull-up immediately
				OTG_StartTimer(A_AIDL_BDIS_TIMER,A_AIDL_BDIS_TIMER_ID);
				OtgTcb.FSM = A_SUSPEND;
			}
			break;

		case A_SUSPEND:

			OTGCtrl_LocalVBus(TRUE);
			OTGCtrl_LocalPullup(FALSE);
			OTGCtrl_LocalSOF(FALSE);
			Hal4OTG_HC_DC_Sel(FALSE);

			if(	1 == OtgTcb.id || 1 == OtgTcb.bus_drop || 1 == OtgTcb.TimeOut)
			{
				if ( 1 == OtgTcb.TimeOut)
				{
					OtgTcb.TimeOut = 0;
					OtgTcb.err_code = OTG_ERR_A_AIDL_BDIS_TMOUT;
				}
				OTG_StopTimer();
				Hal4OTG_RdisLcon_En(FALSE);
				OtgTcb.FSM = A_WAIT_VFALL;
			}
			else if (0 == OtgTcb.a_vbus_vld )
			{
				OtgTcb.FSM = A_VBUS_ERR;
				OtgTcb.err_code = OTG_ERR_A_OVERCURRENT;
			}
			else if ( 0 == OtgTcb.b_conn && 1 == OtgTcb.a_set_b_hnp_en )
			{
				OTGCtrl_LocalPullup(TRUE);
				Hal4OTG_RdisLcon_En(FALSE);
				
#ifdef	WASABI
				Hal4OTG_HC_DC_Sel(TRUE);		//	WASABI-Hot! needs to keep this function call here.
												//	Because sometime (especially after program launch) it takes time to 
												//	change the OTG state from here (SUSPEND) to A_PERIPHERAL.
												//	If the state change takes more than 3mS, it will miss the connection 
												//	from B_HOST. Because in this stage, A-device is enabling Pull-Up but 
												//	the transceiver does not connected to DC. Transceiver and DC will be 
												//	connected after going into A_PERIPHERAL state.
				
//				mprintf( LIGHTCYAN, CONTINUE, "\r\nA-device pull-up ON! @ frame# = %lu\r\n", read_register32( Com32_HcFmNumber ) );
#else
				DcS_EnableIRQ();
#endif
				OtgTcb.FSM = A_PERIPHERAL;

			}
			else if ( 0 == OtgTcb.b_conn && 0 == OtgTcb.a_set_b_hnp_en)
			{
				Hal4OTG_RdisLcon_En(FALSE);
				OTG_StartTimer(A_WAIT_BCON_TIMER,A_WAIT_BCON_TIMER_ID);
				OtgTcb.FSM = A_WAIT_BCON;
			}
			else if(1 == OtgTcb.bus_req \
					|| 1 == OtgTcb.b_bus_resume)
			{
				Hal4OTG_RdisLcon_En(FALSE);
				OtgTcb.FSM = A_HOST;
			}
			break;

		case A_PERIPHERAL:

			OTGCtrl_LocalVBus(TRUE);
			OTGCtrl_LocalPullup(TRUE);
			OTGCtrl_LocalSOF(FALSE);
			Hal4Sys_WaitinUS(10);
			Hal4OTG_HC_DC_Sel(TRUE);
			if(
				1 == OtgTcb.id || \
				1 == OtgTcb.bus_drop )

			{

#ifdef	WASABI
				OTG_exit_from_peripheral_state();
#else
#endif

				OtgTcb.FSM = A_WAIT_VFALL;
			}
			else if (0 == OtgTcb.a_vbus_vld )
			{

#ifdef	WASABI
				OTG_exit_from_peripheral_state();
#else
#endif

				OtgTcb.FSM = A_VBUS_ERR;
				OtgTcb.err_code = OTG_ERR_A_OVERCURRENT;
			}
			else if (1 == OtgTcb.b_bus_suspend)
			{
				OtgTcb.b_bus_suspend = 0;
#ifdef	WASABI
//				mprintf( YELLOW, CONTINUE, "OtgTcb.b_bus_suspend\r\n" );
				OTG_exit_from_peripheral_state();
#else
				DcS_DisableIRQ();
#endif
				OTG_StartTimer(A_WAIT_BCON_TIMER,A_WAIT_BCON_TIMER_ID);
				OtgTcb.FSM = A_WAIT_BCON;
			}
			break;

		case A_WAIT_VFALL:

			OTGCtrl_LocalVBus(FALSE);
			OTGCtrl_LocalPullup(FALSE);
			OTGCtrl_LocalSOF(FALSE);

			Hal4OTG_HC_DC_Sel(FALSE);

			if(
				1 == OtgTcb.id || \
				1 == OtgTcb.bus_req || \
				(0 == OtgTcb.a_sess_vld && 0 == OtgTcb.b_conn))
			{
				OTGsup_SetVarible();
				Hal4OTG_SRP_Det_En(TRUE);	//enable SRP detection
				OtgTcb.FSM = A_IDLE;
			}
			break;

		case A_VBUS_ERR:

			OTGCtrl_LocalVBus(FALSE);
			OTGCtrl_LocalPullup(FALSE);
			OTGCtrl_LocalSOF(FALSE);

			Hal4OTG_HC_DC_Sel(FALSE);

			if(1 == OtgTcb.id || 1 == OtgTcb.bus_drop)
			{
				OtgTcb.FSM = A_WAIT_VFALL;
			}
			break;

		default:
			break;
	}
}

void OTG_FSM(void)
{
	if(OtgTcb.FSM >= A_IDLE)	//device is in A state machine
	{
		OTG_FSM4DeviceA();
	}
	else		//device is in B state machine
	{
		OTG_FSM4DeviceB();
	}
}

void OTG_HW_emulator(void)
{
	// Input of FSM
	OTGStatus_Probe();

	// FSM
	OTG_FSM();

	// Timer Routine
/*	if( 1 == OtgTcb.TimerRunning)
	{
		if(0 == OtgTcb.TimerTick)
		{
			OtgTcb.TimerRunning = 0;
			OtgTcb.TimeOut = 1;
		}
		else
		{
			OtgTcb.TimerTick --;
		}
	}*/
}

void OTGsup_SetVarible(void)
{

	RaiseIRQL();

//	OtgTcb.UsageBased = 1;

	OtgTcb.a_bus_resume = 0;
	OtgTcb.a_bus_suspend = 0;
	OtgTcb.a_bus_reset = 0;
	OtgTcb.b_bus_resume = 0;
	OtgTcb.b_bus_suspend = 0;

	OtgTcb.b_hnp_en = 0;
	OtgTcb.a_set_b_hnp_en = 0;
	OtgTcb.a_hnp_support = 0;
	OtgTcb.a_alt_hnp_support = 0;

	OtgTcb.TimerRunning = 0;
	OtgTcb.TimeOut = 0;
	OtgTcb.TimerTick = 0;
	OtgTcb.TimerID = 0;

	//these variables should be initialized by application
//	OtgTcb.bus_req = 0;
//	OtgTcb.bus_drop = 0;
//	OtgTcb.a_suspend_req = 0;
	OtgTcb.err_code = 0;
	OtgTcb.VendorID = 0;
	OtgTcb.ProductID = 0;
	OtgTcb.DevAddr = 0;

	LowerIRQL();
}

void OTG_Init(void )
{
	OTGsup_SetVarible();

	OtgTcb.bus_req			= 0;
	OtgTcb.bus_drop			= 0;
	OtgTcb.a_suspend_req	= 0;

	OTGStatus_Probe();

#ifdef WASABI
#else
	//Select on-chip charge-pump or external 5v for OTG VBUS.
	//on-chip charge-pump supports up to 8mA, on-board 5v supports up to 500mA
	Hal4OTG_Sel_Vbus();
#endif


#ifdef WASABI
	OTG_exit_from_host_state();
	OTG_exit_from_peripheral_state();
#endif


	switch(OtgTcb.id)
	{
		case 0:
			OtgTcb.FSM = A_IDLE;
			Hal4OTG_HC_DC_Sel(FALSE);	//default HC
			Hal4OTG_SRP_Det_En(TRUE);	//enable SRP detection
			break;

		case 1:
			OtgTcb.FSM = B_IDLE;
			Hal4OTG_HC_DC_Sel(TRUE);	//default DC
			break;

		default:
			break;
	}
}

void OTG_Acquire(void)
{
	OTG_Init();

#ifdef WASABI
#else
	Hal4ISA_AcquireIRQ4Timer();
#endif
}

void OTG_Release(void)
{
#ifdef WASABI
#else
	Hal4ISA_ReleaseIRQ4Timer();
#endif
}

BOOLEAN OTGSup_ADevGiveupMastership(void)
{


#ifdef	WASABI

	if ( 0 == otg_enable_B_host() )

#else

	if( TRUE == UsbStd_SetFeature(
		OtgTcb.DevAddr, //DevAddr,
		0,//Speed,
		8,//RmtDev.PktSize,

		0,//byRecipient,
		USB_FEATURE_B_HNP_ENABLE,//wFeatureSelector,
		0//wIndex
		)
	)
	
#endif

	{
		RaiseIRQL();
		OtgTcb.a_set_b_hnp_en = 1;
		LowerIRQL();

		return TRUE;
	}
	else
	{
		RaiseIRQL();
		OtgTcb.a_set_b_hnp_en = 0;

		LowerIRQL();

		return FALSE;
	}
}

void OTG_do_srp(void)
{

	// Data line Pulsing
	OTGCtrl_LocalPullup(TRUE);
	Hal4Sys_WaitinMS(B_DATA_PLS_TIMER);	// DATA LINE HIGH FOR 5-10MS
	OTGCtrl_LocalPullup(FALSE);

	// VBUS Pulsing
	OTGCtrl_LocalVBus(TRUE);
	Hal4Sys_WaitinMS(B_VBUS_PLS_TIMER);
	OTGCtrl_LocalVBus(FALSE);

	// VBUS discharge
	Hal4OTG_VBUS_DisChrg(TRUE);
	Hal4Sys_WaitinMS(VBUS_DISCHRG_TIMER);
	Hal4OTG_VBUS_DisChrg(FALSE);
	OtgTcb.b_srp_done = 1;

}







#if 0
mprintf( YELLOW, CONTINUE, "REG_OTG_CONTROL    = 0x%04X\r\n", read_register16( REG_OTG_CONTROL    ) );
mprintf( YELLOW, CONTINUE, "REG_OTG_STATUS     = 0x%04X\r\n", read_register16( REG_OTG_STATUS     ) );
mprintf( YELLOW, CONTINUE, "REG_OTG_INTERRUPT  = 0x%04X\r\n", read_register16( REG_OTG_INTERRUPT  ) );
mprintf( YELLOW, CONTINUE, "REG_OTG_INT_ENABLE = 0x%04X\r\n", read_register16( REG_OTG_INT_ENABLE ) );
mprintf( YELLOW, CONTINUE, "REG_OTG_TMR        = 0x%04X\r\n", read_register16( REG_OTG_TMR        ) );
mprintf( YELLOW, CONTINUE, "REG_OTG_TMR2       = 0x%04X\r\n", read_register16( REG_OTG_TMR2       ) );
getchar();
#endif



#if 0
mprintf( YELLOW, CONTINUE, "%01u%01u%01u%01u%01u%01u%01u%01u%01u%01u%01u%01u%01u%01u%01u%01u%01u%01u%01u%01u%01u%01u%01u%01u%01u%01u%01u\r\n",
OtgTcb.id, 
OtgTcb.a_vbus_vld,
OtgTcb.a_sess_vld,
OtgTcb.a_srp_det,
OtgTcb.b_conn,
OtgTcb.b_bus_suspend,
OtgTcb.b_bus_resume,
OtgTcb.b_hnp_support,
OtgTcb.b_srp_support,
OtgTcb.a_set_b_hnp_en,
OtgTcb.a_suspend_req,
OtgTcb.a_host_done,
OtgTcb.b_sess_end,
OtgTcb.b_sess_vld,
OtgTcb.b_se0_srp,
OtgTcb.a_conn,
OtgTcb.a_bus_suspend,
OtgTcb.a_bus_resume,
OtgTcb.a_bus_reset,
OtgTcb.b_srp_done,
OtgTcb.b_hnp_en,
OtgTcb.a_hnp_support,
OtgTcb.a_alt_hnp_support,
OtgTcb.bus_req,
OtgTcb.bus_drop,
OtgTcb.TimeOut,
OtgTcb.TimerRunning
);
#endif

⌨️ 快捷键说明

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