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

📄 dev_ep.c

📁 isp1160_isa_evel_codeUSB主机软件
💻 C
字号:
/*
**  Kenobi2          version 1.3
**
**      ** This code has been made to check/learn the 1161 functionalities ** 
**      ** Release 25-Feb-2002                                             **
**
**      OKANO, Akifumi 
**      
**		Computing Segment, Semisonductors Div, Philips Japan Ltd.
**      akifumi.okano@philips.com
**      +81-3-3740-4668 
*/


#include	<stdio.h>
#include	<stdlib.h>
#include	<alloc.h>
#include	<limits.h>
#include	<mem.h>

#include	"tr_gene.h"
#include	"data_tr.h"
#include	"ui.h"
#include	"chap9.h"
#include	"dev_ep.h"


//	#define		Use_DESCROPTOR_SAVER		//	To use this option, make a folder named "log" in application folder
//	#define		Warn_unknown_DESCROPTOR

#define		BUFF_SIZE		UCHAR_MAX


device_instance		*device_list[ MAX_DEVICE_NUM ];


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( unsigned short **str, device_instance *dvi_ptr, unsigned char index );
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 );
void			descpiptor_saver( unsigned char *data, unsigned short size, char *descriptor_name );


device_instance *create_device( unsigned char speed )
{
	device_instance		*dvi_ptr;
	unsigned char		buffer[ BUFF_SIZE ];
	unsigned char		*data_buffer;
	unsigned char		*tmp_buffer		= NULL;
	unsigned short		rx_size;
	int					i;
	unsigned char 		reserved_address;
	
	data_buffer		= buffer;
	
	
	/*	Check : Is new address available?  */
	
	if ( (0 == (reserved_address	= device_new_address())) )
	{
		mprintf( RED, CONTINUE, "no available device address\r\n" );
		return ( NULL );
	}

	
	
	/*	Memory allocate for new device instance		*/

	if ( NULL == (dvi_ptr		= (device_instance *)malloc( sizeof( device_instance ) )) )
		mprintf( RED, ABORT, "malloc failed @ newing device instance\r\n" );
	
	
	/*	Initialize members		*/
	
	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->epi_ptr[ 0 ]	= create_endpoint( dvi_ptr, 0, Ep_Direction_CONTROL_ENDPOINT, Ep_TransferType_Control, DEFAULT_BUFFER_SIZE );
	
	
	
	/*	Communication starts  */
	
	/********************************************/	
	/*	Get Descriptor [Device] 8 bytes			*/
	/*		to get MaxPacketSize of Endpoint 0	*/
	/********************************************/	
	
	rx_size		= 8;
	
	if ( std_request( data_buffer, dvi_ptr, std_Dv_request_GET_DESCRIPTOR, descriptor_type_DEVICE, 0x0000, &rx_size ) )
		return ( NULL );

	(dvi_ptr->epi_ptr[ 0 ])->max_packet_size	= ((std_dev_descriptor *)data_buffer)->bMaxPacketSize0;



	/********************************************/	
	/*	Set Address								*/
	/*		set new device address				*/
	/********************************************/	
	
	dvi_ptr->address	= reserved_address;
	rx_size				= 0;
	
	if ( std_request( data_buffer, dvi_ptr, std_Dv_request_SET_ADDRESS, (unsigned char)(dvi_ptr->address), 0x0000, &rx_size ) )
		return ( NULL );
	
	(dvi_ptr->epi_ptr[ 0 ])->dev_addr	= dvi_ptr->address;
	
	
	
	/********************************************/	
	/*	Get Descriptor [Device] 18 bytes		*/
	/*		to get full device descriptor		*/
	/********************************************/	
	
	rx_size				= 18;

	if ( std_request( data_buffer, dvi_ptr, std_Dv_request_GET_DESCRIPTOR, descriptor_type_DEVICE, 0x0000, &rx_size ) )
		return ( NULL );
	
	memcpy( (unsigned char *)(&(dvi_ptr->dev_descriptor)), data_buffer, sizeof( std_dev_descriptor ) );



	/********************************************/	
	/*	Get Descriptor [String]					*/
	/*		If failed, returns a NULL			*/
	/********************************************/	

	if ( get_string_descriptor( &(dvi_ptr->string_manufacturer), dvi_ptr, (dvi_ptr->dev_descriptor).iManufacturer ) )
		return ( NULL );
	
	if ( get_string_descriptor( &(dvi_ptr->string_product     ), dvi_ptr, (dvi_ptr->dev_descriptor).iProduct      ) )
		return ( NULL );

	if ( get_string_descriptor( &(dvi_ptr->string_serialNum   ), dvi_ptr, (dvi_ptr->dev_descriptor).iSerialNumber ) )
		return ( NULL );



	/********************************************/	
	/*	Get Descriptor [Cnfg] 4 bytes			*/
	/*		to get the size of cnfg descriptor	*/
	/********************************************/	
		
	rx_size				= 4;

	if ( std_request( data_buffer, dvi_ptr, std_Dv_request_GET_DESCRIPTOR, descriptor_type_CONFIGURATION, 0x0000, &rx_size ) )
		return ( NULL );
				
	
	
	/********************************************/	
	/*	Get Descriptor [Cnfg] full size			*/
	/*		to get full cnfg... descriptor		*/
	/********************************************/	
		
	rx_size				= 	((std_conf_descriptor *)data_buffer)->wTotalLength;
	
	if ( rx_size > BUFF_SIZE )
	{
		if ( NULL == (tmp_buffer	= (unsigned char *)malloc( sizeof( unsigned char ) * rx_size )) )
			mprintf( RED, ABORT, "malloc failed @ newing device instance (more size temp. buffer.\r\n" );
		
		data_buffer		= tmp_buffer;
		
		//	No need to keep "data_buffer" original value. It was a pointer to local array
	}

	if ( std_request( data_buffer, dvi_ptr, std_Dv_request_GET_DESCRIPTOR, descriptor_type_CONFIGURATION, 0x0000, &rx_size ) )
		return ( NULL );
	
	/*	NOTE :	The CONFIGURATION descriptor is just 9 byte descriptor.	 */
	/*			INTERFACE, ENDPOINT descriptor will follow after this	 */

	set_config_descriptors( dvi_ptr, data_buffer, rx_size );
	
	
	
	/********************************************/	
	/*	Set Configuration						*/
	/*		---------------------				*/
	/********************************************/	
	
	rx_size				= 0;
	
	if ( std_request( data_buffer, dvi_ptr, std_Dv_request_SET_CONFIGURATION, ((dvi_ptr->conf_descriptor).bConfigurationValue), 0x0000, &rx_size ) )
		return ( NULL );
	
	
//	device_infomation_viewer( dvi_ptr );
	
	if ( tmp_buffer != NULL )
		free( tmp_buffer );
	
	device_list[ reserved_address ]		= dvi_ptr;
	
	return ( dvi_ptr );
}


