/****************************************************************************** Function: void USBCheckCDCRequest(void) Description: This routine checks the most recently received SETUP data packet to see if the request is specific to the CDC class. If the request was a CDC specific request, this function will take care of handling the request and responding appropriately. PreCondition: This function should only be called after a control transfer SETUP packet has arrived from the host. Parameters: None Return Values: None Remarks: This function does not change status or do anything if the SETUP packet did not contain a CDC class specific request. *****************************************************************************/ void USBCheckCDCRequest(void) { /* * If request recipient is not an interface then return */ if(SetupPkt.Recipient != USB_SETUP_RECIPIENT_INTERFACE_BITFIELD) return; /* * If request type is not class-specific then return */ if(SetupPkt.RequestType != USB_SETUP_TYPE_CLASS_BITFIELD) return; /* * Interface ID must match interface numbers associated with * CDC class, else return */ if((SetupPkt.bIntfID != CDC_COMM_INTF_ID)&& (SetupPkt.bIntfID != CDC_DATA_INTF_ID)) return; switch(SetupPkt.bRequest) { //****** These commands are required ******// case SEND_ENCAPSULATED_COMMAND: //send the packet inPipes[0].pSrc.bRam = (BYTE*)&dummy_encapsulated_cmd_response; inPipes[0].wCount.Val = dummy_length; inPipes[0].info.bits.ctrl_trf_mem = USB_EP0_RAM; inPipes[0].info.bits.busy = 1; break; case GET_ENCAPSULATED_RESPONSE: // Populate dummy_encapsulated_cmd_response first. inPipes[0].pSrc.bRam = (BYTE*)&dummy_encapsulated_cmd_response; inPipes[0].info.bits.busy = 1; break; //****** End of required commands ******// #if defined(USB_CDC_SUPPORT_ABSTRACT_CONTROL_MANAGEMENT_CAPABILITIES_D1) case SET_LINE_CODING: outPipes[0].wCount.Val = SetupPkt.wLength; outPipes[0].pDst.bRam = (BYTE*)LINE_CODING_TARGET; outPipes[0].pFunc = LINE_CODING_PFUNC; outPipes[0].info.bits.busy = 1; break; case GET_LINE_CODING: USBEP0SendRAMPtr( (BYTE*)&line_coding, LINE_CODING_LENGTH, USB_EP0_INCLUDE_ZERO); break; case SET_CONTROL_LINE_STATE: control_signal_bitmap._byte = (BYTE)SetupPkt.W_Value.v[0]; //------------------------------------------------------------------ //One way to control the RTS pin is to allow the USB host to decide the value //that should be output on the RTS pin. Although RTS and CTS pin functions //are technically intended for UART hardware based flow control, some legacy //UART devices use the RTS pin like a "general purpose" output pin //from the PC host. In this usage model, the RTS pin is not related //to flow control for RX/TX. //In this scenario, the USB host would want to be able to control the RTS //pin, and the below line of code should be uncommented. //However, if the intention is to implement true RTS/CTS flow control //for the RX/TX pair, then this application firmware should override //the USB host's setting for RTS, and instead generate a real RTS signal, //based on the amount of remaining buffer space available for the //actual hardware UART of this microcontroller. In this case, the //below code should be left commented out, but instead RTS should be //controlled in the application firmware reponsible for operating the //hardware UART of this microcontroller. //--------- //CONFIGURE_RTS(control_signal_bitmap.CARRIER_CONTROL); //------------------------------------------------------------------ #if defined(USB_CDC_SUPPORT_DTR_SIGNALING) if(control_signal_bitmap.DTE_PRESENT == 1) { UART_DTR = USB_CDC_DTR_ACTIVE_LEVEL; } else { UART_DTR = (USB_CDC_DTR_ACTIVE_LEVEL ^ 1); } #endif inPipes[0].info.bits.busy = 1; break; #endif #if defined(USB_CDC_SUPPORT_ABSTRACT_CONTROL_MANAGEMENT_CAPABILITIES_D2) case SEND_BREAK: // Optional inPipes[0].info.bits.busy = 1; if (SetupPkt.wValue == 0xFFFF) //0xFFFF means send break indefinitely until a new SEND_BREAK command is received { UART_Tx = 0; // Prepare to drive TX low (for break signalling) UART_TRISTx = 0; // Make sure TX pin configured as an output UART_ENABLE = 0; // Turn off USART (to relinquish TX pin control) } else if (SetupPkt.wValue == 0x0000) //0x0000 means stop sending indefinite break { UART_ENABLE = 1; // turn on USART UART_TRISTx = 1; // Make TX pin an input } else { //Send break signalling on the pin for (SetupPkt.wValue) milliseconds UART_SEND_BREAK(); } break; #endif default: break; }//end switch(SetupPkt.bRequest) }//end USBCheckCDCRequest
/****************************************************************************** Function: void USBCheckCDCRequest(void) Description: This routine checks the setup data packet to see if it knows how to handle it PreCondition: None Parameters: None Return Values: None Remarks: None *****************************************************************************/ void USBCheckCDCRequest(void) { /* * If request recipient is not an interface then return */ if(SetupPkt.Recipient != USB_SETUP_RECIPIENT_INTERFACE_BITFIELD) return; /* * If request type is not class-specific then return */ if(SetupPkt.RequestType != USB_SETUP_TYPE_CLASS_BITFIELD) return; /* * Interface ID must match interface numbers associated with * CDC class, else return */ if((SetupPkt.bIntfID != CDC_COMM_INTF_ID)&& (SetupPkt.bIntfID != CDC_DATA_INTF_ID)) return; switch(SetupPkt.bRequest) { //****** These commands are required ******// case SEND_ENCAPSULATED_COMMAND: //send the packet inPipes[0].pSrc.bRam = (BYTE*)&dummy_encapsulated_cmd_response; inPipes[0].wCount.Val = dummy_length; inPipes[0].info.bits.ctrl_trf_mem = USB_EP0_RAM; inPipes[0].info.bits.busy = 1; break; case GET_ENCAPSULATED_RESPONSE: // Populate dummy_encapsulated_cmd_response first. inPipes[0].pSrc.bRam = (BYTE*)&dummy_encapsulated_cmd_response; inPipes[0].info.bits.busy = 1; break; //****** End of required commands ******// #if defined(USB_CDC_SUPPORT_ABSTRACT_CONTROL_MANAGEMENT_CAPABILITIES_D1) case SET_LINE_CODING: outPipes[0].wCount.Val = SetupPkt.wLength; outPipes[0].pDst.bRam = (BYTE*)LINE_CODING_TARGET; outPipes[0].pFunc = LINE_CODING_PFUNC; outPipes[0].info.bits.busy = 1; break; case GET_LINE_CODING: USBEP0SendRAMPtr( (BYTE*)&line_coding, LINE_CODING_LENGTH, USB_EP0_INCLUDE_ZERO); break; case SET_CONTROL_LINE_STATE: control_signal_bitmap._byte = (BYTE)SetupPkt.W_Value.v[0]; CONFIGURE_RTS(control_signal_bitmap.CARRIER_CONTROL); CONFIGURE_DTR(control_signal_bitmap.DTE_PRESENT); inPipes[0].info.bits.busy = 1; break; #endif #if defined(USB_CDC_SUPPORT_ABSTRACT_CONTROL_MANAGEMENT_CAPABILITIES_D2) case SEND_BREAK: // Optional inPipes[0].info.bits.busy = 1; if (SetupPkt.wValue == 0xFFFF) { UART_ENABLE = 0; // turn off USART UART_TRISTx = 0; // Make TX pin an output UART_Tx = 0; // make it low } else if (SetupPkt.wValue == 0x0000) { UART_ENABLE = 1; // turn on USART UART_TRISTx = 1; // Make TX pin an input } else { UART_SEND_BREAK(); } break; #endif default: break; }//end switch(SetupPkt.bRequest) }//end USBCheckCDCRequest