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

📄 usb.c

📁 用ST92163开发的鼠标
💻 C
📖 第 1 页 / 共 2 页
字号:
			break ;
		case 1:
			MOUSE_reset() ;
			break ;
		case 2:
			JOYSTICK_reset() ;
			break ;
		}

		spp( 4) ;	/* restore context after a device reset */
		break ;
	case PORT_SUSPEND:
		P_Status[ idx][ 0] |= 0x04 ;	/* Suspend */
		break ;
	default:
		return TX_STALL ;
	}

	return TX_0 ;
}

static BYTE HUB_ClearPortFeature( void)
{
	BYTE	idx ;
	
	idx = CurRxBuffer[ USB_wIndex] - 1 ;

	if( idx > 2)	/* Port 3 is idx 2 */
	{
		return TX_STALL ;
	}

	switch( CurRxBuffer[ USB_wValue])
	{
	case PORT_CONNECTION:		P_Status[ idx][ 0] &= ~0x01 ; break ;
	case PORT_ENABLE:
		P_Status[ idx][ 0] &= ~0x02 ;
		P_Status[ idx][ 0] &= ~0x04 ;
		break ;
	case PORT_SUSPEND:
		P_Status[ idx][ 0] &= ~0x04 ;
		P_Status[ idx][ 2] |= 0x04 ;
		break ;
	case PORT_OVER_CURRENT:		P_Status[ idx][ 0] &= ~0x08 ; break ;
	case PORT_RESET:			P_Status[ idx][ 0] &= ~0x10 ; break ;
	case PORT_POWER:			P_Status[ idx][ 1] &= ~0x01 ; break ;
	case PORT_LOW_SPEED:		P_Status[ idx][ 1] &= ~0x02 ; break ;
	case C_PORT_CONNECTION:		P_Status[ idx][ 2] &= ~0x01 ; break ;
	case C_PORT_ENABLE:			P_Status[ idx][ 2] &= ~0x02 ; break ;
	case C_PORT_SUSPEND:		P_Status[ idx][ 2] &= ~0x04 ; break ;
	case C_PORT_OVER_CURRENT:	P_Status[ idx][ 2] &= ~0x08 ; break ;
	case C_PORT_RESET:			P_Status[ idx][ 2] &= ~0x10 ; break ;
	default:
		return TX_STALL ;
	}

	return TX_0 ;
}

static BYTE ClearEndPointStall( void)
{
	if( CurRxBuffer[ USB_wValue] != 0)
	{
		return TX_STALL ;
	}
	else
	{
		endpoint_stall[ CurDevice] = 0 ;
		/* Clear the endpoint state */
//		if( CurDevice)
//			MASS_clear_stall( CurDevice - 1) ;
			
		return TX_0 ;
	}
}

static BYTE SetEndPointStall( void)
{
	if( CurRxBuffer[ USB_wValue] != 0)
	{
		return TX_STALL ;
	}
	else
	{
		endpoint_stall[ CurDevice] = 1 ;
//		USBEP1RA &=~0x30 ;
//		USBEP1RA |= 0x10 ;	/* EP1 IN STALL */
		
		return TX_0 ;
	}
}

static BYTE HUB_Status[ 4] /* = {
	0x00, 0x00, 0x00, 0x00
} */ ;

