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

📄 hub.c

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


/****************************************************************************/
/*	function prototypes														*/
/****************************************************************************/
#define	MAX_HUB_PORTS			7

hub_event_flag 	g_hub_device_event = {
								0,
								0x00
							  };

device_instance		*create_hub_class_instance( device_instance *dvi_ptr );
void				hub_callback( transfer_instance *hTrInstance );

extern OS_EVENT	*OS_rhsc_event;
/****************************************************************************/
/*	function definitions													*/
/****************************************************************************/
//*****************************************************************************
// 函数名称:	hub_init_commands
// 输入参数:	dvi_ptr,设备描述信息结构指针
// 输出参数:	正常完成返回0,出错返回-1
// 功能描述:	集线器设备初始化,并使能一个中断传输.
//*****************************************************************************
unsigned short hub_init_commands( device_instance *dvi_ptr )
{
	unsigned char	buffer[ datalength_of_HUB_DESCRIPTOR ];
	hub_instance	*hi_ptr;
	unsigned char	number_of_ports;
	unsigned short	size;
	unsigned short	i;
	endpoint_info *epi_in_ptr;
	transfer_instance *tr_instance_ptr;
	/**************************/
	/*获取集线器描述符*/
	/**************************/
	if ( NULL == create_hub_class_instance( dvi_ptr ) )			// 建立集线器类设备
		return (0xffff);
	hi_ptr = (hub_instance *)hub_instance_ptr( dvi_ptr );			// 获取集线器描术信息结构指针
	number_of_ports = hi_ptr->number_of_ports;				// 获取集线器设备端口数
	for ( i = 1; i <= number_of_ports; i++ )						// 所有端口上电
	{
		size	= 0;	
		std_request( buffer, dvi_ptr, hub_cls_sp_request_SetPortFeature, PORT_POWER, i, &size );
	}
	
	/***************************/
	/* 设置中断传输管道 */
	/***************************/
	epi_in_ptr    = find_endport_type( dvi_ptr ,Ep_TransferType_Interrupt ,	// 杳找集线器设备的第个中断输入端点
								Ep_Direction_IN_ENDPOINT , 1);
	tr_instance_ptr= atl_open_transfer_instance( epi_in_ptr);				// 创建一个传输描述符
	if ( NO_OPEN_ATL_TRANSFER == tr_instance_ptr)						// 出错返回
		return (0xffff);
	hi_ptr->tr_instance_ptr	= tr_instance_ptr;							// 保存传输描述符到集线器描述数据结构
	if(atl_set_transfer(tr_instance_ptr, &(hi_ptr->ep1_data),1, IN, hub_callback ))// 设置集线器中断传输
		return ( 0 );
	return (0xffff);
}


//*****************************************************************************
// 函数名称:	create_hub_class_instance
// 输入参数:	dvi_ptr,集线器设备描述信息结构指针
// 输出参数:	正常返回设备描述信息结构指针,出错返回NULL
// 功能描述: 	建立集线器类设备
//*****************************************************************************
device_instance *create_hub_class_instance( device_instance *dvi_ptr )
{
	hub_instance		*hi_ptr;
	unsigned short		size	= datalength_of_HUB_DESCRIPTOR;
	unsigned char		i;
	endpoint_info 		*epi_in_ptr;
	if ( NULL == (hi_ptr	= (hub_instance *)malloc( 4 +  sizeof( hub_instance ) )) )	// 为集线器描述数据结构分配内存
		return ( NULL );
	/*******************************************/
	/* 检查设备描述符,确定是否为集线器设备				  */
	/*******************************************/	
	if ( (dvi_ptr->conf_descriptor).bNumInterfaces != 1 )
		return ( NULL );
	epi_in_ptr    = find_endport_type( dvi_ptr ,Ep_TransferType_Interrupt ,	// 杳找集线器设备的第个中断输入端点
								Ep_Direction_IN_ENDPOINT , 1);
	if(epi_in_ptr == NULL)
		return ( NULL );
	if ( (epi_in_ptr->endpoint_descriptor).bEndpointAddress != 0x81 )
		return ( NULL );
	if ( (epi_in_ptr->endpoint_descriptor).wMaxPacketSize != 1 )
		return ( NULL );
	hi_ptr->polling_rate = (epi_in_ptr->endpoint_descriptor).bInterval;
	
	/*******************************************/
	/* 获取集线器描述符                                 */
	/*******************************************/
	if ( std_request( (hi_ptr->hub_descriptor), dvi_ptr, 
				     hub_cls_sp_request_GetHubDescripter,
				     0, 0, &size ) )
		return ( NULL );

	/*******************************************/
	/* 初始化集线器设备描述信息         */
	/*******************************************/
	hi_ptr->device_ptr	= dvi_ptr;					// 保存设备描述信息数据结构指针
	hi_ptr->number_of_ports = 						// 从集线器描述符中获取集线器端口数
		((hub_descriptor_params *)(&(hi_ptr->hub_descriptor)))->bNbrPorts;
	hi_ptr->tr_instance_ptr	  = NULL;					// 初始化集线器中断端点传输描述符指针为NULL
	
	for ( i = 0; i < MAX_NUM_OF_PORTS; i++ )			// 初始化集线器端口设备描述信息描述数据结构指针为NULL
		(hi_ptr->device_on_port)[ i ]	= NULL;
	dvi_ptr->class_instance_ptr	= hi_ptr;				// 保存类设备驱动描述数据结构

	return ( dvi_ptr );
}


