Author Topic: HID class on USB  (Read 13075 times)

Offline neil

  • Sr. Member
  • ****
  • Posts: 438
    • View Profile
HID class on USB
« on: November 01, 2015, 07:32:07 PM »
Hi Mark
   Finally I will be starting soon to hopefully use the USB HID. I found a small library that I can use on Visual Studio within the Windows platform. Looking at your previous post (a while back), I see you carried out mouse buttons simulation, who I assume the Windows HID will pick it up as mouse buttons. The library I have will read and send data to the USB port, does your code allow to read and send data ? If so how is this done?

Thanks in advance


regards

Neil

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: HID class on USB
« Reply #1 on: November 01, 2015, 07:58:28 PM »
Hi Neil

HID mouse uses an IN endpoint and the PC host polls it to receive movement and key press information (8 bytes).
The PC host can send a class command to control a few outputs on the mouse.
Therefore I don't know whether HID mouse is suitable generally.

HID keyboard is very similar in that the the PC host also polls for key strokes and can control some outputs (like CAPS lock LED). Again I don't know whether this is generally suitable.

More general and flexible if possibly USE_USB_HID_RAW which allows 64 byte blocks of data to be transferred in both directions.
I have implemented this so that it can be tested with the Teensy example application explained/found here: https://www.pjrc.com/teensy/rawhid.html
I also found a video of it at https://www.youtube.com/watch?v=iMuNbAv61OA (although 95% is how to get it working on Linix - right at the end it shows it operating).

It alows 64 byte blocks in both directions so can handle 64kBye/s to the PC host and higher from the PC host.

The implementation just echoes the data that the PC host sends back to it but this can easily be used as basis for communication between PC and application once commands are defined and handled. Since HID RAW doesn't need any driver it is also practical as base for PC applications.

Regards

Mark



Offline neil

  • Sr. Member
  • ****
  • Posts: 438
    • View Profile
Re: HID class on USB
« Reply #2 on: November 01, 2015, 09:01:23 PM »
Hi Mark
  Thanks for the reply.  Does the latest uTasker have  USE_USB_HID_RAW included?  And does it currently simply echo what it receives from a PC app at the moment?

Thanks again


Regards
Neil

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: HID class on USB
« Reply #3 on: November 01, 2015, 11:34:08 PM »
Neil

USE_USB_HID_RAW is included in the Kinetis developer's version from 14.9.2015.

It configures the USB interface correspondingly (based on the descriptor in usb_hid-raw_descriptors.h)

Code: [Select]
    if (USBPortID_HID_raw != NO_ID_ALLOCATED) {
    #if HID_RAW_TX_SIZE > HID_RAW_RX_SIZE
        static unsigned char ucRawData[HID_RAW_TX_SIZE];                 // static reception buffer
    #else
        static unsigned char ucRawData[HID_RAW_RX_SIZE];                 // static reception buffer
    #endif
        if (fnRead(USBPortID_HID_raw, ucRawData, HID_RAW_RX_SIZE) == HID_RAW_RX_SIZE) {
            fnWrite(USBPortID_HID_raw, ucRawData, HID_RAW_RX_SIZE);      // send back
        }
    }

As you can see, it looks like a serial interface to the application and here it reads a received packet (generally 64 bytes) and echoes it back.
It is however possible to send data at any time.

Regards

Mark

Offline neil

  • Sr. Member
  • ****
  • Posts: 438
    • View Profile
Re: HID class on USB
« Reply #4 on: November 02, 2015, 03:05:39 PM »
Hi Mark,
  As I am using the 52259 processor, can you please email me the required files I need to use this feature? And is it just a matter of enabling the USE_USB_HID_RAW?

Many Thanks

Regards
Neil

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: HID class on USB
« Reply #5 on: November 03, 2015, 01:42:34 AM »
Hi Neil

I have emailed you a link to my latest M522xx working version which has RAW HID, as well as composite support.
In the config.h you can find a set of USB configuration defines.

Regards

Mark

Offline neil

  • Sr. Member
  • ****
  • Posts: 438
    • View Profile
Re: HID class on USB
« Reply #6 on: November 06, 2015, 06:33:22 PM »
Hi Neil

HID mouse uses an IN endpoint and the PC host polls it to receive movement and key press information (8 bytes).
The PC host can send a class command to control a few outputs on the mouse.
Therefore I don't know whether HID mouse is suitable generally.

HID keyboard is very similar in that the the PC host also polls for key strokes and can control some outputs (like CAPS lock LED). Again I don't know whether this is generally suitable.

More general and flexible if possibly USE_USB_HID_RAW which allows 64 byte blocks of data to be transferred in both directions.
I have implemented this so that it can be tested with the Teensy example application explained/found here: https://www.pjrc.com/teensy/rawhid.html
I also found a video of it at https://www.youtube.com/watch?v=iMuNbAv61OA (although 95% is how to get it working on Linix - right at the end it shows it operating).

It alows 64 byte blocks in both directions so can handle 64kBye/s to the PC host and higher from the PC host.

The implementation just echoes the data that the PC host sends back to it but this can easily be used as basis for communication between PC and application once commands are defined and handled. Since HID RAW doesn't need any driver it is also practical as base for PC applications.

Regards

Mark

Hi Mark,
  I used the small console application above , and it worked when I press a key , but nothing was returned from utasker. I placed a breakpoint at where the information should be echoed, so I know it received the information ok.

Regards
Neil

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: HID class on USB
« Reply #7 on: November 07, 2015, 01:58:11 AM »
Neil

Have I understood correctly that the USB task is receiving the data in this code?

        if (fnRead(USBPortID_HID_raw, ucRawData, HID_RAW_RX_SIZE) == HID_RAW_RX_SIZE) {
            fnWrite(USBPortID_HID_raw, ucRawData, HID_RAW_RX_SIZE);      // send back
        }

That is, fnRead() is called and it returns 64 (size of each data block). Then fnWrite() is called?
Is the data in ucRawData[] as expected (probably a single key press value plus 63 x 0x00)?
What value does fnWrite() return?

Regards

Mark


Offline neil

  • Sr. Member
  • ****
  • Posts: 438
    • View Profile
Re: HID class on USB
« Reply #8 on: November 07, 2015, 08:59:04 AM »
Hi Mark,
  Thats correct, the task is receiving the code, and fnWrite is called which returns 64. The ucRawData is as expected after with 1 character and rest filled with zeros. But nothing is displayed on the console application (in  https://www.pjrc.com/teensy/rawhid.html link).

Also, a few questions, if you dont mind:

  1. The receive/transmit block to and from utasker  is always 64 bytes in length , even if 1 character is sent/received?

  2. If No 2, above is true, is there a way of known within the 64 bytes what was the number actually transmitted from the pc app? So if the app sent 4 bytes of data (non ascii) is there a way of known within the app if it was 4 bytes sent? Cant check for the zeros as this value can be sent too.

  3. If I place a break point write after the write line, I get an error in the console application saying the device is offline. Why is this?

Many Thanks
Neil
« Last Edit: November 07, 2015, 01:35:02 PM by neil »

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: HID class on USB
« Reply #9 on: November 09, 2015, 03:31:00 PM »
Neil

I just spent the morning investigating this on a M52259EVB. The EVB does respond by echoing back 64 bytes (seen on USB analyser) but the test tool is not displaying anything. After some analysis I have identified why not - it is because there is no zero data frame send after the the 64 byte frame is acknowledged. Unfortunately the reason for this is that this operation needs to be updated slightly in the USB generic driver (where it is not supported as I have now seen in the older M522xx version).
I'll need to invest about a day of work to ensure that the original generic driver part is updated accordingly so that it is still compatible with oder projects but supports the option USB_TERMINATING_ENDPOINT on the bulk endpoint.

The fact that 64 bytes are always send is due to the test program. I don't think that 64 byte are actually needed in each case.

You'll need to give a a couple of days to complete the work and I'll contact you as soon as I have confirmed that it is operations.

2. I think that you may need to add a counter to the content to know the length of data that is actually valid if less that 64 bytes can't be sent (although I still think that it is just teh test program that works like this).

3. I think that the test program is waiting for something and fails if the debugger stops the code.

regards

Mark


Offline neil

  • Sr. Member
  • ****
  • Posts: 438
    • View Profile
Re: HID class on USB
« Reply #10 on: November 09, 2015, 03:39:14 PM »
Hi Mark,
  Thanks for the update, and your replies to my questions, cheers.  I look forward to findings in the next few days.

Regards
Neil

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: HID class on USB
« Reply #11 on: November 09, 2015, 10:29:11 PM »
Neil

After a few more hours, this time also comparing with Kinetis versions, I no longer think that there is a problem in the M522xx version for RAW HID mode.
It seems more that sending back 64 byte echoes to the PC test program causes the PC software to immediately reject further operation.

I also loaded the Teensy embedded code and compared that. It sends regularly frames to the PC but with a certain content (alwas starting with 0xabcd, with a counter at the end and some data content). The frames are accepted and displayed.

Therefore I think that the test software is not generally a suitable method to use for more general development - it doesn't display all data that it receives (supposedly looking for certain content that must match). After receiving data that it doesn't expect it looks to then fail by never sending any more IN tokens.

After various attempts I think that it is also not accepting data from 'foreign' devices - the original software uses a composite driver (it has its own driver) and my feeling is that it won't work without this. Even if I made tout device look like the orignal HW by using the same PID/VID, product name, erial number etc. so that enumeration is identical, and sending identical data, it just rejects it.

Unfortunately I don't remember the details when I initially tested; possibly I was satisfied that the USB data was correct. However I have spend a complete day of looking into this and don't in fact see anything wrong with either Kinetis or Coldfire operation (there was no missing zero data ACK that I first suspected). I do see the test application resetting the device once it received something that it is seemingly not happy with (even if the content is identical to a content that the Teensy sends).

I would like to suggest that you see what alternative possibilities you have for the PC side so that this can be controlled and it is known what it actually does and what it expects. Continuing with this for real work will require a complete reverse engineering and use of the custom driver, which would require several more days of effort and doesn't seem meaningful for using standard RAW HID (which doesn't need a driver - it is the PC test program that is seemingly not accepting standard operation that doesn't use its own driver).

Regards

Mark


Offline neil

  • Sr. Member
  • ****
  • Posts: 438
    • View Profile
Re: HID class on USB
« Reply #12 on: November 09, 2015, 11:39:26 PM »
Hi Mark
  I managed to find the issue, I increased the define HID_RAW_TX_SIZE from 32 to 64, and the demo works, I now get the characters displayed.  I found another Windows application , where it displays the size of the TX buffer of the device , and it has value of 32. The documentation mentions the size of the transmitted data has to be length HID_RAW_TX_SIZE. so when I sent 32 bytes the info was displayed on the Windows app. So when I increased it to 64 bytes , the demo app you mentioned worked. So it looks like the PC will always send 64 bytes of data , regardless the size to send. And utasker has to send back HID_RAW_TX_SIZE size of buffer.

regards
Neil

Offline neil

  • Sr. Member
  • ****
  • Posts: 438
    • View Profile
Re: HID class on USB
« Reply #13 on: November 10, 2015, 11:37:16 PM »
Hi Mark
    is there a way to detect when an application (a Windows app) connects, and disconnects  to and from utasker?

regards
Neil

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: HID class on USB
« Reply #14 on: November 11, 2015, 02:36:58 AM »
Neil

It may be wise to define some messages messages that can be passed between the PC application and the device. Thsi way you can be sure that the device known when the application is started - also you could use a keep-alive message from the application so that your device could also detect if the application stops/crashes (since the keep-alive woudl be missing for longer than expected).

Regards

Mark