unsigned short get_string_descriptor( unsigned short **unicode_str_ptr_ptr, device_instance *dvi_ptr, unsigned char index )
{
	char				tmp_str[ 2 ];
	unsigned short		rx_size;
	unsigned short		err;
	
	if ( index == 0 )
		return( 0 );

	rx_size		= 2;

	if ( 0 != (err	= std_request( tmp_str, dvi_ptr, std_Dv_request_GET_DESCRIPTOR, descriptor_type_STRING | index, 0x0409, &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 ( NULL );																						//	Don't care. It's just a string descriptor (optional).
	
	if ( 0 != (err	= std_request( (unsigned char *)(*unicode_str_ptr_ptr), dvi_ptr, std_Dv_request_GET_DESCRIPTOR, descriptor_type_STRING | index, 0x0409, &rx_size )) )
		return ( err );
		
#if 0
	{
		int		i;
		
		mprintf( LIGHTGRAY, CONTINUE, "\r\n" );
		
		for ( i = 1; i < (rx_size >> 1); i++ )
			putchar( *(*unicode_str_ptr_ptr + i) & 0xFF );
			
	}
#endif

	return ( 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 );
	
//	mprintf( YELLOW, CONTINUE, "std_request 0x%02X 0x%04X --> 0x%02X\r\n", req.bmRequestType, req.bRequest, err );
	
	if ( err )
	{
		if ( err & 0xF000 )						//	short data received
		{
			*wLength		= err & 0x00FF;		//	In the case of no error, value is not updated.
			err 			= 0;				//	Clear error flag
		}
		else
		{
			dispose_device( dvi_ptr );
			mprintf( RED, CONTINUE, "error detected in control_transfer 0x%04X\r\n", err );
		}
	}
	
	return ( err );
}


#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;
	
	
#ifdef	Use_DESCROPTOR_SAVER
	int							save_flag	= 0;
	unsigned char				*buf_base;
	
	buf_base	= buf;
#endif


	buf_end		= buf + length;

	while ( buf < buf_end )
	{
		desc_length		= descriptor_length( buf );
		desc_type		= descriptor_type( buf ) << 8;	/*	See "chap9.h". Constants descriptor_type_XXX are 
															defined as upper byte in unsigned short				*/
		
		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 )
				{
					/*  This processing is not right to do  			*/
					/*	The interface descriptor may not be only one	*/
				
					memcpy( (unsigned char *)(&(dvi_ptr->interfacef_descriptor)), (unsigned char *)(buf), sizeof( std_interface_descriptor ) );
					get_just_one_interface_descripter	= 0;
				}
//				mprintf( WHITE, CONTINUE, "((std_interface_descriptor *)buf).bInterfaceClass = 0x%02X\r\n", ((std_interface_descriptor *)buf)->bInterfaceClass );
				break;
			case descriptor_type_ENDPOINT :
				memcpy( (unsigned char *)(&(tmp_ep_desc)), (unsigned char *)(buf), sizeof( std_endpoint_descriptor ) );

				if ( !(dvi_ptr->epi_ptr[ EpNumber_bEndpointAddress( tmp_ep_desc.bEndpointAddress ) ]) )
				{
					epi_ptr		= create_endpoint(	
													dvi_ptr, 
													EpNumber_bEndpointAddress( tmp_ep_desc.bEndpointAddress ),
													EpDirection_bEndpointAddress( tmp_ep_desc.bEndpointAddress ),
													Ep_TransferType_bmAttributes( tmp_ep_desc.bmAttributes ), 
													tmp_ep_desc.wMaxPacketSize
												);
												
					epi_ptr->endpoint_descriptor													= tmp_ep_desc;		
					dvi_ptr->epi_ptr[ EpNumber_bEndpointAddress( tmp_ep_desc.bEndpointAddress ) ]	= epi_ptr;
				}
				
				
				if ( NULL == epi_ptr )
				{
					mprintf( RED, CONTINUE, "error @ GetDescriptor [CONFIGURATION] : Could not make a endpoint instance\r\n" );
					return ( 1 );
				}
				
				break;
			default :
			
#ifdef	Use_DESCROPTOR_SAVER
				save_flag	= 1;
#else
#ifdef	Warn_unknown_DESCROPTOR
				mprintf( RED, CONTINUE, "Warning @ GetDescriptor [CONFIGURATION] : Unknown DESCRIPTOR [0x%02X] @ byte=%d\r\n", desc_type, buf - (buf_end - length) );
#endif  //  end of Warn_unknown_DESCROPTOR
#endif  //  end of Use_DESCROPTOR_SAVER

				break;
		}
		
		buf		+= desc_length;
	}
	
#ifdef	Use_DESCROPTOR_SAVER
		
	if ( save_flag )
		descpiptor_saver( buf_base, length, "desc-conf" );
	
#endif
	
	return ( 0 );
}