BYTE do_setup()
{
	switch( CurRxBuffer[ USB_bmRequestType])
	{
		case HOST_TO_DEVICE | STANDARD_REQUEST | DEVICE_RECIPIENT: /* 0x00 */
			switch( CurRxBuffer[ USB_bRequest])
			{
#if 0
				case CLEAR_FEATURE:
					ClearRemoteWakeup() ;
					break ;
				case SET_FEATURE:
					SetRemoteWakeup() ;
					break ;
#endif
				case SET_ADDRESS:
					return set_address() ;
					break ;
				case SET_CONFIGURATION:
					return set_configuration() ;
					break ; 
#if 0
 				case SET_DESCRIPTOR:
					send_stall() ;			/* undefined in wicked.asm */
					break ;
#endif
				default:
					return TX_STALL ;
			}

			break ;
#if 0
		case HOST_TO_DEVICE | STANDARD_REQUEST | INTERFACE_RECIPIENT: /* 0x01 */
		/* undefined in wicked.asm */
			switch( CurRxBuffer[ USB_bRequest])
			{
				case CLEAR_FEATURE:
				case SET_FEATURE:
				case SET_INTERFACE:
				default:
					send_stall() ;
			}

			break ;
#endif
		case HOST_TO_DEVICE | STANDARD_REQUEST | ENDPOINT_RECIPIENT: /* 0x02 */
		/* The only standard feature defined for an endpoint is endpoint_stalled */
			switch( CurRxBuffer[ USB_bRequest])
			{
				case CLEAR_FEATURE:
					return ClearEndPointStall() ;
					break ;
				case SET_FEATURE:
					return SetEndPointStall() ;
					break ;
				default:
					return TX_STALL ;
			}

			break ;
		case DEVICE_TO_HOST | STANDARD_REQUEST | DEVICE_RECIPIENT: /* 0x80 */
			switch( CurRxBuffer[ USB_bRequest])
			{
				case GET_STATUS:
					return GetDeviceStatus() ;
					break ;
				case GET_DESCRIPTOR:
					return get_descriptor() ;
					break ;
				case GET_CONFIGURATION:
					return GetConfiguration() ;
					break ;
				default:
					return TX_STALL ;
			}

			break ;
		case DEVICE_TO_HOST | STANDARD_REQUEST| INTERFACE_RECIPIENT: /* 0x81 */
			switch( CurRxBuffer[ USB_bRequest])
			{
#if 0
				case GET_INTERFACE:
					send_stall() ;			/* undefined in .asm */
					break ;
				case GET_STATUS:
					GetInterfaceStatus() ;
					break ;
#endif
				case GET_DESCRIPTOR:		/* Not in USB but in HID Class */
					return get_descriptor() ;
					break ;
/////				case 0x0A: /* GET_CONFIGURATION */
/////					GetInterfaceStatus() ;
/////					break ;
				default:
					return TX_STALL ;
			}

			break ;

		case DEVICE_TO_HOST | STANDARD_REQUEST | ENDPOINT_RECIPIENT: /* 0x82 */
			switch( CurRxBuffer[ USB_bRequest])
			{
				case GET_STATUS:
					return GetEndpointStatus() ;
					break ;
#if 0
				case SYNCH_FRAME:
					send_stall() ;			/* undefined in .asm */
					break ;
///				case GET_DESCRIPTOR:		/* Memphis? */
///					get_descriptor() ;
///					break ;
#endif
				default:
					return TX_STALL ;
			}

			break ;
		case HOST_TO_DEVICE | CLASS_REQUEST | INTERFACE_RECIPIENT: /* 0x21 */
			switch( CurRxBuffer[ USB_bRequest])
			{
//				case 0xFF:	/* Mass Storage: Bulk-Only Mass Storage Reset */
//					/* wValue == 0
//					** wIndex == interface #
//					** wLength == 0
//					*/
//					MASS_bot_reset( CurDevice - 1) ;
//					return TX_0 ;
//					break ;
#if 0
				case 9:	/* SET_REPORT */
					set_report() ;
					break ;
//				case 10:	/* set_idle */
//					SetIdle() ;
//					break ;
				case 11:	/* set_protocol */
					SetProtocol() ;
					break ;
#endif
				default:
					return TX_STALL ;
			}

			break ;
#if 0
		case HOST_TO_DEVICE | CLASS_REQUEST | ENDPOINT_RECIPIENT: /* 0x22 */
			switch( CurRxBuffer[ USB_bRequest])
			{
//				case 9:
//					set_report() ;
//					break ;
//				case 10:	/* set_idle */
//					SetIdle() ;
//					break ;
//				case 11:	/* set_protocol */
//					SetProtocol() ;
//					break ;
				default:
					send_stall() ;
			}

			break ;
#endif
		case HOST_TO_DEVICE | CLASS_REQUEST | OTHER_RECIPIENT: /* 0x23 */
			if( CurDevice != 0)
			{
				return TX_STALL ;
			}
			else
			switch( CurRxBuffer[ USB_bRequest])
			{
				case SET_FEATURE:
					return HUB_SetPortFeature() ;
					break ;
				case CLEAR_FEATURE:
					return HUB_ClearPortFeature() ;
					break ;
				default:
					return TX_STALL ;
			}
			
			break ;
		case DEVICE_TO_HOST | CLASS_REQUEST | DEVICE_RECIPIENT: /* 0xA0 */
			if( CurDevice != 0)
			{
				return TX_STALL ;
			}
			else
			switch( CurRxBuffer[ USB_bRequest])
			{
				case GET_DESCRIPTOR:
					if( CurRxBuffer[ USB_wIndex] != 0)
					{
						return TX_STALL ;
					}
					else
					{
						data_ptr = (BYTE *) HUB_ReportDescriptor ;
						data_size[ CurDevice] = sizeof HUB_ReportDescriptor ;
						return control_read() ;
					}
					
					break ;
				case GET_STATUS:
					data_ptr = (BYTE *) HUB_Status ;
					data_size[ CurDevice] = 4 ;
					return control_read() ;
				default:
					return TX_STALL ;
			}
			
			break ;			
		case DEVICE_TO_HOST | CLASS_REQUEST | INTERFACE_RECIPIENT: /* 0xA1 */
			switch( CurRxBuffer[ USB_bRequest])
			{
//				case 0xFE:	/* Mass Storage: GET_MAX_LUN */
//					if( CurDevice)
//					{
//					/* We only support LUN 0 */
//						data_size[ CurDevice] = 1 ;
//						data_ptr = "\x00" ;
//						return control_read() ;
//					}
//					
//					break ;
//				case 1:		/* GET_REPORT */
//					GetReport() ;
//					break ;
//				case 2:		/* GET_IDLE */
//					GetIdle() ;
//					break ;
//				case 3:		/* GET_PROTOCOL */
//					GetProtocol() ;
//					break ;
				default:
					return TX_STALL ;
			}

			break ;
		case DEVICE_TO_HOST | CLASS_REQUEST | OTHER_RECIPIENT: /* 0xA3 */
			if( CurDevice != 0)
			{
				return TX_STALL ;
			}
			else
			switch( CurRxBuffer[ USB_bRequest])
			{
				case GET_STATUS:
					data_size[ CurDevice] = 4 ;
					data_ptr = &P_Status[ CurRxBuffer[ USB_wIndex] - 1][ 0] ;
					return control_read() ;
					break ;
				default:
					return TX_STALL ;
			}
			
			break ;
		default:
			return TX_STALL ;	/* Stall unsupported functions */
	}
	
	return TX_STALL ;	/* stall unsupported functions */
}

