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

📄 port_ctl.c

📁 使用ISP1362芯片的USB_OTG参考设计源代码比较新的版本
💻 C
📖 第 1 页 / 共 2 页
字号:

#if 0
	if ( gp_fast_enumeration )
		retry	= 1;
	else
		retry	= ENUM_RETRY;
#else
		retry	= ENUM_RETRY;
#endif

	fast_enumeration_flag_to_remember	= gp_fast_enumeration;

	if ( (address == ROOT_HUB_ADDRESS) && (port == 1) && OTG_host_operation_enabled() )
		gp_fast_enumeration		= 1;

	for ( i = 0; i < retry; i++ )
	{
		speed	= port_reset( address, port, RESET_SECOVERY_TIME );		//	reset a port on ( address, port );

		dvi_ptr		= start_a_device( speed, topology_layer );			//	start a device!

		if ( dvi_ptr != NULL )
			break;
		
//		read_register32( HcRhPortStatusComm[ port - 1 ] & 0x00000001 );	//	Disable port

		if ( gp_warning_message )
			mprintf( YELLOW, CONTINUE, "*** Enumeration RETRY wait #%d\r", i );

		wait_ms( ENUM_RETRY_INTERVAL );
	}
	
	gp_fast_enumeration	= fast_enumeration_flag_to_remember;

	if ( i == retry )
		mprintf( YELLOW, CONTINUE, "\r\n" );

	return ( dvi_ptr );	
}


void disconnect_a_device( device_instance **dvi_ptr_ptr )
{
	unsigned char	address;

	mprintf( LIGHTGRAY, CONTINUE, "\r\ndetected a device disconnection\r\n" );

	if ( *dvi_ptr_ptr == NULL )
	{
		mprintf( LIGHTGRAY, CONTINUE, "un-enumerated device removed.\r\n" );
		return;
	}
	
	address		= (*dvi_ptr_ptr)->address;
	devep_dispose_device( dvi_ptr_ptr );
	
	*dvi_ptr_ptr	= NULL;

	mprintf( WHITE, CONTINUE, "device (address=%d) disposed\r\n", address );
	
	if ( !gp_silent_enumeration )
		beep( 660, 0.20, DECAY, POLY );
}

#define		OTG__SESSION_BASED

unsigned char port_reset( unsigned char address, unsigned char port, unsigned short reset_recovery_time )
{
	unsigned long		h_status;

#ifdef	OTG__SESSION_BASED

	if ( (address == ROOT_HUB_ADDRESS) && (port == 1) && OTG_host_operation_enabled() )
		;																			//	If the local is OTG host, no need to wait.
	else
		wait_ms( 100L );															//	Need to wait before reset to handle bounce

#else

	wait_ms( 100L );																//	Need to wait before reset to handle bounce

#endif


	if ( address == ROOT_HUB_ADDRESS )
	{
		write_register32( HcRhPortStatusComm[ port - 1 ], 0x00000010 );				//	Set port reset

#ifdef LONGER_RESET
		{
			unsigned char	i;
			
			for ( i = 0; i < 41; i++ )
			{
				write_register32( HcRhPortStatusComm[ port - 1 ], 0x00000010 );				//	Set port reset
				wait_ms( 1L );
			}

		}
#else
#endif

		while ( read_register32( HcRhPortStatusComm[ port - 1 ] ) & 0x00000010 )	//	Polling port reset status (waiting for finishing port reset)
			wait_ms( 5L );

		h_status	= read_register32( HcRhPortStatusComm[ port - 1 ] );

		wait_ms( reset_recovery_time );												//	Wait reset recovery time
	}
	else
	{
		hub_reset_hub_device_port( devep_find_device( address ), port );
	
		h_status	= hub_read_hub_device_port_status( devep_find_device( address ), port );

		wait_ms( reset_recovery_time );												//	Wait reset recovery time

		if ( 0x3 == h_status )
			mprintf( LIGHTGRAY, CONTINUE, "\r\nport enabled @hub(addr=%d) port%d\r\n", address, port );
	}

	return ( (h_status >> 9) & 0x1 );
}


device_instance *start_a_device( unsigned char speed, unsigned char topology_layer )
{
	device_instance		*dvi_ptr;
	unsigned char		dv_class_code;
	unsigned char		if_class_code;
	
	if ( NULL == (dvi_ptr	= devep_create_device( speed, topology_layer )) )		//	Do enumeration
	{
		if ( gp_warning_message )
			mprintf( YELLOW, CONTINUE, "\r\nWarning : device may have problem for enumeration process\r\n" );
			
		return ( NULL );
	}
	
	message_of_enum_done( dvi_ptr );

	return ( dvi_ptr );
}


void message_of_enum_done( device_instance *dvi_ptr )
{
	int		i,
			j;

	if ( !gp_silent_enumeration )
	{
		if ( devep_check_interface_class_ID( dvi_ptr, AUDIO_CLASS_INTERFACE ) )
			beep( 886.00, 1.20, DECAY, POLY );
		else
			beep( 443.00, 0.50, DECAY, POLY );
	}

	if ( gp_fast_enumeration )
	{
		mprintf( WHITE, CONTINUE, "device enumerated (address=%d assigned.)", dvi_ptr->address );
		mprintf( DARKGRAY, CONTINUE, "     vid=0x%04X pid=0x%04X\r", (dvi_ptr->dev_descriptor).idVendor, (dvi_ptr->dev_descriptor).idProduct );
//		mprintf( WHITE, CONTINUE, "device enumerated (address=%d assigned.)\r", dvi_ptr->address );
	}
	else
	{
		for ( j = 0; j < 5; j++ )
		{
//			mprintf( (j & 0x1) ? BLACK : WHITE, CONTINUE, "device enumerated (address=%d assigned. VID=0x%04X PID=0x%04X )\r", dvi_ptr->address, (dvi_ptr->dev_descriptor).idVendor, (dvi_ptr->dev_descriptor).idProduct );
			mprintf( (j & 0x1) ? BLACK : WHITE, CONTINUE, "device enumerated (address=%d assigned.)\r", dvi_ptr->address );
			wait_ms( ENUMERATION_DONE_BLINKING_INTERVAL );
		}
	}

	mprintf( WHITE, CONTINUE, "\r\n" );

	ui_show_device_string_descriptors( dvi_ptr );

//	ui_device_infomation_viewer( dvi_ptr );
}


device_instance *portctl_device_on_port( unsigned char port_num )
{
	return ( device_at_root_hub[ port_num - 1 ] );
}


void portctl_force_rh_port_reconnect( void )
{
	write_register32( Com32_HcRhPortStatus1, 0x1 );
	write_register32( Com32_HcRhPortStatus2, 0x1 );

	if ( (gp_root_hub_instance.portctl_device_on_port)[ 0 ] != NULL )
		disconnect_a_device( &((gp_root_hub_instance.portctl_device_on_port)[ 0 ]) );

	if ( (gp_root_hub_instance.portctl_device_on_port)[ 1 ] != NULL )
		disconnect_a_device( &((gp_root_hub_instance.portctl_device_on_port)[ 1 ]) );

	if ( (read_register32( Com32_HcRhPortStatus1 ) & 0x1) )
		(gp_root_hub_instance.portctl_device_on_port)[ 0 ]		= connect_a_device( 1, 1, 1 );
		
	if ( (read_register32( Com32_HcRhPortStatus2 ) & 0x1) )
		(gp_root_hub_instance.portctl_device_on_port)[ 1 ]		= connect_a_device( 1, 2, 1 );
}


unsigned char portctl_check_OTG_port( unsigned char bus_request, unsigned char full_enum )
{
	device_instance		*dvi_ptr		= NULL;
	unsigned long		port_status;

	write_register32( Com32_HcRhPortStatus1, 0x001F0000 );	//	Clearing ststus change bit

	if ( (gp_root_hub_instance.portctl_device_on_port)[ 0 ] != NULL )
		return ( False );
	
	port_status		= read_register32( Com32_HcRhPortStatus1 );

	if ( (port_status & 0x00000001) )						//	Device connected!
	{
	
#if 0
		if ( (!bus_request) && (!full_enum) )
					= otg_host_process_for_HNP();			//	Try to access as remote=DRD
			(gp_root_hub_instance.portctl_device_on_port)[ 0 ]		= connect_a_device( 1, 0 + 1, 0 + 1 );
		else
#endif


		if ( (!bus_request) && (!full_enum) )
			dvi_ptr		= otg_host_process_for_HNP();			//	Try to access as remote=DRD
		
		if ( dvi_ptr == NULL )
			dvi_ptr		= connect_a_device( 1, 0 + 1, 0 + 1 );
	}
	
	(gp_root_hub_instance.portctl_device_on_port)[ 0 ]	= dvi_ptr;

	return ( dvi_ptr ? True : False );
}


void portctl_disconnect_a_device_on_OTG_port( void )
{
	if ( (gp_root_hub_instance.portctl_device_on_port)[ 0 ] != NULL )
		disconnect_a_device( &((gp_root_hub_instance.portctl_device_on_port)[ 0 ]) );
	
	write_register32( Com32_HcRhPortStatus1, 0x00000001 );	//	Disabling OTG port (port1)
	write_register32( Com32_HcRhPortStatus1, 0x001F0000 );	//	Clearing ststus change bit
}


device_instance *portctl_get_OTG_port_device_instance( void )
{
	return ( (gp_root_hub_instance.portctl_device_on_port)[ 0 ] );
}


void portctl_OTG_port_enable_disable( unsigned char enable )
{
	unsigned long	v;
	unsigned char	state;
	

	state	= (read_register32( Com32_HcRhPortStatus1 ) & 0x00000002) ? True       : False;
	v		= enable                                                  ? 0x00000182 : 0x00000181;

	if ( state ^ enable )
		write_register32( Com32_HcRhPortStatus1, v );
}


unsigned char portctl_reset_OTG_port( void )
{
	return ( port_reset( ROOT_HUB_ADDRESS, 1, 10 ) ) ;
}


void portctl_Vbus_control_for_port_1_or_2( unsigned char power, unsigned char port_num )
{
	if ( power )
		write_register32( HcRhPortStatusComm[ port_num - 1 ], 0x00000100 );
	else
		write_register32( HcRhPortStatusComm[ port_num - 1 ], 0x00000200 );
}
























⌨️ 快捷键说明

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