void dispose_device( device_instance *dvi_ptr )
{
	int		i;
	
	if ( dvi_ptr == NULL )
		return;
	
	device_list[ dvi_ptr->address ]		= NULL;
	
	for ( i = 0; i < MAX_ENDPOINT_NUM; i++ )
		if ( dvi_ptr->epi_ptr[ i ] != NULL )
			dispose_endpoint( dvi_ptr, i );
	
	if ( NULL != dvi_ptr->string_manufacturer )
		free( dvi_ptr->string_manufacturer );
		
	if ( NULL != dvi_ptr->string_product )
		free( dvi_ptr->string_product );
		
	if ( NULL != dvi_ptr->string_serialNum )
		free( dvi_ptr->string_serialNum );

	free( dvi_ptr );
}


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	= (endpoint_info *)malloc( sizeof( endpoint_info ) )) )
		mprintf( RED, ABORT, "malloc failed @ epi_ptr malloc err\r\n" );

	dvi_ptr->epi_ptr[ index ]	= epi_ptr;
	
	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;
	epi_ptr->transfer_type		= transfer_type;
	
	if ( transfer_type == Ep_TransferType_Isochronous )
		epi_ptr->tr_type		= Format_Iso;
	else
		epi_ptr->tr_type		= Format_Async;
		
	return ( epi_ptr );
}


