📄 port_ctl.c
字号:
#if 0
if ( gp_fast_enumeration )
retry = 1;
else
retry = ENUM_RETRY;
#else
retry = ENUM_RETRY;
#endif
fast_enumeration_flag_to_remember = gp_fast_enumeration;
if ( (address == ROOT_HUB_ADDRESS) && (port == 1) && OTG_host_operation_enabled() )
gp_fast_enumeration = 1;
for ( i = 0; i < retry; i++ )
{
speed = port_reset( address, port, RESET_SECOVERY_TIME ); // reset a port on ( address, port );
dvi_ptr = start_a_device( speed, topology_layer ); // start a device!
if ( dvi_ptr != NULL )
break;
// read_register32( HcRhPortStatusComm[ port - 1 ] & 0x00000001 ); // Disable port
if ( gp_warning_message )
mprintf( YELLOW, CONTINUE, "*** Enumeration RETRY wait #%d\r", i );
wait_ms( ENUM_RETRY_INTERVAL );
}
gp_fast_enumeration = fast_enumeration_flag_to_remember;
if ( i == retry )
mprintf( YELLOW, CONTINUE, "\r\n" );
return ( dvi_ptr );
}
void disconnect_a_device( device_instance **dvi_ptr_ptr )
{
unsigned char address;
mprintf( LIGHTGRAY, CONTINUE, "\r\ndetected a device disconnection\r\n" );
if ( *dvi_ptr_ptr == NULL )
{
mprintf( LIGHTGRAY, CONTINUE, "un-enumerated device removed.\r\n" );
return;
}
address = (*dvi_ptr_ptr)->address;
devep_dispose_device( dvi_ptr_ptr );
*dvi_ptr_ptr = NULL;
mprintf( WHITE, CONTINUE, "device (address=%d) disposed\r\n", address );
if ( !gp_silent_enumeration )
beep( 660, 0.20, DECAY, POLY );
}
#define OTG__SESSION_BASED
unsigned char port_reset( unsigned char address, unsigned char port, unsigned short reset_recovery_time )
{
unsigned long h_status;
#ifdef OTG__SESSION_BASED
if ( (address == ROOT_HUB_ADDRESS) && (port == 1) && OTG_host_operation_enabled() )
; // If the local is OTG host, no need to wait.
else
wait_ms( 100L ); // Need to wait before reset to handle bounce
#else
wait_ms( 100L ); // Need to wait before reset to handle bounce
#endif
if ( address == ROOT_HUB_ADDRESS )
{
write_register32( HcRhPortStatusComm[ port - 1 ], 0x00000010 ); // Set port reset
#ifdef LONGER_RESET
{
unsigned char i;
for ( i = 0; i < 41; i++ )
{
write_register32( HcRhPortStatusComm[ port - 1 ], 0x00000010 ); // Set port reset
wait_ms( 1L );
}
}
#else
#endif
while ( read_register32( HcRhPortStatusComm[ port - 1 ] ) & 0x00000010 ) // Polling port reset status (waiting for finishing port reset)
wait_ms( 5L );
h_status = read_register32( HcRhPortStatusComm[ port - 1 ] );
wait_ms( reset_recovery_time ); // Wait reset recovery time
}
else
{
hub_reset_hub_device_port( devep_find_device( address ), port );
h_status = hub_read_hub_device_port_status( devep_find_device( address ), port );
wait_ms( reset_recovery_time ); // Wait reset recovery time
if ( 0x3 == h_status )
mprintf( LIGHTGRAY, CONTINUE, "\r\nport enabled @hub(addr=%d) port%d\r\n", address, port );
}
return ( (h_status >> 9) & 0x1 );
}
device_instance *start_a_device( unsigned char speed, unsigned char topology_layer )
{
device_instance *dvi_ptr;
unsigned char dv_class_code;
unsigned char if_class_code;
if ( NULL == (dvi_ptr = devep_create_device( speed, topology_layer )) ) // Do enumeration
{
if ( gp_warning_message )
mprintf( YELLOW, CONTINUE, "\r\nWarning : device may have problem for enumeration process\r\n" );
return ( NULL );
}
message_of_enum_done( dvi_ptr );
return ( dvi_ptr );
}
void message_of_enum_done( device_instance *dvi_ptr )
{
int i,
j;
if ( !gp_silent_enumeration )
{
if ( devep_check_interface_class_ID( dvi_ptr, AUDIO_CLASS_INTERFACE ) )
beep( 886.00, 1.20, DECAY, POLY );
else
beep( 443.00, 0.50, DECAY, POLY );
}
if ( gp_fast_enumeration )
{
mprintf( WHITE, CONTINUE, "device enumerated (address=%d assigned.)", dvi_ptr->address );
mprintf( DARKGRAY, CONTINUE, " vid=0x%04X pid=0x%04X\r", (dvi_ptr->dev_descriptor).idVendor, (dvi_ptr->dev_descriptor).idProduct );
// mprintf( WHITE, CONTINUE, "device enumerated (address=%d assigned.)\r", dvi_ptr->address );
}
else
{
for ( j = 0; j < 5; j++ )
{
// mprintf( (j & 0x1) ? BLACK : WHITE, CONTINUE, "device enumerated (address=%d assigned. VID=0x%04X PID=0x%04X )\r", dvi_ptr->address, (dvi_ptr->dev_descriptor).idVendor, (dvi_ptr->dev_descriptor).idProduct );
mprintf( (j & 0x1) ? BLACK : WHITE, CONTINUE, "device enumerated (address=%d assigned.)\r", dvi_ptr->address );
wait_ms( ENUMERATION_DONE_BLINKING_INTERVAL );
}
}
mprintf( WHITE, CONTINUE, "\r\n" );
ui_show_device_string_descriptors( dvi_ptr );
// ui_device_infomation_viewer( dvi_ptr );
}
device_instance *portctl_device_on_port( unsigned char port_num )
{
return ( device_at_root_hub[ port_num - 1 ] );
}
void portctl_force_rh_port_reconnect( void )
{
write_register32( Com32_HcRhPortStatus1, 0x1 );
write_register32( Com32_HcRhPortStatus2, 0x1 );
if ( (gp_root_hub_instance.portctl_device_on_port)[ 0 ] != NULL )
disconnect_a_device( &((gp_root_hub_instance.portctl_device_on_port)[ 0 ]) );
if ( (gp_root_hub_instance.portctl_device_on_port)[ 1 ] != NULL )
disconnect_a_device( &((gp_root_hub_instance.portctl_device_on_port)[ 1 ]) );
if ( (read_register32( Com32_HcRhPortStatus1 ) & 0x1) )
(gp_root_hub_instance.portctl_device_on_port)[ 0 ] = connect_a_device( 1, 1, 1 );
if ( (read_register32( Com32_HcRhPortStatus2 ) & 0x1) )
(gp_root_hub_instance.portctl_device_on_port)[ 1 ] = connect_a_device( 1, 2, 1 );
}
unsigned char portctl_check_OTG_port( unsigned char bus_request, unsigned char full_enum )
{
device_instance *dvi_ptr = NULL;
unsigned long port_status;
write_register32( Com32_HcRhPortStatus1, 0x001F0000 ); // Clearing ststus change bit
if ( (gp_root_hub_instance.portctl_device_on_port)[ 0 ] != NULL )
return ( False );
port_status = read_register32( Com32_HcRhPortStatus1 );
if ( (port_status & 0x00000001) ) // Device connected!
{
#if 0
if ( (!bus_request) && (!full_enum) )
= otg_host_process_for_HNP(); // Try to access as remote=DRD
(gp_root_hub_instance.portctl_device_on_port)[ 0 ] = connect_a_device( 1, 0 + 1, 0 + 1 );
else
#endif
if ( (!bus_request) && (!full_enum) )
dvi_ptr = otg_host_process_for_HNP(); // Try to access as remote=DRD
if ( dvi_ptr == NULL )
dvi_ptr = connect_a_device( 1, 0 + 1, 0 + 1 );
}
(gp_root_hub_instance.portctl_device_on_port)[ 0 ] = dvi_ptr;
return ( dvi_ptr ? True : False );
}
void portctl_disconnect_a_device_on_OTG_port( void )
{
if ( (gp_root_hub_instance.portctl_device_on_port)[ 0 ] != NULL )
disconnect_a_device( &((gp_root_hub_instance.portctl_device_on_port)[ 0 ]) );
write_register32( Com32_HcRhPortStatus1, 0x00000001 ); // Disabling OTG port (port1)
write_register32( Com32_HcRhPortStatus1, 0x001F0000 ); // Clearing ststus change bit
}
device_instance *portctl_get_OTG_port_device_instance( void )
{
return ( (gp_root_hub_instance.portctl_device_on_port)[ 0 ] );
}
void portctl_OTG_port_enable_disable( unsigned char enable )
{
unsigned long v;
unsigned char state;
state = (read_register32( Com32_HcRhPortStatus1 ) & 0x00000002) ? True : False;
v = enable ? 0x00000182 : 0x00000181;
if ( state ^ enable )
write_register32( Com32_HcRhPortStatus1, v );
}
unsigned char portctl_reset_OTG_port( void )
{
return ( port_reset( ROOT_HUB_ADDRESS, 1, 10 ) ) ;
}
void portctl_Vbus_control_for_port_1_or_2( unsigned char power, unsigned char port_num )
{
if ( power )
write_register32( HcRhPortStatusComm[ port_num - 1 ], 0x00000100 );
else
write_register32( HcRhPortStatusComm[ port_num - 1 ], 0x00000200 );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -