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

📄 port_ctl.c

📁 使用ISP1362芯片的USB_OTG参考设计源代码比较新的版本
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
**  WASABI-Hot! version 1.2c   
**
**
**      -- 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 
*/


//	2002 02 27		Port connection disconnection process improved
//	2002 04 08		Device speed reading timing corrected  


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

#include		<dos.h>
#include		<stdio.h>
#include		<conio.h>

#include		"_hc_core/atl_mix.h"
#include		"_hc_core/dev_ep.h"
#include		"_hc_core/isr.h"
#include		"_hc_core/port_ctl.h"
#include		"_hc_hw/hc_comm.h"
#include		"_hc_hw/hw_acces.h"
#include		"_hc_cls/cls_hndl.h"

#include 		"_otg/otg.h"

#include		"class_dr/hub/hub.h"

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

/****************************************************************************/
/*	constants																*/
/****************************************************************************/

#define			ENUM_RETRY				3
#define			ENUM_RETRY_INTERVAL		1000L

#define			RESET_SECOVERY_TIME		100L		//	In the standard, it is 10mS. But some devices need more time to start enum.
													//	See section 7.1.7.3 in USB2.0 spec.

#define			LONGER_RESET						//	This is required for USB2.0 specification
													//	BusReset from root hub must have 50ms duration.

#define			ENUMERATION_DONE_BLINKING_INTERVAL					350L

#define			ROOT_HUB_ADDRESS									1


/****************************************************************************/
/*	global vars																*/
/****************************************************************************/

device_instance		*device_at_root_hub[ NUMBER_OF_ROOT_HUB_PORT ]		=	{
																				NULL,
																				NULL
																		};
																		
hub_instance		gp_root_hub_instance								=	{
																				NULL,														//	Pointer to device instance
																				{	0x09, 0x29, 0x02, 0x09, 0x00, 0x32, 0x00, 0x00, 0x00 },	//	Dummy hub descriptor
																				2,															//	Number of downstream ports
																				{	NULL, NULL, NULL, NULL, NULL, NULL, NULL },				//	Pointer to device attached on downstream ports			
																				0xFF,														//	Transfer index for interrupt transfer
																				NULL,														//	Pointer to transfer instance
																				0															//	Hub and Port Statua Change Bitmap
																		};
																		
hub_event_flag		gp_hub_event										=	{
																				0,
																				0x00
																		};

unsigned short HcRhPortStatusComm[2]									=	{ 
																				Com32_HcRhPortStatus1,
																				Com32_HcRhPortStatus2
																			};

unsigned char		gp_fast_enumeration								= Disabled;
unsigned char		gp_silent_enumeration							= Disabled;
unsigned char		gp_warning_message								= Disabled;


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

void				isr_flag_handler( void );
void				root_hub_event( hub_instance *hi_ptr );
void				hub_event_handler( hub_event_flag *h_ev_ptr );
unsigned long		read_hub_port_status( unsigned char address, unsigned char port );
void				clear_status_change_bits( unsigned char address, unsigned char port, unsigned long status_bits );
device_instance		*connect_a_device( unsigned char address, unsigned char port, unsigned char topology_layer );
void				disconnect_a_device( device_instance **dvi_ptr_ptr );
unsigned char		port_reset( unsigned char address, unsigned char port, unsigned short reset_recovery_time );
device_instance		*start_a_device( unsigned char speed, unsigned char topology_layer );
void				message_of_enum_done( device_instance *dvi_ptr );


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

void portctl_isr_flag_routine_dspatch( void )
{
	isr_flag_handler();
	
	hub_event_handler( &gp_hub_event );
}


void isr_flag_handler( void )
{
	unsigned short	flag_mask;	/*  this mask shold be set to */

	flag_mask	= SOFISTLInt | ATL_IRQ | AllEOTInterrupt;

	if ( !(gp_isr_flag & ~flag_mask) )
		return;

	root_hub_event( &gp_root_hub_instance );
}