void dispose_endpoint( device_instance *dvi_ptr, unsigned short index )
{
	free( dvi_ptr->epi_ptr[ index ] );
	
	dvi_ptr->epi_ptr[ index ]	= NULL;
}


void device_list_linitialize( void )
{
	int		i;
	
	device_list[ 0 ]	= (device_instance *)1;
	device_list[ 1 ]	= (device_instance *)1;
	
	for ( i = 2; i < MAX_DEVICE_NUM; i++ )
		device_list[ i ]	= NULL;
}


unsigned char device_new_address( void )
{
	int		i;

	for ( i = 2; i < MAX_DEVICE_NUM; i++ )
		if ( !device_list[ i ] )
			return ( i );
	
	return ( 0 );
}


#ifdef	Use_DESCROPTOR_SAVER

#include	<time.h>
#define		FN_LENGTH_LIM		256

void descpiptor_saver( unsigned char *data, unsigned short size, char *descriptor_name )
{
	FILE	*fp;
	char	str[ FN_LENGTH_LIM ];
	char	time_str[ FN_LENGTH_LIM ];
	time_t	t;

	time( &t );

#if 0
//no use turboC can handle only 8 byte file name!!!  (ToT)
	strftime( time_str, FN_LENGTH_LIM, "%Y%b%d-%H%M", localtime( &t ) );
	strncpy( str, descriptor_name, FN_LENGTH_LIM );
	strncat( str, time_str, FN_LENGTH_LIM );
#endif

	strftime( str, FN_LENGTH_LIM, "log/d%dt%H%M.dsc", localtime( &t ) );


	if ( NULL == (fp	= fopen( str, "wb" )) )
	{
		mprintf( RED, CONTINUE, "Warning : failed to open a file named \"%s\" to save the descripter", str );
		return;
	}
	
	fwrite( data, sizeof( unsigned char ), size, fp );
	fclose( fp );
	
	mprintf( RED, CONTINUE, "a file \"%s\" has been made to save the descriptor", str );		
}
#endif  //  enf of Use_DESCROPTOR_SAVER



device_instance *find_device( unsigned char address )
{
	return ( device_list[ address ] );
}


device_instance *find_class_interface( unsigned char InterfaceClassID )
{
	device_instance		*dviPtr;
	int					i;
	
	for ( i = 2; i < 128; i++ )
	{	
		if ( NULL == (dviPtr	= find_device( i )) )
			continue;

		if ( check_interface_class_ID( dviPtr, InterfaceClassID ) )
			return ( dviPtr );
	}
	
	return ( NULL );
}


unsigned char check_interface_class_ID( device_instance *dviPtr, unsigned char InterfaceClassID )
{
	if ( (dviPtr->dev_descriptor).bDeviceClass == 0x00 )
		if ( (dviPtr->interfacef_descriptor).bInterfaceClass == InterfaceClassID )
			return ( 1 );

	return ( 0 );
}






⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -