📄 port_ctl.c
字号:
/****************************************Copyright (c)**************************************************
** Guangzou ZLG-MCU Development Co.,LTD.
** graduate school
** http://www.zlgmcu.com
**
**--------------File Info-------------------------------------------------------------------------------
** File Name: PORT_CTL.c
** Last modified Date: 2005-04-22
** Last Version: V1.0
** Description:
**
**------------------------------------------------------------------------------------------------------
** Created By: Lishan Zhou
** Created date: 2005-04-22
** Version: V1.0
** Description:
**
**------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Description:
**
********************************************************************************************************/
#include "HostStack.h"
#define ENUM_RETRY 3
#define ENUM_RETRY_INTERVAL 1000L
#define RESET_SECOVERY_TIME 100L
device_instance *device_at_root_hub[ NUMBER_OF_ROOT_HUB_PORT ] = {
NULL,
NULL
};
hub_instance g_root_hub_instance = {
NULL,
{ 0x09, 0x29, 0x02, 0x09, 0x00, 0x32, 0x00, 0x00, 0x00 },
2,
{ NULL, NULL, NULL, NULL, NULL, NULL, NULL },
NULL,
0
};
hub_event_flag g_root_hub_event = {
0,
0x00
};
void isr_flag_handler( void );
void root_hub_event( void );
void hub_event_handler( hub_event_flag *h_ev_ptr );
unsigned long read_hub_port_status( unsigned char address, unsigned char port );
void clear_status_change_bits( unsigned char address, unsigned char port, unsigned long status_bits );
device_instance *connect_a_device( unsigned char address, unsigned char port, unsigned char topology_layer );
void disconnect_a_device( device_instance **dvi_ptr_ptr );
unsigned char port_reset( unsigned char address, unsigned char port );
device_instance *start_a_device( unsigned char speed, unsigned char topology_layer );
void message_of_enum_done( device_instance *dvi_ptr );
void hub_handler( void )
{
if(g_event_marker&ROOT_HUB_EVENT)
{
g_event_marker &= ~ROOT_HUB_EVENT;
root_hub_event();
hub_event_handler( &g_root_hub_event );
}
#ifdef HUB_CLASS_DRIVE
if(g_event_marker & DEVICE_HUB_EVENT )
{
g_event_marker &= ~DEVICE_HUB_EVENT;
hub_event_handler(&g_hub_device_event);
}
#endif
}
unsigned short HcRhPortStatusComm[2] = {
Com32_HcRhPortStatus1,
Com32_HcRhPortStatus2
};
void root_hub_event( void )
{
unsigned long rh_status;
unsigned char i;
if ( g_isr_flag & RHSC )
g_isr_flag &= ~RHSC;
else return;
g_root_hub_event.port_status_change_bit_map = 0x0;
for ( i = 0; i < 2; i++ )
{ rh_status = read_register32( HcRhPortStatusComm[ i ] ) ;
if ( rh_status & 0x00010000 )
{ g_root_hub_event.hub_address = 1;
g_root_hub_event.port_status_change_bit_map|= (0x1 << (i + 1));
g_root_hub_event.topology_layer = 0;
}
}
}
void hub_event_handler( hub_event_flag *h_ev_ptr )
{
device_instance *dvi_ptr;
hub_instance *hi_ptr;
unsigned long h_status;
unsigned char port_num;
unsigned char topology_layer;
unsigned char i;
if ( h_ev_ptr->hub_address == 0 )
return;
if ( NULL == (dvi_ptr = find_device( h_ev_ptr->hub_address )) )
return;
if ( h_ev_ptr->hub_address == ROOT_HUB_ADDRESS )
{
hi_ptr = &g_root_hub_instance;
topology_layer = 0 ;
}
else
{
hi_ptr = hub_instance_ptr( dvi_ptr );
topology_layer = hi_ptr->device_ptr->topology_layer;
}
for ( i = 0; i < hi_ptr->number_of_ports; i++ )
{
port_num = i + 1;
if ( !(h_ev_ptr->port_status_change_bit_map & (0x1 << port_num)) )
continue;
h_status = read_hub_port_status( h_ev_ptr->hub_address, port_num );
if ( h_status & 0x001F0000 )
clear_status_change_bits( h_ev_ptr->hub_address, port_num, h_status & 0x001F0000 );
if ( h_status & 0x00010000)
{
dispose_device( &(hi_ptr->device_on_port[ i ]) );
if ( h_status & 0x00000001 )
hi_ptr->device_on_port[ i ] = connect_a_device( h_ev_ptr->hub_address, i + 1, topology_layer + 1 );
}
}
h_ev_ptr->hub_address = 0;
h_ev_ptr->port_status_change_bit_map = 0 ;
}
unsigned long read_hub_port_status( unsigned char address, unsigned char port )
{
if ( address == ROOT_HUB_ADDRESS )
return ( read_register32( HcRhPortStatusComm[ port - 1 ] ) );
else
{
#ifdef HUB_CLASS_DRIVE
return ( read_hub_device_port_status( find_device( address ), port ) );
#else
return NULL;
#endif
}
}
void clear_status_change_bits( unsigned char address, unsigned char port, unsigned long status_bits )
{
if ( address == ROOT_HUB_ADDRESS )
write_register32( HcRhPortStatusComm[ port - 1 ], status_bits );
#ifdef HUB_CLASS_DRIVE
else
{
unsigned char i;
for ( i = 16; i <=20; i++ )
{
if ( status_bits & (0x1L << i) )
clear_status_change_bits_in_hub( find_device( address ), port, i );
}
}
#endif
}
device_instance *connect_a_device( unsigned char address, unsigned char port, unsigned char topology_layer )
{
device_instance *dvi_ptr;
unsigned char speed;
unsigned char i;
dvi_ptr = NULL;
for ( i = 0; i < ENUM_RETRY; i++ )
{
speed = port_reset( address, port );
dvi_ptr = create_device( speed, topology_layer );
if ( dvi_ptr != NULL )
break;
wait_ms( ENUM_RETRY_INTERVAL );
}
return ( dvi_ptr );
}
void disconnect_a_device( device_instance **dvi_ptr_ptr )
{
if ( *dvi_ptr_ptr == NULL )
return;
dispose_device( dvi_ptr_ptr );
}
unsigned char port_reset( unsigned char address, unsigned char port )
{
unsigned long h_status;
wait_ms( 100L );
if ( address == ROOT_HUB_ADDRESS )
{
write_register32( HcRhPortStatusComm[ port - 1 ], 0x00000010 );
while ( read_register32( HcRhPortStatusComm[ port - 1 ] ) & 0x00000010 )
wait_ms( 5L );
h_status = read_register32( HcRhPortStatusComm[ port - 1 ] );
wait_ms( RESET_SECOVERY_TIME );
}
#ifdef HUB_CLASS_DRIVE
else
{
reset_hub_device_port( find_device( address ), port );
h_status = read_hub_device_port_status( find_device( address ), port );
wait_ms( RESET_SECOVERY_TIME );
}
#endif
return ( (h_status >> 9) & 0x1 );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -