📄 usb.c
字号:
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 + -