📄 otgsvc.c
字号:
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 + -