📄 hub.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 + -