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

📄 hub.c

📁 使用ISP1362芯片的USB_OTG参考设计源代码比较新的版本
💻 C
字号:
/*
**  WASABI-Hot! version 1.2c    (Hub sub-unit)
**
**
**      -- copyright (c) 2001-2004 by Philips Japan, Ltd. -- All rights reserved --
**
**
**      ** This code has been made to check/learn                          ** 
**      **                             the ISP1362/ISP1363 functionalities **
**      ** Release 06-Aug-2004                                             **
**
**      OKANO, Akifumi
**      
**		Application Laboratory, Mobile and Connectivity
**      Semiconductors Div, Philips Japan Ltd.
**      akifumi.okano@philips.com
**      +81-3-3740-4668 
*/


/****************************************************************************/
/*	includes																*/
/****************************************************************************/

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

#include		"_hc_core/atl_mix.h"
#include		"_hc_core/dev_ep.h"
#include		"_hc_core/port_ctl.h"
#include		"_hc_core/transfer.h"

#include		"class_dr/hub/hub.h"

#include		"ui.h"
#include		"general.h"


/****************************************************************************/
/*	function prototypes														*/
/****************************************************************************/

device_instance		*create_hub_class_instance( device_instance *dvi_ptr );
void				hub_callback( endpoint_info_ptr epi_ptr );


/****************************************************************************/
/*	function definitions													*/
/****************************************************************************/

unsigned short hub_init_commands( device_instance *dvi_ptr )
{
	unsigned char	buffer[ datalength_of_HUB_DESCRIPTOR ];
	hub_instance	*hi_ptr;
	unsigned char	number_of_ports;
	unsigned short	size;
	unsigned short	i;
	
	if ( devep_regist_config_descriptors( dvi_ptr, 1, 0 ) )
		return ( error );
	
	/*	Get hub descriptor			*/
	
	if ( NULL == create_hub_class_instance( dvi_ptr ) )
		mprintf( LIGHTRED, ABORT, "error @ create_hub_class_instance()\r\n" );

	//	Bus-power turn-on for all ports on the hub.

	hi_ptr				= (hub_instance *)hub_instance_ptr( dvi_ptr );
	number_of_ports		= number_of_port_in_hub( dvi_ptr );

	for ( i = 1; i <= number_of_ports; i++ )
	{
		size	= 0;	//	"size" may/may-not be updated by "devep_std_request()" call.
		devep_std_request( buffer, dvi_ptr, hub_cls_sp_request_SetPortFeature, PORT_POWER, i, &size );
	}

	//	Set interrupt pipe
	
	if ( (NO_OPEN_ATL_TRANSFER_SLOT == (hi_ptr->tr_index	= atlmix_get_open_transfer_index( INTERRUPT_TRANSFER ))) )
		mprintf( LIGHTRED, ABORT, "error @ transfer_control_transaction, transfer list full.\r\n" );

	hi_ptr->tr_instance_ptr		= atlmix_set_transfer( INTERRUPT_TRANSFER, hi_ptr->polling_rate, hi_ptr->tr_index, &(hi_ptr->ep1_data), 1, IN, (dvi_ptr->epi_ptr)[ EpIN ][ 1 ], hub_callback );

	return ( 0 );
}


device_instance *create_hub_class_instance( device_instance *dvi_ptr )
{
	//	This instance will be disposed in function "devep_dispose_device()"

	hub_instance	*hi_ptr;
	unsigned short	size		= datalength_of_HUB_DESCRIPTOR;
	int				i;

	if ( NULL == (hi_ptr	= (hub_instance *)malloc( 4 +  sizeof( hub_instance ) )) )
		mprintf( LIGHTRED, ABORT, "error @ malloc in create_hub_class_instance()\r\n" );

	//	Check endpoint characteristics
	
	if ( (dvi_ptr->conf_descriptor).bNumInterfaces != 1 )
		mprintf( LIGHTRED, ABORT, "error @ create_hub_class_instance, un-supported hub. (dvi_ptr->conf_descriptor).bNumInterfaces is not 1.\r\n" );
	
	if ( ((dvi_ptr->epi_ptr[ EpIN ][ 1 ])->endpoint_descriptor).bEndpointAddress != 0x81 )
		mprintf( LIGHTRED, ABORT, "error @ create_hub_class_instance, un-supported hub. ((dvi_ptr->epi_ptr[ EpIN ][ 1 ])->endpoint_descriptor).bEndpointAddress is not 0x81.\r\n" );
	
	if ( ((dvi_ptr->epi_ptr[ EpIN ][ 1 ])->endpoint_descriptor).wMaxPacketSize != 1 )
		mprintf( LIGHTRED, ABORT, "error @ create_hub_class_instance, un-supported hub. ((dvi_ptr->epi_ptr[ EpIN ][ 1 ])->endpoint_descriptor).wMaxPacketSize is not 1.\r\n" );
	
	hi_ptr->polling_rate	= ((dvi_ptr->epi_ptr[ EpIN ][ 1 ])->endpoint_descriptor).bInterval;
	
	//	Get HUB descriptor
	
	if ( devep_std_request( (hi_ptr->hub_descriptor), dvi_ptr, hub_cls_sp_request_GetHubDescripter, 0, 0, &size ) )
		return ( NULL );

	dvi_ptr->class_instance_ptr		= hi_ptr;
	
	hi_ptr->device_ptr				= dvi_ptr;
	hi_ptr->number_of_ports			= ((hub_descriptor_params *)(&(hi_ptr->hub_descriptor)))->bNbrPorts;
	hi_ptr->tr_index				= 0xFF;
	hi_ptr->tr_instance_ptr			= NULL;
	
	for ( i = 0; i < MAX_NUM_OF_PORTS; i++ )
		(hi_ptr->portctl_device_on_port)[ i ]		= NULL;

	dvi_ptr->class_instance_ptr		= hi_ptr;

	return ( dvi_ptr );
}


