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

📄 dev_ep.c

📁 基于ARM的读U盘
💻 C
📖 第 1 页 / 共 3 页
字号:
/****************************************************************************/
/*	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 + -