📄 otg.c
字号:
unsigned char dummy;
unsigned short rx_size = 0;
dvi_ptr = portctl_get_OTG_port_device_instance();
if ( dvi_ptr == NULL )
return ( 1 );
if ( devep_std_request( &dummy, dvi_ptr, std_Dv_request_SET_FEATURE_Dv, 3, 0x0000, &rx_size ) )
return ( 2 );
return ( 0 );
}
void otg_handle_OTG_descriptor( unsigned char *buf )
{
OtgTcb.b_srp_support = (*(buf + 2) & 0x01);
OtgTcb.b_hnp_support = (*(buf + 2) & 0x02) >> 1;
}
void OTG_status_monitor( void )
{
static unsigned char Last_State = 99;
unsigned char flag = 1;
if ( OtgTcb.err_code )
{
mprintf( WHITE, CONTINUE, " OTG port " );
switch(OtgTcb.err_code)
{
case OTG_ERR_PLUGA_INSERTED:
mprintf( YELLOW, CONTINUE, "mini-A " );
mprintf( WHITE, CONTINUE, "plug " );
mprintf( LIGHTGREEN, CONTINUE, "inserted!" );
break;
case OTG_ERR_PLUGA_REMOVED:
mprintf( YELLOW, CONTINUE, "mini-A " );
mprintf( WHITE, CONTINUE, "plug " );
mprintf( LIGHTRED, CONTINUE, "removed!" );
break;
case OTG_ERR_A_OVERCURRENT:
mprintf( LIGHTRED, CONTINUE, "VBUS over current!" );
OtgTcb.bus_req = 0;
break;
case OTG_ERR_SRP_FAIL:
mprintf( LIGHTRED, CONTINUE, "Error: SRP fail. No repsonse from A-device." );
OtgTcb.bus_req = 0;
break;
case OTG_ERR_A_WAIT_BCON_TMOUT:
mprintf( LIGHTRED, CONTINUE, "No response from B-device." );
OtgTcb.bus_req = 0;
break;
default:
mprintf( LIGHTRED, CONTINUE, "\r \r" );
flag = 0;
break;
}
if ( flag )
mprintf( LIGHTRED, CONTINUE, "\r\n" );
g_quit_grab_process = 1;
}
OtgTcb.err_code = 0;
if( Last_State == OtgTcb.FSM )
return;
Last_State = OtgTcb.FSM;
if ( OTG_leave_from_host_state )
{
portctl_disconnect_a_device_on_OTG_port();
OTG_leave_from_host_state = False;
}
OTG_state_in_host = False;
mprintf( WHITE, CONTINUE, "%s OTG port *** HNP State: ", (wherex() == 1) ? "" : "\r" );
switch ( Last_State )
{
case A_HOST:
mprintf( YELLOW, CONTINUE, "A_HOST " );
mprintf( LIGHTCYAN , CONTINUE, "* " );
break;
case B_HOST:
mprintf( YELLOW, CONTINUE, "B_HOST " );
mprintf( LIGHTCYAN , CONTINUE, "* " );
break;
case A_PERIPHERAL:
mprintf( YELLOW, CONTINUE, "A_PERIPHERAL" );
break;
case B_PERIPHERAL:
mprintf( YELLOW, CONTINUE, "B_PERIPHERAL" );
break;
case A_IDLE:
mprintf( YELLOW, CONTINUE, "A_IDLE " );
break;
case B_IDLE:
mprintf( YELLOW, CONTINUE, "B_IDLE " );
break;
case A_VBUS_ERR:
mprintf( YELLOW, CONTINUE, "A_VBUS_ERR " );
break;
case B_SRP_INIT:
mprintf( YELLOW, CONTINUE, "B_SRP_INIT " );
OTG_do_srp();
break;
case A_WAIT_VRISE:
mprintf( YELLOW, CONTINUE, "A_WAIT_VRISE" );
break;
case A_WAIT_BCON:
mprintf( YELLOW, CONTINUE, "A_WAIT_BCON " );
break;
case A_SUSPEND:
mprintf( YELLOW, CONTINUE, "A_SUSPEND " );
break;
case A_WAIT_VFALL:
mprintf( YELLOW, CONTINUE, "A_WAIT_VFALL" );
break;
case B_WAIT_ACON:
mprintf( YELLOW, CONTINUE, "B_WAIT_ACON " );
break;
default:
// mprintf( YELLOW, CONTINUE, "*** HNP State: %d ***\n",Last_State);
break;
}
mprintf( WHITE, CONTINUE, " ***\r\n" );
// mprintf( WHITE, CONTINUE, " *** f=%lu\r\n", gp_sof_counter );
switch ( Last_State )
{
case A_HOST:
case B_HOST:
beep_pippi( 880.00, .1, 2 );
ui_status_monitor();
OTG_enter_to_host_state();
break;
case A_PERIPHERAL:
ui_status_monitor();
OTG_enter_to_peripheral_state();
case B_PERIPHERAL:
ui_status_monitor();
OTG_enter_to_peripheral_state();
if(OtgTcb.a_bus_reset == 1 && OtgTcb.TimerID == B_BUS_REQ_TIMER_ID)
OTG_StopTimer(); //stop the B_BUS_REQ_TIMER
break;
case A_VBUS_ERR:
wait_ms( 200 );
OTG_bus_drop();
break;
default:
break;
}
}
void OTG_message( char *message )
{
char str[ 80 ];
char s[ 80 ];
unsigned char i;
for ( i = 0; i < 80; i++ )
*(str + i) = ' ';
memcpy( str + 30, message, 20 );
for ( i = 0; i < 80; i++ )
*(s + i) = 0;
for ( i = 1; i < 20; i++ )
{
strncpy( s, (str + 40) - i, (i << 1) );
gotoxy( 40 - i, wherey() );
mprintf( (WHITE << 4 | BLACK), CONTINUE, "%s", s );
wait_ms( 80L );
}
}
void OTG_show_port_status( void )
{
unsigned char color;
static char *status_str[] = {
"B_IDLE ",
"B_SRP_INIT ",
"B_WAIT_ACON ",
"B_PERIPHERAL",
"B_HOST ",
"A_IDLE ",
"A_WAIT_VRISE",
"A_WAIT_BCON ",
"A_HOST ",
"A_PERIPHERAL",
"A_WAIT_VFALL",
"A_VBUS_ERR ",
"A_SUSPEND ",
" "
};
gotoxy( 1, 1 );
mprintf( gp_is_in_DOS_environment ? ((MAGENTA << 4) | YELLOW ) : ((YELLOW << 4) | BLACK ), CONTINUE, " OTG local = %-10s port status : ", gp_id_string, (OtgTcb.FSM < 5) ? "B" : "A" );
switch ( OtgTcb.FSM )
{
case B_HOST :
case A_HOST :
color = (BLUE << 4) | WHITE;
break;
case B_PERIPHERAL :
case A_PERIPHERAL :
color = (GREEN << 4) | WHITE;
break;
default :
color = (BROWN << 4) | WHITE;
break;
}
mprintf( color, CONTINUE, " %s ", status_str[ OtgTcb.FSM ] );
if ( !gp_emulate_peripheral_only )
{
mprintf( (BLACK << 4) | WHITE, CONTINUE, " Bus request = " );
mprintf( (BLACK << 4) | OtgTcb.bus_req ? LIGHTGREEN : LIGHTRED, CONTINUE, "%s", OtgTcb.bus_req ? "ON!" : "OFF" );
}
else
{
mprintf( (BLACK << 4) | LIGHTRED, CONTINUE, " PERIPHERAL ONLY" );
}
}
#define WAIT_TO_GET_MASTERSHIP 5000 // 5000ms
#define POLLING_INTERVAL_FOR_MONITORING_TO_GET_MASTERSHIP 100 // 100ms
unsigned char otg_wait_to_get_mastership( void )
{
unsigned short i;
g_quit_grab_process = False;
i = WAIT_TO_GET_MASTERSHIP / POLLING_INTERVAL_FOR_MONITORING_TO_GET_MASTERSHIP;
mprintf( WHITE, CONTINUE, "\r\n" );
while ( i-- )
{
unsigned char color;
if ( (i * POLLING_INTERVAL_FOR_MONITORING_TO_GET_MASTERSHIP) > 2000 )
color = GREEN;
else if ( i == 0 )
color = RED;
else
color = YELLOW;
mprintf( color, CONTINUE, "Wait to get OTG mastership : %0u sec\r", (i * POLLING_INTERVAL_FOR_MONITORING_TO_GET_MASTERSHIP + 999) / 1000 );
wait_ms( POLLING_INTERVAL_FOR_MONITORING_TO_GET_MASTERSHIP );
if ( OTG_host_operation_enabled() )
return ( True );
if ( g_quit_grab_process )
return ( False );
}
return ( False );
}
void OTG_Dc_bus_reset( void )
{
OtgTcb.a_bus_reset = 1;
OtgTcb.a_bus_suspend = 0;
OtgTcb.b_bus_suspend = 0;
// These OTG internal variables should be cleared upon a bus reset
OtgTcb.b_hnp_en = 0;
OtgTcb.a_hnp_support = 0;
OtgTcb.a_alt_hnp_support = 0;
}
void OTG_Dc_bus_suspend( void )
{
OtgTcb.a_bus_suspend = 1;
OtgTcb.b_bus_suspend = 1;
}
void OTG_Dc_bus_resume( void )
{
OtgTcb.a_bus_suspend = 0;
OtgTcb.b_bus_suspend = 0;
}
device_instance *otg_host_process_for_HNP( void )
{
device_instance *dvi_ptr;
unsigned char speed;
unsigned char buffer[ 3 ];
unsigned short rx_size;
unsigned char i;
speed = portctl_reset_OTG_port();
dvi_ptr = devep_make_device_and_setup_ep0_connection( speed, 1 );
mprintf( LIGHTRED, CONTINUE, " *** " );
mprintf( WHITE, CONTINUE, "Got temporal mastership\r\n" );
rx_size = 3;
if ( devep_std_request( buffer, dvi_ptr, std_Dv_request_GET_DESCRIPTOR, descriptor_type_OTG, 0x0000, &rx_size ) )
{
devep_dispose_device( &dvi_ptr );
return ( NULL );
}
otg_handle_OTG_descriptor( buffer );
if ( !OtgTcb.b_hnp_support )
{
// This process for non-HNP supported OTG device (i.e. OTG peripheral only device)
// For the non-HNP device, host may need to do the full enumeration for the remote.
devep_dispose_device( &dvi_ptr );
return ( NULL );
}
return ( dvi_ptr );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -