/********************************************************************* * * Microchip USB C18 Firmware - HID Version 1.0 * ********************************************************************* * FileName: hid.c * Dependencies: See INCLUDES section below * Processor: PIC18 * Compiler: C18 2.30.01+ * Company: Microchip Technology, Inc. * * * Author Date Comment *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Rawin Rojvanit 19/11/04 Original. * Dario Greggio 28/02/05 aggiunto ClrWdt(). ********************************************************************/ #if defined(__18F4550) || defined(__18F2550) || defined(__18F2455) /** I N C L U D E S **********************************************************/ #include #include #include "system\usb\usb.h" #ifdef USB_USE_HID /** V A R I A B L E S ********************************************************/ #pragma udata byte idle_rate; byte active_protocol; // [0] Boot Protocol [1] Report Protocol byte hid_rpt_rx_len; /** P R I V A T E P R O T O T Y P E S ***************************************/ void HIDGetReportHandler(void); void HIDSetReportHandler(void); /** D E C L A R A T I O N S **************************************************/ #pragma code /** C L A S S S P E C I F I C R E Q ****************************************/ /****************************************************************************** * Function: void USBCheckHIDRequest(void) * * PreCondition: None * * Input: None * * Output: None * * Side Effects: None * * Overview: This routine checks the setup data packet to see if it * knows how to handle it * * Note: None *****************************************************************************/ void USBCheckHIDRequest(void) { if(SetupPkt.Recipient != RCPT_INTF) return; if(SetupPkt.bIntfID != HID_INTF_ID) return; /* * There are two standard requests that hid.c may support. * 1. GET_DSC(DSC_HID,DSC_RPT,DSC_PHY); * 2. SET_DSC(DSC_HID,DSC_RPT,DSC_PHY); */ if(SetupPkt.bRequest == GET_DSC) { switch(SetupPkt.bDscType) { case DSC_HID: ctrl_trf_session_owner = MUID_HID; mUSBGetHIDDscAdr(pSrc.bRom); // See usbcfg.h wCount._word = sizeof(USB_HID_DSC); break; case DSC_RPT: ctrl_trf_session_owner = MUID_HID; mUSBGetHIDRptDscAdr(pSrc.bRom); // See usbcfg.h mUSBGetHIDRptDscSize(wCount._word); // See usbcfg.h break; case DSC_PHY: // ctrl_trf_session_owner = MUID_HID; break; } //end switch(SetupPkt.bDscType) usb_stat.ctrl_trf_mem = _ROM; } //end if(SetupPkt.bRequest == GET_DSC) if(SetupPkt.RequestType != CLASS) return; switch(SetupPkt.bRequest) { case GET_REPORT: HIDGetReportHandler(); break; case SET_REPORT: HIDSetReportHandler(); break; case GET_IDLE: ctrl_trf_session_owner = MUID_HID; pSrc.bRam = (byte*)&idle_rate; // Set source usb_stat.ctrl_trf_mem = _RAM; // Set memory type LSB(wCount) = 1; // Set data count break; case SET_IDLE: ctrl_trf_session_owner = MUID_HID; idle_rate = MSB(SetupPkt.W_Value); break; case GET_PROTOCOL: ctrl_trf_session_owner = MUID_HID; pSrc.bRam = (byte*)&active_protocol;// Set source usb_stat.ctrl_trf_mem = _RAM; // Set memory type LSB(wCount) = 1; // Set data count break; case SET_PROTOCOL: ctrl_trf_session_owner = MUID_HID; active_protocol = LSB(SetupPkt.W_Value); break; } //end switch(SetupPkt.bRequest) } //end USBCheckHIDRequest void HIDGetReportHandler(void) { // ctrl_trf_session_owner = MUID_HID; // The report type is in the high byte of the setup packet's Value field. // 3 = Feature; 1 = Input. switch(MSB(SetupPkt.W_Value)) { byte count; case 1: // Input report // Find out which report ID was specified. // The report ID is in the low byte (LSB) of the Value field. // This example supports Report ID 0. switch(LSB(SetupPkt.W_Value)) { case 0: // Report ID 0 // HID will handle the request. ctrl_trf_session_owner = MUID_HID; // Provide the data to send. GetInputReport0(); break; case 1: // Report ID 1 // Place similar code to handle Report ID 1 here. break; } // end switch(LSB(SetupPkt.W_Value)) break; case 3: // Feature report // The report ID is in the low byte of the Setup packet's Value field. // This example supports Report ID 0. switch(LSB(SetupPkt.W_Value)) { case 0: // Report ID 0 // The HID class code will handle the request. ctrl_trf_session_owner = MUID_HID; // Provide the data to send. GetFeatureReport0(); break; } // end switch(LSB(SetupPkt.W_Value)) break; } // end switch (MSB(SetupPkt.W_Value)) // The data is in RAM. usb_stat.ctrl_trf_mem = _RAM; // Set memory type } //end HIDGetReportHandler void HIDSetReportHandler(void) { // ctrl_trf_session_owner = MUID_HID; // pDst.bRam = (byte*)&hid_report_out; // The report type is in the high byte of the Setup packet's Value field. // 3 = Feature; 2 = Output. switch(MSB(SetupPkt.W_Value)) { case 2: // Output report // The report ID is in the low byte of the Setup packet's Value field. // This example supports Report ID 0. switch(LSB(SetupPkt.W_Value)) { case 0: // Report ID 0 // HID will handle the request. ctrl_trf_session_owner = MUID_HID; // Save the report type and report ID in out_report_status. //out_report_status = SetOutReportStatus // (MSB(SetupPkt.W_Value), // LSB(SetupPkt.W_Value)); // When the report arrives in the data stage, the data will be // stored in hid_report_out (defined in usbmmap.c). pDst.bRam = (byte*)&hid_report_out; break; } // end switch(LSB(SetupPkt.W_Value)) break; case 3: // Feature report // Find out which report ID was specified. // The report ID is in the low byte (LSB) of the Value field. // This example supports Report ID 0. switch(LSB(SetupPkt.W_Value)) { case 0: // Report ID 0 // HID will handle the request. ctrl_trf_session_owner = MUID_HID; // Save the report type and report ID in out_report_status. //out_report_status = SetOutReportStatus // (MSB(SetupPkt.W_Value), // LSB(SetupPkt.W_Value)); // When the report arrives in the data stage, the data will be // stored in hid_report_feature (defined in usbmmap.c). pDst.bRam = (byte*)&hid_report_feature; break; } // end switch(LSB(SetupPkt.W_Value)) break; } // end switch(MSB(SetupPkt.W_Value)) } //end HIDSetReportHandler /** U S E R A P I ***********************************************************/ /****************************************************************************** * Function: void HIDInitEP(void) * * PreCondition: None * * Input: None * * Output: None * * Side Effects: None * * Overview: HIDInitEP initializes HID endpoints, buffer descriptors, * internal state-machine, and variables. * It should be called after the USB host has sent out a * SET_CONFIGURATION request. * See USBStdSetCfgHandler() in usb9.c for examples. * * Note: None *****************************************************************************/ void HIDInitEP(void) { hid_rpt_rx_len =0; HID_UEP = EP_OUT_IN|HSHK_EN; // Enable 2 data pipes HID_BD_OUT.Cnt = sizeof(hid_report_out); // Set buffer size HID_BD_OUT.ADR = (byte*)&hid_report_out; // Set buffer address HID_BD_OUT.Stat._byte = _USIE | _DAT0 | _DTSEN; // Set status /* * Do not have to init Cnt of IN pipes here. * Reason: Number of bytes to send to the host * varies from one transaction to * another. Cnt should equal the exact * number of bytes to transmit for * a given IN transaction. * This number of bytes will only * be known right before the data is * sent. */ HID_BD_IN.ADR = (byte*)&hid_report_in; // Set buffer address HID_BD_IN.Stat._byte = _UCPU | _DAT1; // Set status } //end HIDInitEP /****************************************************************************** * Function: void HIDTxReport(char *buffer, byte len) * * PreCondition: mHIDTxIsBusy() must return false. * * Value of 'len' must be equal to or smaller than * HID_INT_IN_EP_SIZE * For an interrupt endpoint, the largest buffer size is * 64 bytes. * * Input: buffer : Pointer to the starting location of data bytes * len : Number of bytes to be transferred * * Output: None * * Side Effects: None * * Overview: Use this macro to transfer data located in data memory. * * Remember: mHIDTxIsBusy() must return false before user * can call this function. * Unexpected behavior will occur if this function is called * when mHIDTxIsBusy() == 0 * * Typical Usage: * if(!mHIDTxIsBusy()) * HIDTxReport(buffer, 3); * * Note: None *****************************************************************************/ void HIDTxReport(byte *buffer, byte len) { byte i; /* * Value of len should be equal to or smaller than HID_INT_IN_EP_SIZE. * This check forces the value of len to meet the precondition. */ if(len > HID_INT_IN_EP_SIZE) len = HID_INT_IN_EP_SIZE; /* * Copy data from user's buffer to dual-ram buffer */ for(i=0; i HID_BD_OUT.Cnt) len = HID_BD_OUT.Cnt; /* * Copy data from dual-ram buffer to user's buffer */ for(hid_rpt_rx_len=0; hid_rpt_rx_len < len; hid_rpt_rx_len++) { ClrWdt(); *buffer++ = hid_report_out[hid_rpt_rx_len]; } /* * Prepare dual-ram buffer for next OUT transaction */ HID_BD_OUT.Cnt = sizeof(hid_report_out); mUSBBufferReady(HID_BD_OUT); } //end if return hid_rpt_rx_len; } //end HIDRxReport #endif //def USB_USE_HID #endif // 18f4550 static char dummy; /** EOF hid.c ***************************************************************/