DMP_INLINE(void) USB_Standard_Request(USB_Device *usb) { switch (usb->Setup.bRequest) { // case 0x00: Get_Status(usb); break; // case 0x01: Clear_Feature(usb); break; // case 0x02: /* Reserved */ break; // case 0x03: Set_Feature(usb); break; // case 0x04: /* Reserved */ break; case 0x05: Set_Address(usb); break; case 0x06: Get_Descriptor(usb); break; case 0x07: Set_Descriptor(usb); break; case 0x08: Get_Configuration(usb); break; case 0x09: Set_Configuration(usb); break; case 0x0A: Get_Interface(usb); break; case 0x0B: Set_Interface(usb); break; case 0x0C: Synch_Frame(usb); break; default: break; }; }
void handle_Control ( ) { unsigned int usb_cnt=0; if((EP_STATUS_OUT & 0x01)||(EP_STATUS_IN & 0x01)) // 8 byte setup data received { EP_STATUS_OUT = 0x01; // write 1 to clear EP_STATUS_IN = 0x01; EP_STATE[0] = EP_IDLE; // force EP_STATE[0] to EP_IDLE system.usbp0_data.wait_out_report=0; if (CNT0 == 8) // Make sure that EP 0 has an Out Packet of size 8 byte { // added on 2011.5.8 to fix usb set_report error. if (EP0_ADDR_DEF==0x21 && EP0_ADDR_DEF_1 == 0x09 ) { USBINT0 = 0xc0; Set_Report(); system.usbp0_data.report_id=EP0_ADDR_DEF_2; system.usbp0_data.report_type = EP0_ADDR_DEF_3; set_ep_rdy(EP_0); // 1:Endpoint 0 ready for transfer USB data. } else if(EP0_ADDR_DEF==0x21 && EP0_ADDR_DEF_1 == 0x01 ) { // Fix SET_CUR request error SET_CUR(); } else { fifo_Read (EP_0, 8, (UINT8 *) & setup); // Get setup Packet off of Fifo, // it is currently Big-Endian // Compiler Specific - these next three // statements swap the bytes of the // setup packet words to Big Endian so // they can be compared to other 16-bit // values elsewhere properly // USBINT0 = 0xc0; // set_ep_rdy(EP_0); // 1:Endpoint 0 ready for transfer USB data. setup.wValue.i = setup.wValue.c[MSB] + ((int)setup.wValue.c[LSB] << 8); // High byte and low byte exchange() setup.wIndex.i = setup.wIndex.c[MSB] + ( (int)setup.wIndex.c[LSB] << 8); setup.wLength.i = setup.wLength.c[MSB] + ( (int)setup.wLength.c[LSB] << 8); // Intercept HID class - specific requests // Class request. // if( (setup.bmRequestType & ~ 0x80) == DSC_HID) if((setup.bmRequestType & cRequestType) == cClassReq) { #if 0 switch (setup.bRequest) { case GET_REPORT: Get_Report ( ); break; case SET_REPORT: Set_Report(); break; case GET_IDLE: Get_Idle ( ); break; case SET_IDLE: Set_Idle ( ); break; case GET_PROTOCOL: Get_Protocol ( ); break; case SET_PROTOCOL: Set_Protocol ( ); break; default: force_Stall ( ); // Send stall to host if invalid break; // request } #endif switch(setup.bRequest) { // bmRequestType, bRequest, bChannelNum.(CN), bControlSelect(CS, include volume, mute etc.), bInterfaceNO, bTerminal/unit ID, wLength. // CTL: 21 01 00 02 00 05 02 00 // DO: 00 00 case cSET_CUR: if(setup.wIndex.c[1] >= 3) // HID interface. { Get_Report(); } else SET_CUR(); break; case cSET_MIN: if(setup.wIndex.c[1] >= 3) // HID interface. { Get_Idle(); } else SET_MIN(); break; case cSET_MAX: SET_MAX(); break; case cSET_RES: SET_RES(); break; case cSET_MEM: SET_MEM(); break; /* case GET_REPORT: Get_Report(); break; */ case SET_REPORT: Set_Report(); break; /* case GET_IDLE: Get_Idle ( ); break; */ case SET_IDLE: Set_Idle ( ); break; case cGET_CUR: GET_CUR(); break; case cGET_MIN: GET_MIN(); break; case cGET_MAX: GET_MAX(); break; case cGET_RES: GET_RES(); break; case cGET_MEM: GET_MEM(); break; case cGET_STAT: GET_STAT(); break; default: force_Stall ( ); // Send stall to host if invalid break; // request } } else { // Standard request. switch (setup.bRequest) // Call correct subroutine to handle { // each kind of standard request case GET_STATUS: Get_Status ( ); break; case CLEAR_FEATURE: Clear_Feature ( ); break; case SET_FEATURE: Set_Feature ( ); break; case SET_ADDRESS: Set_Address ( ); break; case GET_DESCRIPTOR: Get_Descriptor ( ); break; case GET_CONFIGURATION: Get_Configuration ( ); break; case SET_CONFIGURATION: Set_Configuration( ); break; case GET_INTERFACE: Get_Interface ( ); break; case SET_INTERFACE: // 01 0b 00 00(wValue) 01 00(wIndex) 00 00 Set_Interface ( ); // wValue:Interface alternate setting(0x0 is zero bandwith alternate setting, 0x01 is normal isochronous operate) break; // wIndex: Interface number of one of the audiostreaming interface. default: force_Stall ( ); // Send stall to host if invalid request break; } } } } else { force_Stall ( ); // if rec setup data is not 8 byte , protacal stall } } else if (EP_STATE[0] == EP_SET_ADDRESS) // Handle Status Phase of Set Address { FUNCT_ADR = setup.wValue.c[LSB]; // set usb Address SFR EP_STATE[0] = EP_IDLE; } else if (EP_STATE[0] == EP_WAIT_STATUS) { EP_STATE[0] = EP_IDLE; wait_tx_status=0; } else if (EP_STATE[0] == EP_RX) // See if endpoint should transmit { // Out Token. PC->Device. if (DATASIZE >= EP0_PACKET_SIZE) { fifo_Read(EP_0, EP0_PACKET_SIZE, (unsigned char * )DATAPTR); // Advance data pointer DATAPTR += EP0_PACKET_SIZE; // Decrement data size DATASIZE -= EP0_PACKET_SIZE; // Increment data sent counter DATASENT += EP0_PACKET_SIZE; } else { // read bytes from FIFO // // Report type: 0x01 input, 0x02 output, 0x03 feature report. if( system.usbp0_data.wait_out_report && (system.usbp0_data.report_type==PC_SET_REPORT_2) && (system.usbp0_data.report_id==PC_SET_REPORT_1) ) { system.usbp0_data.wait_out_report=0; DATAPTR = & EP0_ADDR_DEF; if(PC_SET_REPORT_1 == DATAPTR[0]) { DATAPTR++; DATASIZE--; } for ( system.usbp0_data.report_cnt = 0; // read num = NO fifo_data; system.usbp0_data.report_cnt< DATASIZE; system.usbp0_data.report_cnt ++ ) { system.usbp0_data.set_report_data[system.usbp0_data.report_cnt] = DATAPTR[system.usbp0_data.report_cnt]; } system.usbp0_data.aceept = 1; system.usbp0_data.reday_report_flag = 0; set_report_status_phace=1; } else { fifo_Read (EP_0, DATASIZE, (UINT8 * ) DATAPTR); // KEYBOARD_OUT_REPORT if (system.usbp0_data.wait_out_report) { numlock_sta = system.usbp0_data.out_report[0] & 0x01; system.usbp0_data.out_report_index = DATASIZE; system.usbp0_data.wait_out_report=0; set_report_status_phace=1; } } set_Wait_Status ( ); // set Endpoint to EP_WAIT_STATUS } if ( (DATASENT == setup.wLength.i) && (set_report_status_phace==0) ) { set_Wait_Status ( ); } set_report_status_phace=0; } if (EP_STATE[0] == EP_TX) // See if endpoint should transmit { // In Token, device->PC if ((DATASIZE == 0))// || (DATASENT == setup.wLength.i)) // when all data has been sent over { set_Wait_Status ( ); } else { CFG_EP0_1 = 0xc0; if (DATASIZE >= EP0_PACKET_SIZE) { // Break Data into multiple packets if larger than Max Packet fifo_Write (EP_0, EP0_PACKET_SIZE, (unsigned char*)DATAPTR); // Advance data pointer DATAPTR += EP0_PACKET_SIZE; // Decrement data size DATASIZE -= EP0_PACKET_SIZE; // Increment data sent counter DATASENT += EP0_PACKET_SIZE; } else { // If data is less than Max Packet size or zero fifo_Write (EP_0, DATASIZE, (unsigned char*)DATAPTR); // Increment data sent counter DATASENT += DATASIZE; // Decrement data size DATASIZE = 0; USBINT0 = 0xc0; EP_RDY = 0x01 ; // when usb_reset and send ok inttrupt (USBINT0&0x48)!=0 // when setup come (EP_STATUS & 0x01) will set while(((USBINT0 & 0x4C) == 0) && ((EP_STATUS_OUT & 0x01) == 0)); //wait usb_reset, suspend or sending end interrupt happend, wait setup come if((USBINT0&0x40) !=0) { CFG_EP0_1 =0x40; EP_RDY = 0x01 ; USBINT0 = 0xc0; EP_STATE[0]= EP_WAIT_STATUS; } wait_tx_status = 1; system.usbp0_data.wait_out_report=0; } } } if (system.usbp0_data.wait_out_report==0 && wait_tx_status ==0) { USBINT0 = 0xc0; // set_ep_rdy(EP_0); // set ready to receive or send next packet EP_RDY = 0x01 ; } }