📄 usbch9.c
字号:
break;
/* set endpoint feature */
case 2:
/* check for valid feature (only ENDPOINT_HALT available) */
if (usb_setup.VALUE != 0) {
STALL_ENDPOINT_0;
return;
}
/* check endpoint no. and stall if not configured or > 0 */
if (CheckEP(usb_setup.INDEX))
return;
/* set ENDPOINT_HALT */
USB_ISR_set_endpoint_status(usb_setup.INDEX, 1);
break;
/* set interface feature (no features defined) */
default:
STALL_ENDPOINT_0;
return;
}
/* status phase */
USB_ISR_io_request(EP0_SEND, 0, 0);
}
else {
if (test_mode_index) {
/* Enter Test Mode */
USB_STATUS_TESTMODE(test_mode_index >> 8);
USB_ISR_set_test_mode(test_mode_index);
}
}
}
/**************************************************************************
*
* Function Name: SetAddress
* Comments:
* Chapter 9 SetAddress command
* We setup a transmit packet of 0 length ready for the IN token.
* Once we get the service_ep0 interrupt for the IN token, then
* we finally change the ADDR register and go to the ADDRESS state.
*
**************************************************************************/
static void SetAddress(Boolean setup)
{
if (setup) {
usb_state.DEVICE_ADDRESS = usb_setup.VALUE;
/* status phase */
USB_ISR_io_request(EP0_SEND, 0, 0);
}
else {
/* Address zero means back to default state. */
USB_ISR_set_address(usb_state.DEVICE_ADDRESS);
if (usb_state.DEVICE_ADDRESS)
usb_state.USB_STATE = USB_STATE_ADDRESS;
else
usb_state.USB_STATE = USB_STATE_DEFAULT;
}
USB_STATUS_SET(ENUMERATED);
}
/**************************************************************************
*
* Function Name: GetDescriptor
* Comments:
* Chapter 9 GetDescriptor command
*
**************************************************************************/
static void GetDescriptor(void)
{
Uint16 desc_index = usb_setup.VALUE & 0xFF;
Uint16 length = usb_setup.LENGTH, ConfigSize;
Uint8 *ConfigDesc, *OtherSpeed;
/* Load the appropriate string depending on the descriptor requested.*/
switch (usb_setup.VALUE >> 8) {
/* get device descriptor */
case 1:
if (length > USB_Conf.DevDesc[0])
length = USB_Conf.DevDesc[0];
USB_ISR_io_request(EP0_SEND, (Uint8 *)USB_Conf.DevDesc, length);
break;
/* get configuration descriptor */
case 2:
USB_Conf.MaxAltIface = 0;
ConfigSize = USB_Conf.ConfigurationSize;
if (USB20_HighSpeed)
ConfigDesc = USB_Conf.HSConfDesc;
else
ConfigDesc = USB_Conf.FSConfDesc;
ConfigDesc[1] = 2; /* bDescType 2 = CONFIGURATION */
if (length > ConfigSize)
length = ConfigSize;
USB_ISR_io_request(EP0_SEND, ConfigDesc, length);
break;
/* get string descriptor descriptor */
case 3:
if (desc_index) {
/* Check if requested language (in INDEX) is supported. */
if (USB_Conf.StrDescTable[0][2] != (usb_setup.INDEX & 0xFF) ||
USB_Conf.StrDescTable[0][3] != (usb_setup.INDEX >> 8))
{
/* Language error: We only support English in this example. */
desc_index = USB_Conf.StrErrorLanguage;
}
/* check index range */
else if (desc_index > USB_Conf.StrDescCount) {
/* 'Illegal Index' */
desc_index = USB_Conf.StrErrorIndex;
}
}
if (length > USB_Conf.StrDescTable[desc_index][0])
length = USB_Conf.StrDescTable[desc_index][0];
USB_ISR_io_request(EP0_SEND,
(Uint8 *)USB_Conf.StrDescTable[desc_index], length);
break;
/* get device_qualifier descriptor */
case 6:
if (length > USB_Conf.DevQualifierDesc[0])
length = USB_Conf.DevQualifierDesc[0];
USB_ISR_io_request(EP0_SEND,
(Uint8 *)USB_Conf.DevQualifierDesc, length);
break;
/* get other_speed_configuration descriptor */
case 7:
USB_Conf.MaxAltIface = 0;
ConfigSize = USB_Conf.ConfigurationSize;
if (USB20_HighSpeed)
OtherSpeed = USB_Conf.FSConfDesc;
else
OtherSpeed = USB_Conf.HSConfDesc;
OtherSpeed[1] = 7; /* bDescType 7 = OTHER_SPEED_CONFIGURATION */
if (length > ConfigSize)
length = ConfigSize;
USB_ISR_io_request(EP0_SEND, OtherSpeed, length);
break;
/* get HID Descriptor */
case 0x21:
if ((usb_setup.INDEX & 0xFF) != USB_Conf.HIDinterface) {
STALL_ENDPOINT_0;
return;
}
if (length > USB_Conf.HIDDescriptor_size)
length = USB_Conf.HIDDescriptor_size;
USB_ISR_io_request(EP0_SEND, USB_Conf.HIDDescriptor, length);
break;
/* get HID Class Report Descriptor */
case 0x22:
if ((usb_setup.INDEX & 0xFF) != USB_Conf.HIDinterface) {
STALL_ENDPOINT_0;
return;
}
if (length > USB_Conf.HIDClassReportDesc_size)
length = USB_Conf.HIDClassReportDesc_size;
USB_ISR_io_request(EP0_SEND, USB_Conf.HIDClassReportDesc, length);
break;
default:
/* 4 get interface descriptor */
/* 5 get endpoint descriptor */
STALL_ENDPOINT_0;
return;
}
/* status phase */
USB_ISR_io_request(EP0_RECV, 0, 0);
}
/**************************************************************************
*
* Function Name: SetConfig
* Comments:
* Chapter 9 SetConfig command
*
**************************************************************************/
static void SetConfig(void)
{
Uint16 config_no = usb_setup.VALUE & 0xFF;
if (usb_state.USB_STATE != USB_STATE_CONFIG &&
usb_state.USB_STATE != USB_STATE_ADDRESS)
{
STALL_ENDPOINT_0;
return;
}
/* Configuration number 0 indicates return to unconfigured state. */
if (config_no == 0) {
/* Clear the currently selected config value. */
usb_state.USB_CURR_CONFIG = 0;
usb_state.USB_STATE = USB_STATE_ADDRESS;
}
else {
/*
* If the configuration value (config_no) differs from the current
* configuration value, then deconfigure current interface endpoints.
*/
if (usb_state.USB_CURR_CONFIG != config_no) {
USB_ISR_io_request(EP0_SEND, 0, 0);
usb_state.USB_STATE = USB_STATE_CONFIG;
USB_deconfigure_current_interface();
usb_state.USB_CURR_CONFIG = config_no;
/* MAC OS assumes that the first interface is enabled by default */
SetIfaceNo(0);
return;
}
usb_state.USB_STATE = USB_STATE_CONFIG;
/* MAC OS assumes that the first interface is enabled by default */
SetIfaceNo(0);
if (USB_ForceReset)
return;
}
/* status phase */
USB_ISR_io_request(EP0_SEND, 0, 0);
}
/**************************************************************************
*
* Function Name: GetInterface
* Comments:
* Chapter 9 GetInterface command
*
**************************************************************************/
static void GetInterface(void)
{
static Uint8 interface_no;
interface_no = usb_setup.INDEX & 0xFF;
if (usb_state.USB_STATE != USB_STATE_CONFIG || interface_no > MAX_IFACE) {
STALL_ENDPOINT_0;
return;
}
interface_no = (alt_interface_no >= 0) ? alt_interface_no : 0;
USB_ISR_io_request(EP0_SEND, &interface_no, 1);
/* status phase */
USB_ISR_io_request(EP0_RECV, 0, 0);
}
/**************************************************************************
*
* Function Name: SetInterface
* Comments:
* Chapter 9 SetInterface command
*
**************************************************************************/
static void SetInterface(void)
{
Uint8 alt_setting, interface_no;
alt_setting = usb_setup.VALUE & 0xFF;
interface_no = usb_setup.INDEX & 0xFF;
if (alt_setting > USB_Conf.MaxAltIface || interface_no > MAX_IFACE ||
usb_setup.REQUESTTYPE != 0x01)
{
STALL_ENDPOINT_0;
return;
}
SetIfaceNo(alt_setting);
if (USB_ForceReset)
return;
/* status phase */
USB_ISR_io_request(EP0_SEND, 0, 0);
}
/*
* Code to set Interface has been broken out so that SetConfig() can
* set the first available interface as the default (required by
* MAC OS 10.2).
*/
static void SetIfaceNo(Uint8 alt_setting)
{
/*
* If the alternate value differs from the current alternate value
* for the specified interface, then endpoints must be reconfigured
* to match the new alternate.
*/
if (alt_interface_no != alt_setting)
{
Uint16 size;
/*
* Deconfigure current interface endpoints, return if not successful
* (i.e., taking too long) so that it can be done at task level by
* USB_task.
*/
USB_deconfigure_current_interface();
if (USB_ForceReset)
return;
size = USB20_HighSpeed ? HS_BULK_SIZE : FS_BULK_SIZE;
/* Alternate interface: 0 */
if (alt_setting == 0) {
prn_status = EP_CONFIG_RW;
USB_init_endpoint(PRN_RECV, size, USB_BULK_ENDPOINT, TRUE);
USB_init_endpoint(PRN_SEND, size, USB_BULK_ENDPOINT, TRUE);
#if SCANNER_EPS
scn_status = EP_CONFIG_RW;
USB_init_endpoint(SCN_RECV, size, USB_BULK_ENDPOINT, TRUE);
# ifdef MAC_SCANNER_WORKAROUND
USB_init_endpoint(SCN_SEND, 64, USB_BULK_ENDPOINT, TRUE);
# else
USB_init_endpoint(SCN_SEND, size, USB_BULK_ENDPOINT, TRUE);
# endif /* MAC_SCANNER_WORKAROUND */
#endif /* SCANNER_EPS */
hid_status = EP_CONFIG_W;
USB_init_endpoint(HID_SEND, INT_BSIZE, USB_INTERRUPT_ENDPOINT, TRUE);
#if DEBUG_EPS
dbg_status = EP_CONFIG_RW;
USB_init_endpoint(DBG_RECV, size, USB_BULK_ENDPOINT, TRUE);
USB_init_endpoint(DBG_SEND, size, USB_BULK_ENDPOINT, TRUE);
#endif /* DEBUG_EPS */
#ifdef MEMORY_CARD_READER
mem_status = EP_CONFIG_RW;
USB_init_endpoint(MEM_RECV, size, USB_BULK_ENDPOINT, TRUE);
USB_init_endpoint(MEM_SEND, size, USB_BULK_ENDPOINT, TRUE);
#endif /* MEMORY_CARD_READER */
}
alt_interface_no = alt_setting;
CableConnected = TRUE;
/*
* Initiate read of endpoints. This is copy of StartEndpointRead()
* code for ISR use.
*
* Compute space available left in input buffer (multiple of 512).
*/
ISRStartEndpointRead(PRN_RECV, &prn_recv);
#if SCANNER_EPS
ISRStartEndpointRead(SCN_RECV, &scn_recv);
#endif
#if DEBUG_EPS
ISRStartEndpointRead(DBG_RECV, &dbg_recv);
#endif /* DEBUG_EPS */
#ifdef MEMORY_CARD_READER
ISRStartEndpointRead(MEM_RECV, &mem_recv);
#endif /* MEMORY_CARD_READER */
#if USB_ALWAYS_SEND_HID
/*
* If USB 1.1 there are problems with the USB PHY and certain chip
* sets. To avoid hardware issues with HID endpoint, always send
* something (no-operation packet) if valid HID data not available.
*/
#ifdef USB_HID_NULL2
/* This version sends null packet in both USB 1.1 and USB 2.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -