www.pudn.com > USBdiskRW.rar > hub_811.c


//////////////////////////////////////////////////////////////////////////////// 
// Cypress Semiconductor - Customer Design Center  
//////////////////////////////////////////////////////////////////////////////// 
// File:		hub_811.c 
// Purpose:	    8051 firmware to master SL811 downstream hub (CY7C651xx).  
//              Contains hub-related control firmware.  
//              Based on SL811HST code written by cxn. 
// H/W Target:  SL811HST(Rev 1.5) + EZUSB DEV KIT 
// IMPORTANT :  Turn ON SW4 of S6-DIP-SWITCH  
//              to enable upper 32K memory on EZUSB Dev Kit 
// 
// $Header: /USB/ez811/firmware/Emb_Host/hub_811.c 7     5/17/02 6:09p Tpm $ 
// Copyright (c) 2002 Cypress Semiconductor. May not be reproduced without permission. 
// See the license agreement for more details. 
//////////////////////////////////////////////////////////////////////////////// 
 
#include "ezusb.h" 
#include "ezregs.h" 
#include "host_811.h" 
 
extern xdata BYTE 			STATUS[8];		// for status data buffer 
extern xdata BYTE 			HubChange[1];	// Hub port endpoint 1 data status 
extern xdata BYTE 			pNumPort;		// Number of downstream ports on hub 
extern xdata pHUBDEV		uHub;			// Struct for downstream device on HUB 
extern xdata pPortStatus	pStat;			// HID ports status 
 
//***************************************************************************************** 
// Hub's downstream ports enumeration routine 
//***************************************************************************************** 
int HubPortEnum(void) 
{ 
	xdata BYTE 	DevAddr, PortNum=0, PortSel; 
	xdata BYTE	j=0; 
//	xdata BYTE	TempDevAddr; 
 
	PortSel = 0x02;											// start with port 1 first 
	while(j++ < pNumPort)									// loop for all 4 port, bit 1 to bit 4 
	{ 
		if(!(HubChange[0]&PortSel))							// test if bit representing port is set 
		{ 
			PortSel <<= 1;									// shift mask to test for next bit port 
		} 
		else 
		{ 
			switch(HubChange[0]&PortSel)					// valid downstream port number #1..#4 only 
			{ 
				case 0x02:	PortNum = 0x01;	break;			// Limit to onboard hub with 4 downstream ports 
				case 0x04:	PortNum = 0x02; break;			// 
				case 0x08:	PortNum = 0x03; break;			// 
				case 0x10:	PortNum = 0x04; break;			// 
				default:	PortNum = HubChange[0]; break;	// for debug purpose 
			} 
			break;											// found one port, exit while loop now 
		} 
	} 
 
	// Always use USB address #1 for HUB communication 
	pStat =(pPortStatus)STATUS;								// keep current wPortStatus & wPortChange 
	if (!GetPortStatus(HUB_ADDR,PortNum,STATUS)) return 0;	// If the device is already attached to hub 
 
	//------------------------------------------------------------------------------ 
	// Device is present on current downstream port 
	//------------------------------------------------------------------------------ 
	if((pStat->wPortStatus_Lo)&0x01)						 
	{	 
		//------------------------------------------------ 
		// Search for unused USB address (#2..#5 valid) 
		//------------------------------------------------ 
		for(DevAddr=HUB_ADDR + 1; DevAddrwPortChange_Lo)&USB_PORT_STAT_C_CONNECTION)); 
 
		 
		if (!PortFeature(HUB_ADDR,SET_FEATURE,PORT_RESET,PortNum)) return 0;	// reset this port for at least 10ms 
		EZUSB_Delay(10); 
		do{ // Set PORT_RESET  
			if (!GetPortStatus(HUB_ADDR,PortNum,STATUS)) return 0; 
        } 
		while( !((pStat->wPortChange_Lo)&USB_PORT_STAT_C_RESET) ); 
 
				 
		if (!PortFeature(HUB_ADDR,CLEAR_FEATURE,C_PORT_RESET,PortNum)) return 0; 
		do{ // Clear C_PORT_RESET state 
			if (!GetPortStatus(HUB_ADDR,PortNum,STATUS)) return 0; 
        } 
		while(((pStat->wPortChange_Lo)&USB_PORT_STAT_C_RESET)); 
	 
		//------------------------------------------------ 
		// Determine attached downstream speed 
		//------------------------------------------------ 
		if ((pStat->wPortStatus_Hi)&0x02)								// check bit 9 of wPortStatus for port speed 
			uHub.bPortSpeed[0] = uHub.bPortSpeed[DevAddr] = 1;			// '1' - lowspeed, USB address 0 must also be set 
		else								 
			uHub.bPortSpeed[0] = uHub.bPortSpeed[DevAddr] = 0;			// '0' - fullspeed, USB address 0 must also be set 
				 
		//------------------------------------------------ 
		// Enumerate current attached device on hub 
		//------------------------------------------------ 
		EZUSB_Delay(50);							// some device require a long delay before it can enumerate properly 
		if (!EnumUsbDev(DevAddr))					// enumerate device attached to current hub downstream port 
			return 0; 
 
		uHub.bPortPresent[DevAddr] = 1;				// set USB device present on this address	 
		uHub.bPortNumber[DevAddr] = PortNum;		// Save port number used in this address 
		/*switch(PortNum)		     		            // Downstream port # 
		{											// 
			case 1:	OUTA &= ~PORT1_LED; break;		// Downstream Port #1 
			case 2:	OUTA &= ~PORT2_LED; break;		// Downstream Port #2 
			case 3:	OUTA &= ~PORT3_LED; break;		// Downstream Port #3 
			case 4:	OUTA &= ~PORT4_LED; break;		// Downstream Port #4 
			default: break; 
		}*/				 
	} 
 
	//------------------------------------------------------------------------------ 
	// Device is not present on current downstream port 
	//------------------------------------------------------------------------------ 
	else 
	{ 
		do{	// Clear C_PORT_CONNECTION state 
		    if (!PortFeature(HUB_ADDR,CLEAR_FEATURE,C_PORT_CONNECTION,PortNum)) return 0; 
			if (!GetPortStatus(HUB_ADDR,PortNum,STATUS)) return 0; 
        }						// 
		while(((pStat->wPortChange_Lo)&USB_PORT_STAT_C_CONNECTION)); 
 
		do{	// Clear C_PORT_ENABLE state - PORT_ENABLE was set for some hub only 
		    if (!PortFeature(HUB_ADDR,CLEAR_FEATURE,C_PORT_ENABLE,PortNum)) return 0; 
			if (!GetPortStatus(HUB_ADDR,PortNum,STATUS)) return 0; 
        }						// 
		while(((pStat->wPortChange_Lo)&USB_PORT_STAT_C_ENABLE)); 
 
		//------------------------------------------------ 
		// Search Port Number that was detached 
		//------------------------------------------------ 
		for(DevAddr=HUB_ADDR + 1; DevAddr