#pragma INTERRUPT ep0_int
void ep0_int( void)
{
	spp( 4) ;

	if( EP0RA == 0xEE)	/* Correct SETUP received */
	{
		EP0RB |= 0x80 ;	/* By default we expect STATUS_OUT */
		CurDevice = 0 ;
		CurRxBuffer = (BYTE *) EP0RxAddr ;
		fsm_state[ 0] = do_setup() ;
		switch( fsm_state[ 0])
		{
			case TX_STALL:
				EP0RA &= ~0x30 ;	/* Clear STAT bits */
				EP0RA |= 0x10 ;		/* Tx STAT_STALL */
				break ;
			case TX_N:
				EP0TxAddr = data_ptr ;
				if( data_size[ 0] >= MAX_PACKET_SIZE)
				{
					EP0TxCount = MAX_PACKET_SIZE ;
				}
				else
				{
					EP0TxCount = data_size[ 0] ;
					fsm_state[ 0] = TX_LAST ;
				}
		
				EP0RA |= 0x30 ;	/* TX STAT_VALID */
				break ;
			case TX_ACK_ADDR:
			case TX_0:
				EP0TxCount = 0 ;					/* Enable the transmission */
				EP0RA |= 0x30 ;
				break ;
			default:
				nop() ;
		}
	}
	else if( (EP0RA & 0xBF) == 0xAA)	/* IN (don't care toggle) */
	{
		switch( fsm_state[ 0])
		{
			case TX_N:	/* after IN( n) => send next */
				EP0TxAddr += EP0TxCount ;
				data_size[ 0] -= EP0TxCount ;
				if( data_size[ 0] < MAX_PACKET_SIZE)
				{
					EP0TxCount = data_size[ 0] ;
					fsm_state[ 0] = TX_LAST ;
				}

				EP0RA |= 0x30 ;	/* Tx STAT_VALID */				
				break ;
			case TX_LAST:	/* after a IN( 0) => expect STATUS_OUT */
				break ;
			case TX_ACK_ADDR:
				spp( USB_PG) ;
				DADDR0 = 0x80 | address[ 0] ;
				spp( 4) ;
				/* Fall Through */
			case TX_0:	/* STATUS_IN */
				fsm_state[ 0] = UNDEFINED ;
				break ;
		}
	}
	else if( (EP0RA & 0x8F) == 0x82)	/* OUT (don't care Tx STAT */
	{
		switch( fsm_state[ 0])
		{
			case TX_N:	/* HOST stops transmission */
				EP0RA &= ~0x30 ;	/* Tx STAT_DISABLE */
				/* Fall Through */
			case TX_LAST:	/* Status_out following transmission */
				fsm_state[ 0] = UNDEFINED ;				
		}
	}

	EP0RxCount = MAX_PACKET_SIZE ;
	EP0RB |= 0x30 ; /* Rx STAT_VALID */
	EP0RA &= ~0x80 ;	/* Reset CTR */		
}