void root_hub_event( hub_instance *dummy_for_func_compatibility )
{
	static unsigned char	rh_Vbus_status[ 2 ]		= { 0, 0 };		//	##	version1.2c
	unsigned long			rh_status;								//	##	version1.2c
	unsigned char			i;										//	##	version1.2c

	dummy_for_func_compatibility	= dummy_for_func_compatibility;	//	This line for erase warning

	if ( gp_isr_flag & RHSC )
		gp_isr_flag	&= ~RHSC;
	else
		return;

	gp_hub_event.port_status_change_bit_map	= 0x0;

	for ( i = 0; i < 2; i++ )
	{
		rh_status	= read_register32( HcRhPortStatusComm[ i ] );

#ifdef	PORT1_AS_HOST_ONLY
#else
		if ( i == 0 )
		{
			if ( !OTG_host_operation_enabled() )
				continue;
			else if ( (rh_status & 0x1) && (gp_root_hub_instance.portctl_device_on_port)[ 0 ] )
				continue;
		}
#endif

		//	##	version1.2c	(from here)

		if ( (rh_status & 0x001F0000) || (rh_Vbus_status[ i ] && (~rh_status & 0x100)) )	//	##	version1.2c
		{
			//	If this event is happened root-hub, over-ride the any hub events. 
			//	Root-hub event has highest priority
			
			if ( rh_status & 0x00080000 )
				ui_over_current_detected_message( i );

			gp_hub_event.hub_address				 = 1;
			gp_hub_event.port_status_change_bit_map	|= (0x1 << (i + 1));
			gp_hub_event.topology_layer				 = 0;
		}
		
		rh_Vbus_status[ i ]		= (rh_status & 0x100) ? True : False;	//	##	version1.2c

		//	##	version1.2c	(to here)

	}
}


void hub_event_handler( hub_event_flag *h_ev_ptr )
{
	device_instance				*dvi_ptr;
	hub_instance				*hi_ptr;
	unsigned long				h_status;
	unsigned char				port_num;
	int							i;

	if ( h_ev_ptr->hub_address == 0 )
		return;
		
	if ( NULL == (dvi_ptr	= devep_find_device( h_ev_ptr->hub_address )) )
		return;
	
	
	//	Set target HUB
	
	if ( h_ev_ptr->hub_address == ROOT_HUB_ADDRESS )
	{
		hi_ptr	= &gp_root_hub_instance;				//	If the target is a root HUB
	}
	else
	{
		hi_ptr	= hub_instance_ptr( dvi_ptr );		//	If the target is a device HUB
	}
	
	
	//	Port processing for target HUB

	for ( i = 0; i < hi_ptr->number_of_ports; i++ )
	{
		port_num	= i + 1;
		
		if ( !(h_ev_ptr->port_status_change_bit_map & (0x1 << port_num)) )
			continue;
			
		h_status		= read_hub_port_status( h_ev_ptr->hub_address, port_num );

		if ( h_status & 0x001F0000 )
		{
			//	This function clears register bits for hub.
			//	It clears interrupt transfer data body from device-hub
			clear_status_change_bits( h_ev_ptr->hub_address, port_num, h_status & 0x001F0000 );
		}


		//	##	version1.2c	(from here)

		if ( (h_status & 0x00010000) && ( h_status & 0x00000001) )		//	Device connected!
		{
			if ( NULL == hi_ptr->portctl_device_on_port[ i ] )

				hi_ptr->portctl_device_on_port[ i ]		= connect_a_device( h_ev_ptr->hub_address, i + 1, h_ev_ptr->topology_layer + 1 );


		}
		else if ( ((h_status & 0x00010000) && (~h_status & 0x00000001)) || ((hi_ptr->portctl_device_on_port[ i ] != NULL) && (~h_status & 0x00000001)) )
					//	Device disconnected!                            or     Vbus turned-off while the device instance exist
		{
			disconnect_a_device( &(hi_ptr->portctl_device_on_port[ i ]) );
		}
		//	##	version1.2c	(from here)
	}

	h_ev_ptr->hub_address	= 0;

#if 0

	if ( h_status & 0x00010000 )
		ui_show_topology();
#endif
}


unsigned long read_hub_port_status( unsigned char address, unsigned char port )
{
	if ( address == ROOT_HUB_ADDRESS )
		return ( read_register32( HcRhPortStatusComm[ port - 1 ] ) );
	else
		return ( hub_read_hub_device_port_status( devep_find_device( address ), port ) );
}


void clear_status_change_bits( unsigned char address, unsigned char port, unsigned long status_bits )
{
	int		i;
	
	if ( address == ROOT_HUB_ADDRESS )
		write_register32( HcRhPortStatusComm[ port - 1 ], status_bits );
	else
	{
		for ( i = 16; i <=20; i++ )
		{
			if ( status_bits & (0x1L << i) )
				hub_clear_status_change_bits_in_hub(  devep_find_device( address ), port, i );
		}
	}
}


device_instance *connect_a_device( unsigned char address, unsigned char port, unsigned char topology_layer )
{
	device_instance		*dvi_ptr;
	unsigned char		speed;
	unsigned char		retry;
	unsigned char		i;
	unsigned char		fast_enumeration_flag_to_remember;
	
	dvi_ptr		= NULL;

#if 0
	if ( address == ROOT_HUB_ADDRESS )
		mprintf( LIGHTGRAY, CONTINUE, "\r\ndetected a connection @root_hub" );
	else
		mprintf( LIGHTGRAY, CONTINUE, "\r\ndetected a connection @hub(addr=%d)", address );
#endif

⌨️ 快捷键说明

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