unsigned short hub_dispose_process( device_instance *dvi_ptr )
{
	hub_instance		*hi_ptr;
	device_instance		*downstream_device_ptr;
	int					i;

	/*
	**	Stop interrupt transfer to the hub
	*/
	
	hi_ptr				= (hub_instance *)hub_instance_ptr( dvi_ptr );
	atlmix_free_transfer_index( INTERRUPT_TRANSFER, hi_ptr->tr_index );


	/*
	**	Dispose devices at downstream ports
	*/
	
	for ( i = 0; i < hi_ptr->number_of_ports; i++ )
	{
		downstream_device_ptr	= (hub_instance_ptr( dvi_ptr )->portctl_device_on_port)[ i ];

		if ( NULL != downstream_device_ptr )
			devep_dispose_device( &downstream_device_ptr );
	}
	
	return ( 0 );
}


void hub_callback( endpoint_info_ptr epi_ptr )
{
	hub_event_flag	this_event;

	if ( atlmix_is_fatal_error( (transfer_instance *)(epi_ptr->transfer_instance) ) )
	{
		//	Device may be detached
		
		atlmix_free_transfer( (transfer_instance *)(epi_ptr->transfer_instance) );
		return;
	}
		
	this_event.port_status_change_bit_map	= *(((transfer_instance *)(epi_ptr->transfer_instance))->data_ptr_base);

	atlmix_re_enable_interrupt_transfer( epi_ptr->transfer_instance );

	this_event.hub_address					= epi_ptr->dev_addr;
	this_event.topology_layer				= (devep_find_device( this_event.hub_address ))->topology_layer;

	//	If this event is happened at hub in leaf side in tree, no process will be done at this time.
	//	The event will be handled by next timing of callback (interrupt transfer ACKed time)

	if ( gp_hub_event.hub_address )
		if ( gp_hub_event.topology_layer < this_event.topology_layer )
			return;

	//	If this event is happened at hub in root side in tree, over-ride the event. 
	//	Root side event has higher priority
	
	gp_hub_event		= this_event;
}









unsigned long hub_read_hub_device_port_status( device_instance *dvi_ptr, unsigned char port )
{
	unsigned long	data;
	unsigned short	size;
	
	size	= 4;
	devep_std_request( (unsigned char *)(&data), dvi_ptr, hub_cls_sp_request_GetPortStatus, 0, port, &size );

	return ( data );
}


void hub_reset_hub_device_port( device_instance *dvi_ptr, unsigned char port )
{
	unsigned long	dummy;
	unsigned short	size;
	
	size	= 0;
	devep_std_request( (unsigned char *)(&dummy), dvi_ptr, hub_cls_sp_request_SetPortFeature, PORT_RESET, port, &size );
}


void hub_clear_hub_device_port( device_instance *dvi_ptr, unsigned char port )
{
	unsigned long	dummy;
	unsigned short	size;
	
	size	= 0;
	devep_std_request( (unsigned char *)(&dummy), dvi_ptr, hub_cls_sp_request_ClearPortFeature, C_PORT_CONNECTION, port, &size );
}


void hub_clear_status_change_bits_in_hub( device_instance *dvi_ptr, unsigned char port, unsigned short pos )
{
	unsigned long	dummy;
	unsigned short	size;
	
	size	= 0;
	devep_std_request( (unsigned char *)(&dummy), dvi_ptr, hub_cls_sp_request_ClearPortFeature, pos, port, &size );
}





#if 0
	/*	GET_STATUS from all ports	*/
	//	4 bytes data getting
	
	for ( i = 0; i < number_of_ports; i++ )
	{
		size	= 4;
		devep_std_request( port_status[ i ], dvi_ptr, hub_cls_sp_request_GetPortStatus, 0, (i + 1), &size );
	}

	for ( i = 0; i < number_of_ports; i++ )
	{
		if ( port_status[ i ][ 0 ] & 0x01 )
			mprintf( WHITE, CONTINUE, "port %d has device on this hub (address %d)\r\n", i + 1, dvi_ptr->address );
	}
#endif








⌨️ 快捷键说明

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