//******************************************************************************
// 函数名称:	hub_dispose_process
// 输入参数:	dvi_ptr,设备描述信息结构指针
// 输出参数:	只返回0表示正确
// 功能描述: 集线器设备删除处理
//*******************************************************************************
unsigned short hub_dispose_process( device_instance *dvi_ptr )
{
	hub_instance		*hi_ptr;
	device_instance	*downstream_device_ptr;
	unsigned char		i;

	hi_ptr = (hub_instance *) dvi_ptr->class_instance_ptr;	// 获取集线器类设备描述信息	
	atl_close_transfer_instance( hi_ptr->tr_instance_ptr);	// 删除传输描述符

	for ( i = 0; i < hi_ptr->number_of_ports; i++ )			// 删除集线器端口下设已连接的设备
	{	downstream_device_ptr	= (hub_instance_ptr( dvi_ptr )->device_on_port)[ i ];
		if ( NULL != downstream_device_ptr )
			dispose_device( &downstream_device_ptr );		
	}
	return ( 0 );
}

//*****************************************************************************
// 函数名称:hub_callback
// 输入参数:tr_instance_ptr,传输描述符结构指针
// 输出参数:无
// 功能描述:集线器设备中断传输的回调函数。
//*****************************************************************************
void hub_callback( transfer_instance *tr_instance_ptr )
{
	hub_event_flag	this_event;
	endpoint_info_ptr epi_ptr;

	epi_ptr = tr_instance_ptr->epi_ptr;
	this_event.port_status_change_bit_map = *(tr_instance_ptr->data_ptr_base);

	re_enable_interrupt_transfer( tr_instance_ptr );	// 重新使能中断传输

	if(tr_instance_ptr->completion_code !=0)
		return ;

	this_event.hub_address	  = epi_ptr->dev_addr;
	this_event.topology_layer = (find_device( this_event.hub_address ))->topology_layer;

	if ( g_hub_device_event.hub_address )
		if ( g_hub_device_event.topology_layer < this_event.topology_layer ) 
			return;
	
	g_hub_device_event.hub_address	= this_event.hub_address;
	g_hub_device_event.port_status_change_bit_map = this_event.port_status_change_bit_map;
	g_hub_device_event.topology_layer 	= this_event.topology_layer;

	g_event_marker = DEVICE_HUB_EVENT;
	OSSemPost(OS_rhsc_event);
}


/******************************************************************************/
/* 集线器功能控制函数	                                                                                            */
/******************************************************************************/

//*****************************************************************************
// 函数名称:read_hub_device_port_status
// 输入参数:dvi_ptr,集线器设备描述信息结构指针
//				   port,端口号
// 输出参数:返回端点状态标数据
// 功能描述:读集线器设备端口状态
//*****************************************************************************
unsigned long read_hub_device_port_status( device_instance *dvi_ptr, unsigned char port )
{
	unsigned long	data = 0;
	unsigned short	size;
	
	size	= 4;
	std_request( (unsigned char *)(&data), dvi_ptr, hub_cls_sp_request_GetPortStatus, 0, port, &size );

	return ( data );
}

//*****************************************************************************
// 函数名称:reset_hub_device_port
// 输入参数:dvi_ptr,集线器设备描述信息结构指针
//				   port,端口号
// 输出参数:无
// 功能描述:复位集线器下行端口
//*****************************************************************************
void reset_hub_device_port( device_instance *dvi_ptr, unsigned char port )
{
	unsigned long	dummy;
	unsigned short	size;
	
	size	= 0;
	std_request( (unsigned char *)(&dummy), dvi_ptr, hub_cls_sp_request_SetPortFeature, PORT_RESET, port, &size );
}

//*****************************************************************************
// 函数名称:clear_hub_device_port
// 输入参数:dvi_ptr,集线器设备描述信息结构
//			           port,端口号
// 输出参数:无
// 功能描述:清除集线器端口特性
//*****************************************************************************
void clear_hub_device_port( device_instance *dvi_ptr, unsigned char port )
{
	unsigned long	dummy;
	unsigned short	size;
	
	size	= 0;
	std_request( (unsigned char *)(&dummy), dvi_ptr, hub_cls_sp_request_ClearPortFeature, C_PORT_CONNECTION, port, &size );
}

//*****************************************************************************
// 函数名称: 	clear_status_change_bits_in_hub
// 输入参数:	dvi_ptr,
//				port,
//				pos
// 输出参数:	无
// 功能描述:	清除集线器端口状态改变位
//*****************************************************************************
void clear_status_change_bits_in_hub( device_instance *dvi_ptr, 
										   unsigned char port, 
										   unsigned short pos )
{
	unsigned long	dummy;
	unsigned short	size;
	
	size	= 0;
	std_request( (unsigned char *)(&dummy), dvi_ptr, hub_cls_sp_request_ClearPortFeature, pos, port, &size );
}

⌨️ 快捷键说明

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