View previous topic :: View next topic |
Author |
Message |
steav
Joined: 22 Nov 2011 Posts: 10
|
(Solved) USB_HID_REQUEST_SET_REPORT implementation |
Posted: Wed Nov 05, 2014 3:36 am |
|
|
Hi!
I'm using CCS PCD v5.030 with PIC24FJ256DA210 (MCP development board).
The CCS HID USB driver is working fine, but I can't get the HID get_report/set_report feature to work.
USB.h - CCS already defined these codes, but didn't implement it.
Code: |
//HID Class Setup bRequest Codes
#define USB_HID_REQUEST_GET_REPORT 0x01
#define USB_HID_REQUEST_GET_IDLE 0x02
#define USB_HID_REQUEST_GET_PROTOCOL 0x03
#define USB_HID_REQUEST_SET_REPORT 0x09
#define USB_HID_REQUEST_SET_IDLE 0x0A
#define USB_HID_REQUEST_SET_PROTOCOL 0x0B
|
USB.c - The function which handles these codes is already defined
Code: |
/**************************************************************
/* usb_isr_tkn_setup_ClassInterface()
/*
/* Input: usb_ep0_rx_buffer[1] == bRequest
/*
/* Summary: bmRequestType told us it was a Class request. The only Class this drivers supports is HID.
/* bRequest says which request. Only certain requests are valid,
/* if a non-valid request was made then return with an Wrong-Statue (IDLE)
/*
/* Part of usb_isr_tok_setup_dne()
/* Only compiled if HID_DEVICE is TRUE
/***************************************************************/
#IF USB_HID_DEVICE
void usb_isr_tkn_setup_ClassInterface(void) {
switch(usb_ep0_rx_buffer[1]) {
#IF USB_HID_BOOT_PROTOCOL
case USB_HID_REQUEST_GET_PROTOCOL: //03
debug_usb(debug_putc,"GP");
usb_ep0_tx_buffer[0]=hid_protocol[usb_ep0_rx_buffer[4]];
usb_request_send_response(1);
break;
#ENDIF
#IF USB_HID_BOOT_PROTOCOL
case USB_HID_REQUEST_SET_PROTOCOL: //0b
debug_usb(debug_putc,"SP");
hid_protocol[usb_ep0_rx_buffer[4]]=usb_ep0_rx_buffer[2];
usb_put_0len_0(); //send 0len packet69
break;
#ENDIF
#IF USB_HID_IDLE
case USB_HID_REQUEST_SET_IDLE: //0a
#error TODO: if you want to support SET_IDLE, add code here
#ENDIF
#IF USB_HID_IDLE
case USB_HID_REQUEST_GET_IDLE: //02
#error TODO: if you want to support GET_IDLE, add code here
#ENDIF
case USB_HID_REQUEST_SET_REPORT:
output_high(P_GREEN);
// Do something here
break;
case USB_HID_REQUEST_GET_REPORT:
// Do something here
break;
default:
usb_request_stall();
break;
}
}
#ENDIF
|
I added the USB_HID_REQUEST_SET_REPORT and USB_HID_REQUEST_GET_REPORT.
In the moment I write a packet using HIDAPI (http://www.signal11.us/oss/hidapi/), the green led lights up
Code: |
unsigned char buf[65];
res = hid_write(handle, buf, 65);
|
I also set all HID buffer sizes to 64:
Code: |
#define USB_MAX_EP0_PACKET_LENGTH 64
#define USB_CONFIG_HID_RX_SIZE 64
#define USB_CONFIG_HID_TX_SIZE 64
|
Now I just want to receive USB_HID_REQUEST_SET_REPORT 64byte packets of custom data from HIDAPI, using usb_get_packet().
The strange thing is, if I use usb_kbhit() and usb_get_packet(), to check if there are some new packets available, I only get packets from the operation system asking the PIC e.g. for device descriptors, and since I receive them in my main application instead of the CCS HID driver, the USB device is freezing.
Thanks a lot!
Last edited by steav on Wed Nov 05, 2014 6:15 am; edited 1 time in total |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19545
|
|
Posted: Wed Nov 05, 2014 4:44 am |
|
|
Look at ex_usb_kbmouse2.c
This uses two HID reports one to handle a mouse, and one a keyboard. Note it is just sent as a packet. No fiddling changing the driver.
Then look at the reception of the LED settings.
Beware that unless you must have 64bytes, if you are using a report ID, then it is faster to keep the total packet <=64bytes, including the ID. |
|
|
steav
Joined: 22 Nov 2011 Posts: 10
|
|
Posted: Wed Nov 05, 2014 5:01 am |
|
|
Thank you for your answer!
I do it exactly the same way:
Code: |
void usb_rx_task(void)
{
int8 rx_msg[USB_EP1_RX_SIZE];
if (usb_kbhit(1))
{
usb_get_packet(1, rx_msg, sizeof(rx_msg));
}
}
|
Unfortunately, the usb_kbhit(1) triggers on every incoming USB packet, especially on those which should by handled by the HID driver itself. If I use this code above, my USB Prober App (http://touch-base.com/documentation/USBMacProber.htm) doesn't show the string desc. (manufacturer, serial...) anymore and is freezing while waiting for these reply packets. So I decided to extend the HID driver with the code for the case USB_HID_REQUEST_SET_REPORT. I just don't know how to access the payload of a HID set report request (initiated by HIDAPI) within this switch-case.
I didn't change anything else in the driver but the sizes to 64.
As you mentioned, 32bytes of payload for each HID packet are enough for me. I can change that. |
|
|
steav
Joined: 22 Nov 2011 Posts: 10
|
|
Posted: Wed Nov 05, 2014 6:14 am |
|
|
I found the problem!
The USB driver files where included in incorrect order, overwriting some #define macros. Now it is working as it shound using usb_kbhit(), without the need of adding a USB_HID_REQUEST_SET_REPORT switch-case. |
|
|
VernonAMiller
Joined: 11 Sep 2014 Posts: 25 Location: Contoocook, NH
|
|
Posted: Wed Nov 05, 2014 8:07 am |
|
|
If it's a mistake you think one of us might make, please let us know the correct order so we can not make it
Thanks!
VAM |
|
|
steav
Joined: 22 Nov 2011 Posts: 10
|
|
Posted: Wed Nov 05, 2014 8:18 am |
|
|
The correct order is just to include the USB files in the same way as shown as in the examples and NOT to remove #includes within driver files
In my main application, these are the includes, copied from the PICC drivers folder:
Header includes
Code: |
#include "Driver/USB/usb_desc_hid.h"
#include "Driver/USB/usb.h"
#include "Driver/USB/pic24_usb.h"
|
Source includes
Code: |
#include "Driver/USB/usb.c"
|
|
|
|
VernonAMiller
Joined: 11 Sep 2014 Posts: 25 Location: Contoocook, NH
|
|
Posted: Wed Nov 05, 2014 8:40 am |
|
|
steav wrote: | The correct order is just to include the USB files in the same way as shown as in the examples and NOT to remove #includes within driver files
|
Cool. Thanks!
VAM |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19545
|
|
Posted: Wed Nov 05, 2014 10:01 am |
|
|
Well done, and well done for updating (helps others). |
|
|
|