void handle_usb_control(int sockfd, USBIP_RET_SUBMIT *usb_req) { int handled = 0; StandardDeviceRequest control_req; #ifdef LINUX printf("%016llX\n",usb_req->setup); #else printf("%016I64X\n",usb_req->setup); #endif control_req.bmRequestType= (usb_req->setup & 0xFF00000000000000)>>56; control_req.bRequest= (usb_req->setup & 0x00FF000000000000)>>48; control_req.wValue0= (usb_req->setup & 0x0000FF0000000000)>>40; control_req.wValue1= (usb_req->setup & 0x000000FF00000000)>>32; control_req.wIndex0= (usb_req->setup & 0x00000000FF000000)>>24; control_req.wIndex1= (usb_req->setup & 0x0000000000FF0000)>>16; control_req.wLength= ntohs(usb_req->setup & 0x000000000000FFFF); printf(" UC Request Type %u\n",control_req.bmRequestType); printf(" UC Request %u\n",control_req.bRequest); printf(" UC Value %u[%u]\n",control_req.wValue1,control_req.wValue0); printf(" UCIndex %u-%u\n",control_req.wIndex1,control_req.wIndex0); printf(" UC Length %u\n",control_req.wLength); if(control_req.bmRequestType == 0x80) // Host Request { if(control_req.bRequest == 0x06) // Get Descriptor { handled = handle_get_descriptor(sockfd, &control_req, usb_req); } if(control_req.bRequest == 0x00) // Get STATUS { char data[2]; data[0]=0x01; data[1]=0x00; send_usb_req(sockfd,usb_req, data, 2 , 0); handled = 1; printf("GET_STATUS\n"); } } if(control_req.bmRequestType == 0x00) // { if(control_req.bRequest == 0x09) // Set Configuration { handled = handle_set_configuration(sockfd, &control_req, usb_req); } } if(control_req.bmRequestType == 0x01) { if(control_req.bRequest == 0x0B) //SET_INTERFACE { printf("SET_INTERFACE\n"); send_usb_req(sockfd,usb_req,"",0,1); handled=1; } } if(! handled) handle_unknown_control(sockfd, &control_req, usb_req); }
void main_init(void) { /* Disable extra movx delays */ CKCON &= ~(bmBIT2 | bmBIT1 | bmBIT0); /* Setup FIFO before CPUCS: - Use internal clock source as FPGA is not providing one yet - Set internal clock to 48MHz - Keep clock out disabled - Do not inverse clock polarity - Keep FIFO synchronous - Do not enable GSTATE - Set ports B and D as 16bits slave FIFO */ IFCONFIG = bmIFCLKSRC | bm3048MHZ | bmIFCFG1 | bmIFCFG0; SYNCDELAY; /* 1 CLKOUT: CLK0 23 */ CPUCS = CLKSPD48 | bmCLKOE; REVCTL = bmNOAUTOARM | bmSKIPCOMMIT; SYNCDELAY; /* PortA pinout: INT0: TP14, 133 PA1: TP4, 119 SLOE: VCC PA3: D1 ("Host power") led, then R7 and VCC - so on when low. FIFOADR0: FIFOADR1: PKTEND: SLCS#: GND */ PORTACFG = bmSLCS | bmINT0; IOA = bmBIT1; OEA = bmBIT3 | bmBIT1; /* PortE pinout: 108 PE0: 114 109 PE1: 113 110 PE2: 112 Used to load FPGA bitstream: 111 RXD0OUT: DATA0 20 112 PE4 & TXD0: DCLK 21 113 PE5: CONF_DONE 123 114 PE6: STATUS# 121 115 PE7: CONFIG# 26 */ PORTECFG = bmRXD0OUT; IOE = bmBIT2 | bmBIT1 | bmBIT0; OEE = FPGA_nCONFIG | FPGA_DCLK | bmBIT2 | bmBIT1 | bmBIT0; /* SCON0 = XXXXX100: CLKOUT / 4, mode 0 */ SM2 = 1; readSerialNumber(); EP0BCH = 0; SYNCDELAY; /* As of TRM rev.*D 8.6.1.2 */ /* FLAGD is the only flag connected to FPGA, and the FPGA needs to know when the fifo is full. FLADG defaults to FIFO2PF, which by default behaves like FIFO2FF. So map FIFO2FF to FLAGD instead. */ PINFLAGSCD = (PINFLAGSCD & 0xf0) | 0xc0; /* FIFO2PF: >=1 uncommitted bytes */ EP2FIFOPFH = bmDECIS | bmPKTSTAT; EP2FIFOPFL = 1; /* Timer 2: Used to update EP2FIFOPF depending on the number of transfers committed to USB since previous timer interrupt. */ T2CON = 0x00; CKCON &= ~bmBIT5; RCAP2L = 0; RCAP2H = 0; ET2 = 1; /* Enable Timer 2 interrupt */ TR2 = 1; /* Timer 2: run */ handle_set_configuration(CONFIG_UNCONFIGURED); }
/** * Looks into the SETUPDAT data and dispatches to the callback handlers. * * Note that this code will handshake the packet for all callbacks except * handle_vendorcommand(). This code *used* to handshake those too, but as it * is not required by the specification to do so (for packets with a DATA * segment) it doesn't do it anymore. */ void handle_setupdata() { BOOL handshake = TRUE; //printf ( "Handle setupdat: %02x\n", SETUPDAT[1] ); switch ( SETUPDAT[1] ) { case GET_STATUS: if (!handle_get_status()) STALLEP0(); break; case CLEAR_FEATURE: if (!handle_clear_feature()) { STALLEP0(); } break; case SET_FEATURE: if (!handle_set_feature()) { STALLEP0(); } break; case GET_DESCRIPTOR: handle_get_descriptor(); break; case GET_CONFIGURATION: EP0BUF[0] = handle_get_configuration(); EP0BCH=0; EP0BCL=1; break; case SET_CONFIGURATION: // user callback if( !handle_set_configuration(SETUPDAT[2])) { STALLEP0(); } break; case GET_INTERFACE: { BYTE alt_ifc; if (!handle_get_interface(SETUPDAT[4],&alt_ifc)) { STALLEP0(); } else { EP0BUF[0] = alt_ifc; EP0BCH=0; EP0BCL=1; } } break; case SET_INTERFACE: // user callback if ( !handle_set_interface(SETUPDAT[4],SETUPDAT[2])) { STALLEP0(); } break; default: if (handle_vendorcommand(SETUPDAT[1])) { handshake = FALSE; } else { printf ( "Unhandled Vendor Command: %02x\n" , SETUPDAT[1] ); STALLEP0(); } } // do the handshake if(handshake) { EP0CS |= bmHSNAK; } }