Hello,
I am hoping to setup my LPC2468 to act as a USB Host and to work with the HID Class. I am wondering if anyone has suggestions on example code or reading material?
I have gotten Keil's USB HID Client working on my hardware, and have been looking through the Host Lite Mass Storage example provided by Keil/Nxp/OnChip.
Any suggestions would be greatly appreciated.
Thank you, Eric
Hello Eric,
I asked Keil support a while ago the very same question. They said that they have indeed plans to implement the host-side software, but did not say "it will happen within x months/releases". The best thing to do, I think, is to use an external hardware to get the job done. See www.ftdichip.com/FTProducts.htm www.ftdichip.com/FTProducts.htm or www.8052.com/.../168057 etc.
Is the target HID device a specific one? Or, do you want to accept any HID devices?
NXP Host Lite example provides enough functions to enumerate any device. Also, functions for control/bulk/interrupt transfer are available.
For a specific HID device, these functions accomplish the work. But for any HID device, you have to make up a parser of HID report descriptor.
Tsuneo
Tsuneo,
Thank you for your reply -- I'd like to follow your suggestion of getting NXP Host Lite to work for my purposes.
The device I am connecting is specific, in fact it is another LPC2468 running a modified version of Keil's HID Client example. This device has an interrupt IN endpoint and an interrupt OUT endpoint (both endpoint 1) that I would like to use for transferring the data. The IN report and OUT report size are each 64 bytes (and I do not need a feature report). The end point descriptors request to be polled every 8ms.
Is there any chance you can give me some guidance on modifying NXP Host Lite to communicate with this device? It seems like the main task is to add the support of interrupt transfers - as it looks like Host Lite is setup only for Control and Bulk transfers.
I realize that it may be too much for me to ask you to tell me literally what to modify in Host Lite, but maybe you could suggest something of a check list of items that I must add/modify? (Certainly, if you feel like typing in some literal changes, I would appreciate that - whichever is more practical for you)
A couple questions: 1) For the Interrupt transfers, do I have to set up a timer to that asks for an IN report every 8ms -- or is this something that I can configure the Host Interface to do automatically?
2) Is the polling interval a hard and fast rule, or is it more of a suggestion? (ie, if the device requests to be polled every 8 ms, but I find this to be too big of a performance drag on the host, can I decide to poll it every 16 ms?)
Thank you for any guidance you have the time to give!
-----------------------------------------
Tamir, I am glad to hear that you have put in a request to Keil asking for more USB Host examples.
-Eric
Ah, NXP host lite doesn't support interrupt and isoc transfer fully. But the handling of interrupt is almost same as bulk, except for its scheduling. You'll easily add interrupt transfer support to host lite.
OHCI spec The host controller (HC) on LPC2468 follows OHCI spec. The spec is downloaded from the link on USB.org www.usb.org/.../
I found many bugs on the original OHCI spec, which have been left unrevised so long. This Renesas app note includes the OHCI spec, in which most of bugs are revised. I recommend you to refer both documents side by side.
SH7727 USB Host Module Application Note documentation.renesas.com/.../rej05b0015_sh7727.pdf Section 2, Overview of the Open Host Controller Interface (OpenHCI) Specification
Scheduling of interrupt transfer The polling interval of interrupt transfer is fixed on OHCI; 1, 2, 4, 8, 16 and 32 ms. Your host firmware selects one of interval from this series, so that the interval is less than and nearest to the bInterval field of the target endpoint. This limitation comes from the structure of OHCI HC; 32 members of periodic table (HccaInterruptTable).
These chapters on the OHCI spec explains the way how the HC handles periodic (interrupt and isoc) using this list. 3.3.2 Data Structures 4.4.2.1 HccaInterruptTable
For an IN interrupt endpoint of 8 ms interval on the host lite, 1) Firmware reserves an HCED (EDIntIn) and HCTD structures on the memory. 2) Fill EDIntIn structure just after enumeration, according to the endpoint descriptor of the target device. Link above HCTD to EDIntIn. 3) Insert the pointer to EDIntIn into hcca->IntTable[] at the index of 0, 8, 16, 24 4) Set HcPeriodicStart to 0x2A2F 5) Set HcControl.PeriodicListEnable bit
For another OUT interrupt endpoint, another HCED and HCTD structures are reserved and initialized. a) you may append this ED to EDIntIn.Next. This results the OUT transaction is scheduled just after the IN transaction. OR b) you may insert the schedule to new series on the hcca->IntTable[], for example, index of 1, 9, 17, 25
The rest of transaction handling is almost same as bulk one.
HID host driver always polls the interrupt IN endpoint. You have to recover the interrupt TD immediately after its completion, for next poll. On the other hand, interrupt OUT endpoint is used just on demand from host application. sKip bit of HCED.Control enables the transaction without changing the HCED/HCTD structures so much.
Thank you so much! This is really great.
In above post, I said that the English version of "SH7727 USB Host Module Application Note" includes revised OHCI spec. But it is wrong.
The revised OHCI spec is included just in Japanese-translated version of the appnote, not in English version.
Japanese version of above appnote documentation.renesas.com/.../rjj05b0015_sh7727.pdf
Sorry for my mistake.
I hope Renesas reflects the revision to the English version, too, for the benefit of us all.
Your advice has been great. I have things up and running with Interrupt transfers.
However, I am noticing a strange problem that occasionally occurs. My interrupt IN endpoint stops working, but my interrupt OUT endpoint continues to operate. What I mean by not working, is that the host controller stops servicing the endpoint. The IN endpoint HALT bit and SKIP bit are both not set. TailTd != HeadTd, and yet the transfer descriptor is not serviced. Meanwhile, every time I attached a TD onto the OUT endpoint, it is immediately serviced. Is there a control register or bit somewhere that could cause this problem?
Here are the register values for my IN endpoint (taken in debug mode when the IN endpoint stopped being serviced):
Control = 0x00401081 TailTd = 0x7fd00160 HeadTd = 0x7fd00150 Next = 0
Register values for the TD being pointed to by HeadTd (taken in debug mode when the IN endpoint stopped being serviced):
Control = 0x00100000 CurrBufPtr = 0x7fd00400 Next = 0x7fd00160 BufEnd = 0x7fd0043f
Also, I have verified that the Interrupt Table in the Hcca is correct:
IntTable[0] = &ED_IN IntTable[1] = &ED_OUT IntTable[8] = &ED_IN IntTable[9] = &ED_OUT IntTable[16] = &ED_IN IntTable[17] = &ED_OUT IntTable[24] = &ED_IN IntTable[25] = &ED_OUT
This problem seems to happen when I disconnect the USB cable during when a transfer is in progress. When I reconnect the cable, if the problem is going to happen, the IN endpoint will work for a few TDs and then stop. Once the problem has happened, it doesn't matter if I disconnect and reconnect the cable -- the problem will occur again. Furthermore, if I power-cycle the USB host, the problem does not go away. HOWEVER, if I power-cycle the client, the problem does go away.
Both the client and the host are running on an LPC2468.
Any thoughts would be greatly appreciated!
Thanks, Eric
Ah, okay, so I determined the problem: my client wasn't sending data (oops!). But this raises an interesting question:
My understanding of the USB OHCI spec is that regardless of if a periodic (interrupt) IN endpoint receives data, it's TD will be processed, declared completed and placed on the done head. (ie, my understanding was that as soon as the Host Controller gets to servicing the periodic IN endpoint, it attempts a read from the USB client, and then regardless of whether or not the client had data to send, it would retire the TD to the Hcca->Done list).
However, what appears to be happening is that the Host Controller does not decide retire the TD to the Hcca->Done list until some data actually comes in. So, since my USB client had no data to send, it appears that the IN TD was not being placed on the Hcca->Done list.
Is this the way the OCHI USB HC is supposed to behave?
try key in
OpenHCI-HIDSampleCo
in the Google Search, you can down load my free sample code "OpenHCI-HIDSampleCode.zip".
S. K. Lin