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

📄 port_ctl.c

📁 ARM读写U盘驱动软件包源程序
💻 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 + -