#pragma INTERRUPT ep1_int
void ep1_int( void)
{
	spp( 4) ;
	ENDPR1_A &= ~0x80 ;	/* Reset CTR bit */
}

void isr_init( void)
{
#define	SINGLE_MODE	0	/* Single interrupt vector mode */
#define	MULTI_MODE	1	/* Multiple interrupt vector mode */

#define	USB_VECTOR		0x00

#define	Interrupt_Mode(opt) if (opt==MULTI_MODE) CTLR&=~0x10; else CTLR|=0x10

	/* USB interrupts initialization. We use single vector mode */
	spp( USB_COMMON_PG) ;
	IVR = USB_VECTOR ;			/* Set interrupt vector */
//	IVR = 30 ;
	Interrupt_Mode( MULTI_MODE);	/* Use individual vectors */

	/* Set Interrupt mask register */
	IMR = INT_RESET;

 	IPR = 0x08 | 0x05;			/* Enable non-iso endpoint CTR interrupt */
								/* and set priority level to 5 for non-iso */
	ISTR = 0x0;					/* clear pending flag */

	ei() ;
}

// extern BYTE Interrupt_Mask;

void Get_Connection0( void)
{
	spp( USB_COMMON_PG) ;
	CTLR &= ~0x07 ;	/* Connect the device */
}

void Disconnection0( void)
{
	spp( USB_COMMON_PG) ;
	CTLR |= 0x07 ;	/* Disconnect the device */
}

static BYTE HUB_Buffer[ 1] ;

void HUB_proc( void)
{
	BYTE	b = 0 ;
	static BYTE	f_active = 0 ;
	static BYTE	idle_count = 0 ;
	static WORD	inner_count = 0 ;

	if( configuration_status[ 0])	/* HUB has not been activated */
	{
		spp( 4) ;
		if( (ENDPR1_A & 0x30) == 0x20 /* STAT_NAK */)
		{
			if( HUB_Status[ 2])
				b |= 1 ;
	
			if( P_Status[ 0][ 2])
				b |= 2 ;
	
			if( P_Status[ 1][ 2])
				b |= 4 ;
	
			if( P_Status[ 2][ 2])
				b |= 8 ;
	
			if( b)
			{
				f_active = 1 ;
				HUB_Buffer[ 0] = b ;
				spp( 4) ;
				EP1TxAddr = HUB_Buffer ;
				EP1TxCount = 1 ;
				ENDPR1_A |= 0x30 ;	/* Tx Valid */
			}
			else if( !f_active)
			{
				inner_count += 1 ;
				if( inner_count == 0)
					idle_count += 1 ;
					
				if( idle_count == 30)
				{
					di() ;
					Disconnection0() ;
					HUB_reset( 0) ;
					main_device = 2 ;	/* select mouse as main device */
					isr_init() ;
					Get_Connection0() ;
				}
			}
		}
	}
}

/* end of usb.c */

⌨️ 快捷键说明

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