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

📄 port_ctl.c

📁 usb host在ARM7上的实现
💻 C
字号:
/****************************************************************************/
/*	includes																*/
/****************************************************************************/
#include "HostStack.h"

/****************************************************************************/
/*	constants																*/
/****************************************************************************/

#define	ENUM_RETRY				3
#define	ENUM_RETRY_INTERVAL		1000L

#define	RESET_SECOVERY_TIME		100L		//	In the standard, it is 10mS. But some devices need more time to start enum.
													//	See section 7.1.7.3 in USB2.0 spec.


/****************************************************************************/
/*	global vars																*/
/****************************************************************************/

device_instance	*device_at_root_hub[ NUMBER_OF_ROOT_HUB_PORT ] = {
																	NULL,
																	NULL
															    };
																		
hub_instance		g_root_hub_instance =	{
										NULL,											//	Pointer to device instance
										{	0x09, 0x29, 0x02, 0x09, 0x00, 0x32, 0x00, 0x00, 0x00 },	//	Dummy hub descriptor
										2,												//	Number of downstream ports
										{	NULL, NULL, NULL, NULL, NULL, NULL, NULL },		//	Pointer to device attached on downstream ports			
										NULL,											//	Pointer to ransfer instance
										0												//	Hub and Port Statua Change Bitmap
									};
																		
hub_event_flag 	g_root_hub_event = {
								0,
								0x00
							  };

/****************************************************************************/
/*	function definitions													*/
/****************************************************************************/

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 );



/*********************************************************
**
**  Hub event handling.
**
**********************************************************/
//**********************************************************************
// 函数名称:hub_handler
// 输入参数:无
// 输出参数:无
// 功能描述:根集线器和集线器设备事件处理
//**********************************************************************
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
										};
//**************************************************************
// 函数名称: root_hub_event
// 输入参数: 无
// 输出参数: 无
// 功能描述: 根集线器事件处理
//**************************************************************
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;			// 根集线器为拓朴的第0层
		}
	}
}

//**********************************************************************
// 函数名称: hub_event_handler
// 输入参数: h_ev_ptr
// 输出参数: 无
// 功描述符: 集线器事件处理
//**********************************************************************
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;				//	If the target is a root HUB
		topology_layer = 0 ;							// 根集线器下的设备为0层
	}
	else
	{
		hi_ptr = hub_instance_ptr( dvi_ptr );		//	If the target is a device HUB
		topology_layer = hi_ptr->device_ptr->topology_layer;
	}
	
	
	//	Port processing for target HUB
	//    目标集线器端口处理
	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 )										//	Device connected!
				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 ;
}

//******************************************************************************************
// 函数名称:read_hub_port_status
// 输入参数:address,集线器地址,根集线器为1
//		   port,集线器下行端口
// 输出参数:端口状态值
// 功能描述:读集线器下行端口状态
//******************************************************************************************
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
	}
}

//*************************************************************
// 函数名称:	clear_status_change_bits
// 输入参数: 	address,集线器地址,根集线器为1
//				port,集线器下行端口
//				status_bits,清除状态位
// 输出参数:无
// 功能描述:清除集线器端口状态改变位
//*************************************************************
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
}



/*********************************************************
**
**  Port event handling.
**
**********************************************************/
//**************************************************************************
// 函数名称:	connect_a_device
// 输入参数:	address,设备地址;
//				port,设备端口;
//				topology_layer,拓扑层,根集线器下的设备为0(层)
// 输出参数: dvi_ptr,设备描述信息结构指针.
// 功能描述: 连接上一个USB设备处理.
//**************************************************************************
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 );				//复位集线器一个端口,根集线器地址为1
		dvi_ptr = create_device( speed, topology_layer );	// 建立设备(枚举)
		if ( dvi_ptr != NULL )								// 设备建立成功,退出循环
			break;
		wait_ms( ENUM_RETRY_INTERVAL );					// 延时片刻,准备从试
	}
	return ( dvi_ptr );										// 返回成功建立设备的描述信息结构指针,出错返回NULL
}

//**************************************************************************
// 函数名称:	connect_a_device
// 输入参数:	address,设备地址;
//				port,设备端口;
//				topology_layer,
// 输出参数: dvi_ptr,设备描述信息结构指针.
// 功能描述: 断开USB设备连接处理.
//**************************************************************************
void disconnect_a_device( device_instance **dvi_ptr_ptr )
{
	if ( *dvi_ptr_ptr == NULL )
		return;
	dispose_device( dvi_ptr_ptr );
}

//***********************************************************************
// 函数名称:port_reset
// 输入参数:address,设备地址
//				   port,端口号
// 输出参数:h_status,返回集线器状态
// 功能描述:端口复位,并返口设备类型,全速或低速。
//***********************************************************************
unsigned char port_reset( unsigned char address, unsigned char port )
{
	unsigned long		h_status;

	wait_ms( 100L );														//	Need to wait before reset to handle bounce
	if ( address == ROOT_HUB_ADDRESS )
	{	// 根集线器
		write_register32( HcRhPortStatusComm[ port - 1 ], 0x00000010 );			//	Set port reset
		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_SECOVERY_TIME );									//	Wait reset recovery 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 );									//	Wait reset recovery time
	}
#endif
	return ( (h_status >> 9) & 0x1 ); 
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -