📄 dev_ep.c
字号:
/****************************************************************************/
/* includes */
/****************************************************************************/
#include "HostStack.h"
#ifndef MAX_DEV_INF_MEMRY
#define MAX_DEV_INF_MEMRY 10 // 定义设备描述符
#endif
#ifndef MAX_ENDP_INF_MEMRY
#define MAX_ENDP_INF_MEMRY 60 // 定义端点描述符个数
#endif
/****************************************************************************/
/* global vars */
/****************************************************************************/
device_instance *device_list[ MAX_DEVICE_NUM ];
/****************************************************************************/
/* function prototypes */
/****************************************************************************/
endpoint_info *create_endpoint( device_instance *dvi_ptr, unsigned short index, unsigned short direction, unsigned short transfer_type, unsigned short max_packet_size );
unsigned short get_string_descriptor_LANG_code( unsigned short *code, device_instance *dvi_ptr );
unsigned char get_string_descriptor( unsigned short **unicode_str_ptr_ptr, device_instance *dvi_ptr, unsigned char index, unsigned short language_ID );
unsigned char set_config_descriptors( device_instance *dvi_ptr, unsigned char *buf, unsigned short length );
void dispose_endpoint( device_instance *dvi_ptr, unsigned short index );
void device_list_linitialize( void );
unsigned char device_new_address( void );
/****************************************************************************/
/* function definitions */
/****************************************************************************/
//***************************************************************************
// 分配device_instance内存
//***************************************************************************
unsigned char DevInfMemIndex[MAX_DEV_INF_MEMRY];
device_instance device_infomation[MAX_DEV_INF_MEMRY] ;
void ini_device_instance(void)
{
unsigned short i;
for(i=0;i<MAX_DEV_INF_MEMRY;i++) //
device_infomation[i].address = 0xff;
}
//***********************************************************************
//函数名称:malloc_device_instance
//输入参数:无
//输出参数:设备描述信息指针
//函数功能:分配设备信息内存
//***********************************************************************
device_instance * malloc_device_instance(void)
{
unsigned short i;
for(i=0;i<MAX_DEV_INF_MEMRY;i++) //
if( device_infomation[i].address == 0xff)
{
device_infomation[i].address=0;
return &device_infomation[i]; // 返回可用缓冲区指针
}
return (NULL);
}
//***********************************************************************
//函数名称:free_device_instance
//输入参数:dvi_ptr,设备描述信息指针
//输出参数:无
//函数功能:释放设备信息内存
//***********************************************************************
void free_device_instance(device_instance * dvi_ptr)
{
unsigned short i;
for(i=0;i<MAX_DEV_INF_MEMRY;i++) //
if((&device_infomation[i])==dvi_ptr)
{
device_infomation[i].address = 0xff;
break;
}
}
//***********************************************************************
// 端点描述信息结构
//***********************************************************************
unsigned char EndpInfMemIndex[MAX_ENDP_INF_MEMRY];
endpoint_info endpoint_infomation[MAX_ENDP_INF_MEMRY] ;
void ini_endpoint_info(void)
{
unsigned short i;
for(i=0;i<MAX_ENDP_INF_MEMRY;i++)
{
endpoint_infomation[i].ep_num = ENDPOINT_BE_FREE;
endpoint_infomation[i].tr_instance_ptr = NULL;//不是必需的
}
}
//***********************************************************************
//函数名称:malloc_endpoint_info
//输入参数:无
//输出参数:端点描述信息指针
//函数功能:分配端点信息内存
//***********************************************************************
endpoint_info * malloc_endpoint_info(void)
{
unsigned short i;
for(i=0;i<MAX_ENDP_INF_MEMRY;i++) //
if(endpoint_infomation[i].ep_num == ENDPOINT_BE_FREE)
{
endpoint_infomation[i].ep_num = 0 ;
return &(endpoint_infomation[i]);
}
return (NULL);
}
//***********************************************************************
//函数名称:free_endpoint_info
//输入参数:dvi_ptr,设备描述信息指针
//输出参数:无
//函数功能:释放端点信息内存
//***********************************************************************
void free_endpoint_info( endpoint_info * epi_ptr)
{
epi_ptr->ep_num = ENDPOINT_BE_FREE;
epi_ptr->tr_instance_ptr = NULL;
}
/*************************************************
**
** Create a device instance
**
*************************************************/
//************************************************************************
// 函数名称:create_device
// 输入参数:speed,全速或低速设备
// topology_layer
// 输出参数:设备描述信息结构指针,出错返回NULL
// 功能描述:建立USB外设
//***********************************************************************
device_instance *create_device( unsigned char speed, unsigned char topology_layer )
{
device_instance *dvi_ptr;
unsigned char buffer[64];
unsigned char *config_desc_buffer = NULL;
unsigned short rx_size;
unsigned char i;
unsigned char reserved_address;
#ifdef STRING_DESCRIPTOR
unsigned short language_ID;
#endif
if ( (0 == (reserved_address = device_new_address())) ) // 获取一个设备地址
return ( NULL );
if ( NULL == (dvi_ptr= malloc_device_instance( ) )) // 分配一个设备描述信息结构RAM
return ( NULL );
/* 初始化设备描述信息结构 */
dvi_ptr->address = 0;
dvi_ptr->speed = speed;
for ( i = 0; i < MAX_ENDPOINT_NUM; i++ ) // 初始化该设备的端点描述结构指针
dvi_ptr->epi_ptr[ i ] = NULL;
dvi_ptr->string_manufacturer = NULL;
dvi_ptr->string_product = NULL;
dvi_ptr->string_serialNum = NULL;
dvi_ptr->class_instance_ptr = NULL;
dvi_ptr->topology_layer = topology_layer;
dvi_ptr->epi_ptr[ 0 ] = create_endpoint( dvi_ptr, 0,
Ep_Direction_CONTROL_ENDPOINT,
Ep_TransferType_Control,
DEFAULT_BUFFER_SIZE );
if(dvi_ptr->epi_ptr[ 0 ]==NULL)
{
dispose_device( &dvi_ptr );
return ( NULL );
}
dvi_ptr->epi_ptr[ 1 ] = create_endpoint( dvi_ptr, 1,
Ep_Direction_CONTROL_ENDPOINT,
Ep_TransferType_Control,
DEFAULT_BUFFER_SIZE );
if(dvi_ptr->epi_ptr[ 1 ]==NULL)
{
dispose_device( &dvi_ptr );
return ( NULL );
}
/* 以下枚举开始 */
/********************************************/
/* 首先获设备8个字节设备描述符*/
/* 从而获得默认端点MaxPacketSize */
/********************************************/
rx_size = 8;
if ( std_request( buffer, dvi_ptr, std_Dv_request_GET_DESCRIPTOR, descriptor_type_DEVICE, 0x0000, &rx_size ) )
{
dispose_device( &dvi_ptr );
return ( NULL );
}
dvi_ptr->epi_ptr[ 0 ]->max_packet_size = ((std_dev_descriptor *)buffer)->bMaxPacketSize0;
dvi_ptr->epi_ptr[ 1 ]->max_packet_size = ((std_dev_descriptor *)buffer)->bMaxPacketSize0;
/********************************************/
/* 设备地址,为设备设置一个 */
/* 新地址 */
/********************************************/
dvi_ptr->address = reserved_address;
rx_size = 0;
if ( std_request( buffer, dvi_ptr, std_Dv_request_SET_ADDRESS, (unsigned char)(dvi_ptr->address), 0x0000, &rx_size ) )
{
dispose_device( &dvi_ptr );
return ( NULL );
}
dvi_ptr->epi_ptr[ 0 ]->dev_addr = dvi_ptr->address;
dvi_ptr->epi_ptr[ 1 ]->dev_addr = dvi_ptr->address;
/********************************************/
/* 获取18字节的设备描述符 */
/* */
/********************************************/
rx_size = 18;
if ( std_request( buffer, dvi_ptr,
std_Dv_request_GET_DESCRIPTOR,
descriptor_type_DEVICE,
0x0000, &rx_size ) )
{
dispose_device( &dvi_ptr );
return ( NULL );
}
memcpy( (unsigned char *)(&(dvi_ptr->dev_descriptor)), buffer, sizeof( std_dev_descriptor ) );
#ifdef STRING_DESCRIPTOR
/********************************************/
/* 获取字符串描述符 */
/* 如所失败返回NULL */
/********************************************/
if ( (dvi_ptr->dev_descriptor).iManufacturer |
(dvi_ptr->dev_descriptor).iProduct |
(dvi_ptr->dev_descriptor).iSerialNumber )
{
if ( get_string_descriptor_LANG_code( &language_ID, dvi_ptr ) )
return ( NULL );
if ( get_string_descriptor( &(dvi_ptr->string_manufacturer), dvi_ptr,
(dvi_ptr->dev_descriptor).iManufacturer, language_ID ) )
return ( NULL );
if ( get_string_descriptor( &(dvi_ptr->string_product ), dvi_ptr,
(dvi_ptr->dev_descriptor).iProduct, language_ID ) )
return ( NULL );
if ( get_string_descriptor( &(dvi_ptr->string_serialNum ), dvi_ptr,
(dvi_ptr->dev_descriptor).iSerialNumber, language_ID ) )
return ( NULL );
}
#endif
/********************************************/
/* 获取配置描述符前4字节 */
/* 从而获取配置描述符集长度*/
/********************************************/
rx_size = 4;
if ( std_request( buffer, dvi_ptr,
std_Dv_request_GET_DESCRIPTOR,
descriptor_type_CONFIGURATION,
0x0000, &rx_size ) )
{
dispose_device( &dvi_ptr );
return ( NULL );
}
/********************************************/
/* 获取配置描述符集 */
/* */
/********************************************/
rx_size = ((std_conf_descriptor *)buffer)->wTotalLength;
if ( NULL == (config_desc_buffer = (unsigned char *)malloc( sizeof( unsigned char ) * rx_size )) )
return ( NULL );
if ( std_request( config_desc_buffer, dvi_ptr,
std_Dv_request_GET_DESCRIPTOR,
descriptor_type_CONFIGURATION,
0x0000, &rx_size ) )
{
free( config_desc_buffer );
dispose_device( &dvi_ptr );
return ( NULL );
}
if(set_config_descriptors( dvi_ptr, config_desc_buffer, rx_size ))
{
free( config_desc_buffer );
dispose_device( &dvi_ptr );
return ( NULL );
}
free( config_desc_buffer );
/********************************************/
/* 设置配置 */
/* -------------------- */
/********************************************/
rx_size = 0;
if ( std_request( buffer, dvi_ptr,
std_Dv_request_SET_CONFIGURATION,
((dvi_ptr->conf_descriptor).bConfigurationValue),
0x0000, &rx_size ) )
{
dispose_device( &dvi_ptr );
return ( NULL );
}
#ifdef CLASS_DRIVE
/********************************************/
/* 安装设备类驱动 */
/* -------------------- */
/********************************************/
if ( class_driver_install( dvi_ptr ) ) // 安装设备类驱动入口
{
dispose_device( &dvi_ptr );
return ( NULL );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -