Generic_HID Firmware for Microchip Full-speed USB Chips Using Microchip MCHPFSUSB Framework v2.3 Jan Axelson www.Lvr.com 12/24/08 V1.4 See generic_hid.c for project history PROJECT DESCRIPTION This firmware is for a generic HID USB device (not a system keyboard or mouse) that does the following: Receives Output reports using interrupt OUT transfers and sends the report data back to the host in Input reports using interrupt IN transfers. Receives Output reports using control transfers (Set_Report request) and sends the report data back to the host in Input reports using control transfers (Get_Report requests.) Receives Feature reports using control transfers (Set_Report request) and sends the report data back to the host in Feature reports using control transfers (Get_Report requests.) A single buffer holds received Feature reports and reports to be sent. The firmware is adapted from Microchip's Mouse example. The project has been tested on the PICDEM™ FS USB DEMONSTRATION BOARD MORE INFORMATION This application, host applications to communicate with the device, and more about USB and HIDs are available from: www.Lvr.com/hidpage.htm HOW TO CREATE THE PROJECT Download and install the Microchip MCHPFSUSB Framework v2.3. Try this location for the Framework: http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=2651¶m=en534494 The installation creates a directory structure under "Microchip Solutions", assuming you use the default directory. The zip file that contains this readme file also contains a project directory for the Generic HID application. The directory is: USB Device - Generic HID Copy this directory as a subdirectory of the Microchip Solutions directory so you end up with: Microchip Solutions\USB Device - Generic HID STACK CHANGES You'll also need to make some additions to three of the USB stack files in Microchip Solutions\Microchip. The changes support some additional HID-specific capabilities and shouldn't affect other Microchip examples. 1. In usb_device.c: Add line 4 (hid_report_feature) in this block: #if defined(USB_USE_HID) volatile unsigned char hid_report_out[HID_INT_OUT_EP_SIZE]; volatile unsigned char hid_report_in[HID_INT_IN_EP_SIZE]; volatile unsigned char hid_report_feature[EP0_BUFF_SIZE]; #endif 2. In usb_device.h: Add line 5 (hid_report_feature) in this block: #if defined(USB_USE_HID) //class specific data buffers extern volatile unsigned char hid_report_out[HID_INT_OUT_EP_SIZE]; extern volatile unsigned char hid_report_in[HID_INT_IN_EP_SIZE]; extern volatile unsigned char hid_report_feature[EP0_BUFF_SIZE]; #endif 3. In usb_function_hid.c: Replace the empty functions HIDGetReportHandler and HIDSetReportHandler with these: /******************************************************************** * Function: void HIDGetReportHandler(void) * * PreCondition: A Setup packet with a HID Get_Report request * has been received. * * Input: None * * Output: None * * Side Effects: None * * Overview: If the HID supports the requested report, provides data * for an Input or Feature report. Otherwise configures * the endpoint to return STALL. * * Note: None *******************************************************************/ void HIDGetReportHandler(void) { inPipes[0].info.bits.busy = 1; inPipes[0].info.Val = USB_INPIPES_RAM | USB_INPIPES_BUSY | USB_INPIPES_INCLUDE_ZERO; if ((SetupPkt.W_Value.byte.HB) == 0x01) { // Input report if (SetupPkt.W_Value.byte.LB == 0x00) { // Report ID = 0 inPipes[0].pSrc.bRam = (BYTE*)&hid_report_in; inPipes[0].wCount.Val = HID_INPUT_REPORT_BYTES; } else { // Stall unsupported report IDs. pBDTEntryIn[0]->STAT.Val = _USIE|_BSTALL; } } else if (SetupPkt.W_Value.byte.HB == 0x03) { // Feature report if (SetupPkt.W_Value.byte.LB == 0x00) { // Report ID = 0 inPipes[0].pSrc.bRam = (BYTE*)&hid_report_feature; inPipes[0].wCount.Val = HID_FEATURE_REPORT_BYTES; } else { // Stall unsupported report IDs. pBDTEntryIn[0]->STAT.Val = _USIE|_BSTALL; } } else { // Stall unsupported report types. pBDTEntryIn[0]->STAT.Val = _USIE|_BSTALL; } }//end HIDGetReportHandler /******************************************************************** * Function: void HIDSetReportHandler(void) * * PreCondition: A Setup packet with a HID Set_Report request * has been received. * * Input: None * * Output: None * * Side Effects: None * * Overview: If the HID supports the report the host is requesting * to send, prepares to receive the report in the * Data stage of the control transfer. * Otherwise the endpoint returns STALL. * * Note: None *******************************************************************/ void HIDSetReportHandler(void) { switch (ReportSupported()) { case 0x02: // Output report { outPipes[0].wCount.Val = SetupPkt.wLength; outPipes[0].pDst.bRam = (BYTE*)OUTPUT_REPORT; outPipes[0].pFunc = SET_REPORT_PFUNC; outPipes[0].info.bits.busy = 1; break; } case 0x03: // Feature report { outPipes[0].wCount.Val = SetupPkt.wLength; outPipes[0].pDst.bRam = (BYTE*)FEATURE_REPORT; outPipes[0].pFunc = SET_REPORT_PFUNC; outPipes[0].info.bits.busy = 1; break; } default: { // The endpoint will return STALL. outPipes[0].info.bits.busy = 0; } } }//end HIDSetReportHandler *** To include the Microchip C18 libraries in the project: 1. Select Project > Build Options > Project 2. In "Show Directories for;", select Include Search Path 3. Click New. 4. Browse to your MCC18\h directory and add it to the Search Path List. 5. Click OK.