📄 dev_ep.c
字号:
#endif
device_list[ reserved_address ] = dvi_ptr;
return ( dvi_ptr );
}
#ifdef STRING_DESCRIPTOR
//*******************************************************************************
// 函数名称:get_string_descriptor_LANG_code
// 输入参数:code,保存unicode区域代码
// 输出参数:正常返回0,出错返回出错代码,
// 功能描述:获取字符串描述符区域代码
//*******************************************************************************
unsigned short get_string_descriptor_LANG_code( unsigned short *code, device_instance *dvi_ptr )
{
#define LANG_code_request 0x00
unsigned char tmp_str[ 4 ];
unsigned short rx_size;
unsigned short err;
rx_size = 4;
if ( 0 != (err = std_request( tmp_str, dvi_ptr,
std_Dv_request_GET_DESCRIPTOR,
descriptor_type_STRING | LANG_code_request,
0x0000, &rx_size )) )
return ( err );
*code = *(((unsigned short *)tmp_str) + 1);
return ( 0 );
}
#endif
#ifdef STRING_DESCRIPTOR
//*******************************************************************************************
// 函数名称:get_string_descriptor
// 输入参数:unicode_str_ptr_ptr,保存字符串描述符指针的指针
// dvi_ptr,设备描述信息数据结构指针
// index,字符串索引号
// language_ID,UNICODE编码ID
// 输出参数:正常返回0,出错返回出错代码,内存出错返回0xff
// 功能描述:获取设备字符串描述符
//*******************************************************************************************
unsigned char get_string_descriptor( unsigned short **unicode_str_ptr_ptr,
device_instance *dvi_ptr,
unsigned char index,
unsigned short language_ID )
{
unsigned char tmp_str[ 2 ];
unsigned short rx_size;
unsigned short err;
if ( index == 0 )
{
*unicode_str_ptr_ptr = NULL;
return( 0 );
}
rx_size = 2;
if ( 0 != (err = std_request( tmp_str, dvi_ptr,
std_Dv_request_GET_DESCRIPTOR,
descriptor_type_STRING | index,
language_ID, &rx_size )) )
return ( err );
rx_size = ((std_string_descriptor *)tmp_str)->bLength;
if ( NULL == (*unicode_str_ptr_ptr = (unsigned short *)malloc( sizeof( unsigned char ) * rx_size )) ) // Because the "rx_size" is given as a number of bytes.
return 0xff;
if ( 0 != (err= std_request( (unsigned char *)(*unicode_str_ptr_ptr), dvi_ptr,
std_Dv_request_GET_DESCRIPTOR,
descriptor_type_STRING | index,
language_ID, &rx_size )) )
return ( err );
return ( 0 );
}
#endif
//*******************************************************************************
// 函数名称:std_request
// 输入参数:buff_ptr,传输数据缓冲区指针
// dvi_ptr,设备描述信息结构指针
// request,标准请求类型
// wValue,值
// wIndex,索引
// wLength,长度
// 输出参数:正常返回0,出错返回出错代码。
// 功能描述:发送和接收标准请求。
//*******************************************************************************
unsigned short std_request( unsigned char *buff_ptr,
device_instance *dvi_ptr,
unsigned short request,
unsigned short wValue,
unsigned short wIndex,
unsigned short *wLength )
{
USB_Device_Request req;
unsigned short err;
req.bmRequestType = reqtype( request );
req.bRequest = request( request );
req.wValue = wValue;
req.wIndex = wIndex;
req.wLength = *wLength;
err = control_transfer( &req, dvi_ptr, buff_ptr ); // 控制传输
if ( err )
{ if ( err & 0x8000 ) // 接收到短包
{ *wLength = err & 0x7FFF; // 短包不是错误,返回传输长度
err = 0; // 清错误标记
}
}
return ( err );
}
//**************************************************************************
// 函数名称: set_config_descriptors
// 输入参数: dvi_ptr,设备描述信息结构指针
// buf,配置描述符集合
// length,配置描述符集合长度
// 输出参数:正确返回TURE,出错返回FALSE
// 功能描述: 设置配置描述符.
//**************************************************************************
#define descriptor_length( x ) *( x )
#define descriptor_type( x ) *( (x) + 1 )
unsigned char set_config_descriptors( device_instance *dvi_ptr,
unsigned char *buf,
unsigned short length )
{
unsigned char *buf_end;
unsigned char desc_length;
unsigned short desc_type;
std_endpoint_descriptor tmp_ep_desc;
endpoint_info *epi_ptr;
unsigned char get_just_one_interface_descripter= 1;
unsigned char pip_index;
buf_end = buf + length;
while ( buf < buf_end )
{
desc_length = descriptor_length( buf ); // 设备描述符类型
desc_type = descriptor_type( buf ) << 8; // 设备描述符类型
switch ( desc_type )
{
case descriptor_type_CONFIGURATION : // 配置描述符
memcpy( (unsigned char *)(&(dvi_ptr->conf_descriptor)), (unsigned char *)(buf), sizeof( std_conf_descriptor ) );
break;
case descriptor_type_INTERFACE : // 接口描述符
if ( get_just_one_interface_descripter ) // 设备可能会有多个接口描述符,但本驱动只支持第1个
{
memcpy( (unsigned char *)(&(dvi_ptr->interfacef_descriptor)), (unsigned char *)(buf), sizeof( std_interface_descriptor ) );
get_just_one_interface_descripter = 0;
}
break;
case descriptor_type_ENDPOINT : // 端点描述符
memcpy( (unsigned char *)(&(tmp_ep_desc)), (unsigned char *)(buf), sizeof( std_endpoint_descriptor ) );
pip_index = EpNum_bEndAdd( tmp_ep_desc.bEndpointAddress ) * 2
+EpDir_bEndAdd( tmp_ep_desc.bEndpointAddress ) ;
if ( !(dvi_ptr->epi_ptr[ pip_index ]) )
{ epi_ptr = create_endpoint( dvi_ptr, // 建立HCD端点描述信息数据结构
EpNum_bEndAdd( tmp_ep_desc.bEndpointAddress ),
EpDir_bEndAdd( tmp_ep_desc.bEndpointAddress ),
Ep_TranType_bmAttr( tmp_ep_desc.bmAttributes ),
tmp_ep_desc.wMaxPacketSize );
if ( NULL == epi_ptr )
return FALSE ;
epi_ptr->endpoint_descriptor = tmp_ep_desc;
dvi_ptr->epi_ptr[ pip_index ] = epi_ptr; // 保存端点描述信息结构到设备端点列表
}
else
return TRUE;
break;
default :
break;
}
buf += desc_length;
}
return FALSE;
}
//**************************************************************************
// 函数名称:dispose_device
// 输入参数:dvi_ptr_ptr,指向设备描述信息结构指针的指针
// 输出参数:无
// 功能描述:删除设备
//**************************************************************************
void dispose_device( device_instance **dvi_ptr_ptr )
{
unsigned char i;
if ( (*dvi_ptr_ptr) == NULL )
return;
disable();
#ifdef CLASS_DRIVE
if ( NULL != ((*dvi_ptr_ptr)->class_instance_ptr) ) // 如果设备为类设备,删除类设备信息
class_drive_dispose( *dvi_ptr_ptr ); // 删除类设备
#endif
if((*dvi_ptr_ptr)->address >1)
device_list[ (*dvi_ptr_ptr)->address ] = NULL;
for ( i = 0; i < MAX_ENDPOINT_NUM; i++ ) // 删除设备端点描述信息
if ( (*dvi_ptr_ptr)->epi_ptr[ i ] != NULL )
dispose_endpoint( *dvi_ptr_ptr, i );
#ifdef STRING_DESCRIPTOR
/* 释放字符串描述符占用的RAM */
if ( NULL != (*dvi_ptr_ptr)->string_manufacturer )
free( (*dvi_ptr_ptr)->string_manufacturer );
if ( NULL != (*dvi_ptr_ptr)->string_product )
free( (*dvi_ptr_ptr)->string_product );
if ( NULL != (*dvi_ptr_ptr)->string_serialNum )
free( (*dvi_ptr_ptr)->string_serialNum );
if ( NULL != (*dvi_ptr_ptr)->class_instance_ptr )
free( (*dvi_ptr_ptr)->class_instance_ptr );
#endif
free_device_instance( *dvi_ptr_ptr ); // 删除设备信息结构
*dvi_ptr_ptr = NULL;
enable();
}
/*************************************************
**
** Cleate endpoint instance
**
*************************************************/
//**************************************************************************
// 函数名称: create_endpoint
// 输入参数: dvi_ptr,设备描述信息结构指针
// index,端点索引号
// direction,端点方向
// transfer_type,端点传输类型
// max_packet_size,端点最大包大小
// 输出参数: 无
// 功能描述: 建立端点描述信息结构指针
//**************************************************************************
endpoint_info *create_endpoint( device_instance *dvi_ptr,
unsigned short index,
unsigned short direction,
unsigned short transfer_type,
unsigned short max_packet_size )
{
endpoint_info *epi_ptr;
if ( NULL == (epi_ptr= malloc_endpoint_info( ) )) // 释取端点描述信息结构
return ( NULL );
epi_ptr->max_packet_size = max_packet_size;
epi_ptr->dev_addr = dvi_ptr->address;
epi_ptr->ep_num = index;
epi_ptr->toggle = 0;
epi_ptr->speed = dvi_ptr->speed; // 速度:全速低速
epi_ptr->direction = direction; // 方向:IN、OUT
epi_ptr->transfer_type = transfer_type|ENDPOINT_SHARE; // 设端点为可共享
if ( transfer_type == Ep_TransferType_Isochronous )
epi_ptr->tr_type = Format_Iso; // 标记该端点为同步传输
else
epi_ptr->tr_type = Format_Async; //
//-----------------------------------------
epi_ptr->endpoint_create_id = g_sof_counter;// 端点创建ID
return epi_ptr ;
}
/*************************************************
**
** Dispose endpoint instance
**
*************************************************/
//**************************************************************************
// 函数名称: dispose_endpoint
// 输入参数: dvi_ptr,设备描述信息结构指针
// index,端点索引号
// 输出参数: 无
// 功能描述: 卸载端点描述信息
//**************************************************************************
void dispose_endpoint( device_instance *dvi_ptr, unsigned short index )
{
transfer_instance *tr_inst_ptr;
disable();
tr_inst_ptr = dvi_ptr->epi_ptr[ index ]->tr_instance_ptr;
if(dvi_ptr->epi_ptr[ index ]->ep_num==0x2)
dvi_ptr = dvi_ptr;
while(tr_inst_ptr !=NULL) // 扫描端点相关的传输描述符
{
atl_close_transfer_instance(tr_inst_ptr);// 删除传输描述符
tr_inst_ptr = tr_inst_ptr->tr_list_for_ep.Blink; //指向下一个传输描述符
}
free_endpoint_info( dvi_ptr->epi_ptr[ index ] ); // 释放端点数据结构
dvi_ptr->epi_ptr[ index ] = NULL;
enable();
}
//**************************************************************************
// 函数名称: device_list_linitialize
// 输入参数: 无
// 输出参数: 返回地址编号
// 功能描述: 初始化设备列表
//**************************************************************************
void device_list_linitialize( void )
{
int i;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -