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

📄 dev_ep.c

📁 usb host在ARM7上的实现
💻 C
📖 第 1 页 / 共 3 页
字号:
#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 + -