GDay to all,
once again I return with an HID Question
Recently I implemented a lowlewel protocol based upon HID in order to transport more data. In general, it uses packet counters to embed larger data within reports and the usual sender/receiver states (send data, busy, receiving data etc)
It worked very well when it was based on the USBHID example. Then we integrated it into our RL-ARM based application, but this did not work and threw exceptions all the time. My USB and RL-ARM understanding is not deep enough to see why - so I went to use the RTX_HID sample as a new basis.
Our application is based on LPC17x and we use an OS-tick of 1000 -> should result in 1 ms slices for the scheduler
After integration in the target, it is still working but with totally different timing and response behaviour. Very slow and many duplicated reports - quite close to unusable.
After that discovery - I inspected the priorities being assigned to the USB tasks (Default USB is 3, and the endpoint tasks 2) and found them to be way too low, so I raised them above all my own tasks. But no change in behaviour
Put together, the main symptom is: Hosts says: Do something Target should immediately start with the job and should return BUSY in an instant
Using plain HID, it worked as expected, using RTX_HID it does not
If I consider the time slice and the high prios for USB and the endpoint tasks I assigned (above all others) I simply don't understand why it takes from 5-30 msec to see a change on the input reports (when it was 1 ms on the other sample - reliably) I could live with 2-3 reports, but not with 30
1) Why can't I use the original USB code? I thought all the "code down there" would execute in IRQ anyway ... and my lowlevel protocol could live with that well (as there is a clean layer in between to separate it from the rtx-driven application)
2) Any suggestions what parameters to change in order to speed up the RTX sample ?
many thanks in advance, as usual ULI
addendum:
from time to time, the application crashes with a "fifo full" exception in on of the USB tasks (fifo enlargment did not help)
You are likely working on these KEIL examples. C:\Keil\ARM\Boards\Keil\MCB1700\USBHID C:\Keil\ARM\Boards\Keil\MCB1700\RL\USB\RTX_HID
> After integration in the target, it is still working but with totally different timing and response behaviour. Very slow and many duplicated reports - quite close to unusable.
Sound like you didn't change the communication model yet. I believe it is the source of the problem.
These KEIL HID examples always put input reports repeatedly, regardless of host query over Output report. But you want to communicate in tight query-reply pair.
We have already discussed on this modification for LPC2141 RTX_HID on this topic. Apply this modification to the LPC17xx example, first. Fortunately, the KEIL's stack implementation hides the difference of the MCUs well. http://www.keil.com/forum/17770/
Tsuneo
Hi Tsuneo,
and thanks as usual
in this particular case, the duplicated reports are not the problem. In order to achieve biggest throughput possible, we chose a different approach. this is NOT a typical request/reply scenario. In our application, host msg usually is between 100 and 300 bytes, while the reply can become much larger. So, when a message to the host is ready to be sent, the device always sends a part of the message upon every GetReport, virtually endlessly. The host puts the fragements that were embedded in reports together again to the entire message. That way, we came very close to the theoretical maximum data transfer rate. (and, as already said in OP, it worked super without RL-ARM)
But, and this is the interesting point, why does it take so long for the target to change states? I believe this is not a particular USB problem but a combination of USB with RL-ARM.
I see your point that I am able to just not send any answer reports, but this is not our problem here.
If the RL time slice is set to 1 ms, the prios are set up properly (at least I do think so) why does it then take sooo long for the target to acknowledge commands? If we see 30 reports there (and we can live very well with duplicated ones per design of our protocol) there must be approx 30 ms until the state change takes place.
The other option would be to use the original HID sample in our RL-ARM environment, but as I said, off the shelf it is NOT working.
kind regards UB
> So, when a message to the host is ready to be sent, the device always sends a part of the message upon every GetReport, virtually endlessly.
Is it a GetReport Request or report transfer over HID interrupt IN endpoint?
The timing of GetReport Request is given by the host, not by the device side. It sounds like transfer over interrupt IN EP is better, if the device determines the start timing of report transfer.
We added the code where the original GetReport in the Keil-sample was - without bothering about the style - and the non RL-ARM version worked very well.
> We added the code where the original GetReport in the Keil-sample was
I don't see any GetReport() function on the original code, neither non RL nor RL. Maybe you mean GetInReport() function?
> I simply don't understand why it takes from 5-30 msec to see a change on the input reports (when it was 1 ms on the other sample - reliably)
What is the bInterval value of the interrupt IN endpoint? The original examples set it to 32ms
C:\Keil\ARM\Boards\Keil\MCB1700\RL\USB\RTX_HID\usbdesc.c /* USB Configuration Descriptor */ /* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor) */ const U8 USB_ConfigDescriptor[] = { ... ... /* Endpoint, HID Interrupt In */ USB_ENDPOINT_DESC_SIZE, /* bLength */ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ USB_ENDPOINT_IN(1), /* bEndpointAddress */ USB_ENDPOINT_TYPE_INTERRUPT, /* bmAttributes */ WBVAL(0x0004), /* wMaxPacketSize */ 0x20, /* 32ms */ /* bInterval */ <---------- /* Terminator */ 0 /* bLength */ };
SORRY - a dumb typo!
GetInReport is correct. And thank you Tsuneo for thinking of everything !! But in this particular case, no - bInterval - was already set to 1 ms.
the fact that really confuses me is the general behaviour in terms of timing. Using the RL - less sample brought us _VERY_ close to 64kB/s .. and everything was fine. Now, using the OS based sample, the trhoughput is gone as some aspects of the task-switching cause these problems (at least I think so)
thank you as usual Uli