📄 dev_ep.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 + -