// Device request parser void SetupCommand(void) { void *dscr_ptr; switch(SETUPDAT[1]) { case SC_GET_DESCRIPTOR: // *** Get Descriptor if(TRUE)//DR_GetDescriptor()) switch(SETUPDAT[3]) { case GD_DEVICE: // Device SUDPTRH = MSB(pDeviceDscr); SUDPTRL = LSB(pDeviceDscr); break; case GD_DEVICE_QUALIFIER: // Device Qualifier // only retuen a device qualifier if this is a high speed // capable chip. if (HighSpeedCapable()) { SUDPTRH = MSB(pDeviceQualDscr); SUDPTRL = LSB(pDeviceQualDscr); } else { EZUSB_STALL_EP0(); } break; case GD_CONFIGURATION: // Configuration SUDPTRH = MSB(pConfigDscr); SUDPTRL = LSB(pConfigDscr); break; case GD_OTHER_SPEED_CONFIGURATION: // Other Speed Configuration SUDPTRH = MSB(pOtherConfigDscr); SUDPTRL = LSB(pOtherConfigDscr); break; case GD_STRING: // String if(dscr_ptr = (void *)EZUSB_GetStringDscr(SETUPDAT[2])) { SUDPTRH = MSB(dscr_ptr); SUDPTRL = LSB(dscr_ptr); } else EZUSB_STALL_EP0(); // Stall End Point 0 break; default: // Invalid request EZUSB_STALL_EP0(); // Stall End Point 0 } break; case SC_GET_INTERFACE: // *** Get Interface DR_GetInterface(); break; case SC_SET_INTERFACE: // *** Set Interface //DR_SetInterface(); break; case SC_SET_CONFIGURATION: // *** Set Configuration DR_SetConfiguration(); break; case SC_GET_CONFIGURATION: // *** Get Configuration DR_GetConfiguration(); break; case SC_GET_STATUS: // *** Get Status if(TRUE)//DR_GetStatus()) switch(SETUPDAT[0]) { case GS_DEVICE: // Device EP0BUF[0] = ((BYTE)Rwuen << 1) | (BYTE)Selfpwr; EP0BUF[1] = 0; EP0BCH = 0; EP0BCL = 2; break; case GS_INTERFACE: // Interface EP0BUF[0] = 0; EP0BUF[1] = 0; EP0BCH = 0; EP0BCL = 2; break; case GS_ENDPOINT: // End Point EP0BUF[0] = *(BYTE xdata *) epcs(SETUPDAT[4]) & bmEPSTALL; EP0BUF[1] = 0; EP0BCH = 0; EP0BCL = 2; break; default: // Invalid Command EZUSB_STALL_EP0(); // Stall End Point 0 } break; case SC_CLEAR_FEATURE: // *** Clear Feature if(TRUE)//DR_ClearFeature()) switch(SETUPDAT[0]) { case FT_DEVICE: // Device if(SETUPDAT[2] == 1) Rwuen = FALSE; // Disable Remote Wakeup else EZUSB_STALL_EP0(); // Stall End Point 0 break; case FT_ENDPOINT: // End Point if(SETUPDAT[2] == 0) { *(BYTE xdata *) epcs(SETUPDAT[4]) &= ~bmEPSTALL; EZUSB_RESET_DATA_TOGGLE( SETUPDAT[4] ); } else EZUSB_STALL_EP0(); // Stall End Point 0 break; } break; case SC_SET_FEATURE: // *** Set Feature if(TRUE)//DR_SetFeature()) switch(SETUPDAT[0]) { case FT_DEVICE: // Device if(SETUPDAT[2] == 1) Rwuen = TRUE; // Enable Remote Wakeup else if(SETUPDAT[2] == 2) // Set Feature Test Mode. The core handles this request. However, it is // necessary for the firmware to complete the handshake phase of the // control transfer before the chip will enter test mode. It is also // necessary for FX2 to be physically disconnected (D+ and D-) // from the host before it will enter test mode. break; else EZUSB_STALL_EP0(); // Stall End Point 0 break; case FT_ENDPOINT: // End Point *(BYTE xdata *) epcs(SETUPDAT[4]) |= bmEPSTALL; break; default: EZUSB_STALL_EP0(); // Stall End Point 0 } break; default: // *** Invalid Command if(DR_VendorCmnd()) EZUSB_STALL_EP0(); // Stall End Point 0 } // Acknowledge handshake phase of device request EP0CS |= bmHSNAK; }
void usb_handle_setup_packet (void) { _usb_got_SUDAV = 0; // handle the standard requests... switch (bRequestType & bmRT_TYPE_MASK){ case bmRT_TYPE_CLASS: case bmRT_TYPE_RESERVED: fx2_stall_ep0 (); // we don't handle these. indicate error break; case bmRT_TYPE_VENDOR: // call the application code. // If it handles the command it returns non-zero if (!app_vendor_cmd ()) fx2_stall_ep0 (); break; case bmRT_TYPE_STD: // these are the standard requests... if ((bRequestType & bmRT_DIR_MASK) == bmRT_DIR_IN){ //////////////////////////////////// // handle the IN requests //////////////////////////////////// switch (bRequest){ case RQ_GET_CONFIG: EP0BUF[0] = _usb_config; // FIXME app should handle EP0BCH = 0; EP0BCL = 1; break; // -------------------------------- case RQ_GET_INTERFACE: EP0BUF[0] = _usb_alt_setting; // FIXME app should handle EP0BCH = 0; EP0BCL = 1; break; // -------------------------------- case RQ_GET_DESCR: switch (wValueH){ case DT_DEVICE: SUDPTRH = MSB (current_device_descr); SUDPTRL = LSB (current_device_descr); break; case DT_DEVQUAL: SUDPTRH = MSB (current_devqual_descr); SUDPTRL = LSB (current_devqual_descr); break; case DT_CONFIG: if (0 && wValueL != 1) // FIXME only a single configuration fx2_stall_ep0 (); else { SUDPTRH = MSB (current_config_descr); SUDPTRL = LSB (current_config_descr); } break; case DT_OTHER_SPEED: if (0 && wValueL != 1) // FIXME only a single configuration fx2_stall_ep0 (); else { SUDPTRH = MSB (other_config_descr); SUDPTRL = LSB (other_config_descr); } break; case DT_STRING: if (wValueL >= nstring_descriptors) fx2_stall_ep0 (); else { xdata char *p = string_descriptors[wValueL]; SUDPTRH = MSB (p); SUDPTRL = LSB (p); } break; default: fx2_stall_ep0 (); // invalid request break; } break; // -------------------------------- case RQ_GET_STATUS: switch (bRequestType & bmRT_RECIP_MASK){ case bmRT_RECIP_DEVICE: EP0BUF[0] = bmGSDA_SELF_POWERED; // FIXME app should handle EP0BUF[1] = 0; EP0BCH = 0; EP0BCL = 2; break; case bmRT_RECIP_INTERFACE: EP0BUF[0] = 0; EP0BUF[1] = 0; EP0BCH = 0; EP0BCL = 2; break; case bmRT_RECIP_ENDPOINT: if (plausible_endpoint (wIndexL)){ EP0BUF[0] = *epcs (wIndexL) & bmEPSTALL; EP0BUF[1] = 0; EP0BCH = 0; EP0BCL = 2; } else fx2_stall_ep0 (); break; default: fx2_stall_ep0 (); break; } break; // -------------------------------- case RQ_SYNCH_FRAME: // not implemented default: fx2_stall_ep0 (); break; } } else { //////////////////////////////////// // handle the OUT requests //////////////////////////////////// switch (bRequest){ case RQ_SET_CONFIG: _usb_config = wValueL; // FIXME app should handle break; case RQ_SET_INTERFACE: _usb_alt_setting = wValueL; // FIXME app should handle break; // -------------------------------- case RQ_CLEAR_FEATURE: switch (bRequestType & bmRT_RECIP_MASK){ case bmRT_RECIP_DEVICE: switch (wValueL){ case FS_DEV_REMOTE_WAKEUP: default: fx2_stall_ep0 (); } break; case bmRT_RECIP_ENDPOINT: if (wValueL == FS_ENDPOINT_HALT && plausible_endpoint (wIndexL)){ *epcs (wIndexL) &= ~bmEPSTALL; fx2_reset_data_toggle (wIndexL); } else fx2_stall_ep0 (); break; default: fx2_stall_ep0 (); break; } break; // -------------------------------- case RQ_SET_FEATURE: switch (bRequestType & bmRT_RECIP_MASK){ case bmRT_RECIP_DEVICE: switch (wValueL){ case FS_TEST_MODE: // hardware handles this after we complete SETUP phase handshake break; case FS_DEV_REMOTE_WAKEUP: default: fx2_stall_ep0 (); break; } } break; case bmRT_RECIP_ENDPOINT: switch (wValueL){ case FS_ENDPOINT_HALT: if (plausible_endpoint (wIndexL)) *epcs (wIndexL) |= bmEPSTALL; else fx2_stall_ep0 (); break; default: fx2_stall_ep0 (); break; } break; // -------------------------------- case RQ_SET_ADDRESS: // handled by fx2 hardware case RQ_SET_DESCR: // not implemented default: fx2_stall_ep0 (); } } break; } // bmRT_TYPE_MASK // ack handshake phase of device request EP0CS |= bmHSNAK; }