LPC4357 USB HID OUT endpoint problem

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

LPC4357 USB HID OUT endpoint problem

1,391 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by GTA on Tue Jul 30 14:36:27 MST 2013
Hello All,

I am using an LPC4357 Embedded Artists dev board and LPCOpen to create a USB HID device with one interrupt IN and one OUT endpoint (endpoints 1 and 2). The HID device enumerates OK and I am able to correctly send info device->host via the IN endpoint. However, despite configuring the OUT endpoint it does not seem to register any data being sent to it from the host.

I saw this in HIDClassDevice.h for USB_ClassInfo_HID_Device_t:

@note Due to technical limitations, the HID device class driver does not utilize a separate OUT
 *        endpoint for host->device communications. Instead, the host->device data (if any) is sent to
 *        the device via the control endpoint.


Before going into full detail on low level USB controller debugging, what are those "technical limitations"? Is there something fundamental preventing me from implementing a HID interrupt OUT endpoint? Or is it just that support for it is not yet implemented in the HID class stack (or not considered important enough)?

Thanks,
Labels (1)
0 Kudos
5 Replies

1,129 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Tsuneo on Tue Oct 29 07:19:55 MST 2013

Quote:
a) EP0Data.Count appears to be at a higher level than HID_SetReport provides access to.


At the entry of "case USB_EVT_SETUP:"
EP0Data.Count and EP0Data.pData are invalid.
You have to assign EP0Data.Count to the number to be transferred,
EP0Data.pData to the buffer to be transferred.

case USB_EVT_SETUP:
pCtrl->EP0Data.Count = setup.wLength;
pCtrl->EP0Data.pData = (uint8_t*)tmpStpBuf;


Quote:
b) SetupPacket.wLength report size to HID_SetReport appears to be at a higher level than HID_SetReport provides access to.


What kind of PC OS are you working on?
Did you compare the SetupPacket values with those on sniffer or hardware bus analyzer?


Quote:
c) I made the presumption that HID_Ep_Hdlr is the interrupt OUT endpoint, consistent with GTA's report.


Hah?
Do you insist that you were talking about HID interrupt OUT endpoint, in your first and above second post?
All of these terms in your post, CP0Data.Count, SetupPacket.wLength, bMaxPacketSize0, suggest Control transfer on the EP0. These terms are never used in interrupt endpoint handling.


If you want better code, see these posts.
http://www.lpcware.com/content/forum/lpc1347-control-packets-64bytes#comment-1132926
and
http://www.lpcware.com/content/forum/readep-does-not-work-custom-usb-class#comment-1131034

Tsuneo
0 Kudos

1,129 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by mathseng on Sun Oct 27 01:59:49 MST 2013
Hi Tsuneo,
With the code I have, I am unable to replicate the values you report, for the LPC1347 (testing with USB_MEM_BASE in either RamUsb2 or RamPeriph2).
I am hampered by only being exposed to USB and LPC since Aug'13, and I am relying upon the LPC docs and the LPC examples (ROM_USB_hid in NXP_LPC1347_2012_02_22.zip).

I get good results for HID USB ROM-based operations for multi-packet report sizes when using the default RamLoc8 segment for USB_MEM_BASE, but am missing some step for the other RAM segments (pBuffer parameter to HID_SetReport points to USB_MEM_BASE + 0x01ac, which does not appear correct for RamUsb2 and RamPeriph2, where the 64 byte buffer data is observed to be at USB_MEM_BASE + 0x0200)
Note: As per one of your posts, I set the HID_SetReport buffer of size HID_OUTPUT_REPORT_BYTES when the length passed is 0, and this works for me when USB_MEM_BASE is in RamLoc8.

Summary
a) EP0Data.Count appears to be at a higher level than HID_SetReport provides access to.
b) SetupPacket.wLength report size to HID_SetReport appears to be at a higher level than  HID_SetReport provides access to.
However, I observed that:
+ the data in the USB_MEM_BASE segment 64 byte buffer at the call to HID_SetReport is the LAST packet of the USB transmission.
+ when a large buffer is provided (set *pBuffer = largeBuffer (on call when length==0) AND USB_MEM_BASE is in RamLoc8, the correct number of bytes is transferred, but nothing appears in largeBuffer when USB_MEM_BASE is in other RAM segments.

c) I made the presumption that HID_Ep_Hdlr is the interrupt OUT endpoint, consistent with GTA's report. With my code, I am successfully receiving packets of size < packetSize, size = packetSize * n (n = 1..n), and size = packetSize*n + x (where x = 1..packetSIze-1)

If you have published code which I can examine, I would appreciate the link to the webpage, so that I can create better software in my projects.

Bill

0 Kudos

1,129 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Tsuneo on Thu Oct 24 21:56:46 MST 2013
mathseng,

Firstly, your post has nothing to do with the original GTA's
- GTA told on the HID interrupt OUT endpoint of LPC4357, working on LPCOpen.
- You are talking about the default endpoint of LPC1347 over the ROM driver.


Quote:
+ the number of bytes remaining to transfer is in CP0Data.Count, showing 0 after the last packet.
+ the report size is in SetupPacket.wLength.
+ when the last packet sent is of length bMaxPacketSize0, a ZLP is received.

None of the above appears true for my testing



On my test on LPC1347 ROM driver,
a) CP0Data.Count shows correctly zero after the last packet for HID Set_Report and Get_Report.

b) Also, the report size was correctly in SetupPacket.wLength
If it weren't, the host should be significantly out of spec. At least, you may rely on wLength in major OS (Windows, Linux and MacOSX)

c) By the USB spec, additional ZLP isn't sent when the last packet sent is of length bMaxPacketSize0, for the DATA stage of control transfer. You are mixing up GTA's interrupt OUT endpoint with control transfer.

We have discussed on custom EP0 handler for control transfer on LPC1347 ROM driver, here.
http://www.lpcware.com/content/forum/lpc1347-control-packets-64bytes

Tsuneo
0 Kudos

1,129 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by mathseng on Thu Oct 24 05:44:16 MST 2013
This is what I found for the LPC1347.
Doco seems to indicate that:
+ the number of bytes remaining to transfer is in CP0Data.Count, showing 0 after the last packet.
+ the report size is in SetupPacket.wLength.
+ when the last packet sent is of length bMaxPacketSize0, a ZLP is received.

None of the above appears true for my testing - it appears that other code is necessary to make this work for the sample code.
When the input and output reports are of different sizes, this does not seem to be true for wLength.

To allow me to use a report size equal to the max packet size, I tried this kludge, which appears to work, where I use a 2 counters to manage my transfers. I needed to know that the buffer is being used, and also when the transfer is complete, hence:
uint16_t bytesOut = 0;    // the number of bytes received during THIS  ReadEP. For the last packet in the stream, this will be either  bMaxPacketSize0 or a smaller value.
uint16_t bytesTot;          // the total number of bytes, in a sequence of packets received.

When the last packet is bMaxPacketSize0, then the number of bytes in total received is the test for completion.
I suppose that a test for number of bytes >= report size could be also valid.

I use a struct containing 2 flags and the buffer for the transfer.
The dirty flag indicates that a transfer is in progress, while the full flag allows the consumer to take the data.


<code>
case USB_EVT_OUT:
  // if start of nPacket transfer, reset pointer
   if (bytesOut < bMaxPacketSize0 || bytesTot >= HID_OUTPUT_REPORT_BYTES)
       bytesTot = 0;

  // do the read and update buffer stuff.
  bytesOut = pUsbApi->hw->ReadEP(hUsb, pHidCtrl->epout_adr, &(cBuf->buf[bytesTot]));

  // set the flags for consumer
  bytesTot += bytesOut;
  cBuf->isFull = (bytesOut < bMaxPacketSize0 || bytesTot >= HID_OUTPUT_REPORT_BYTES);
  cBuf->isDirty = true;
  break;
</code>

Bill
0 Kudos

1,129 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by GTA on Wed Jul 31 15:55:13 MST 2013
Hello, it's me again.

After a number of hours of reading the LPC4357 UM on USB0 and analyzing the LPCOpen LPCUSBLib code I have now gotten the HID interrupt OUT EP to work. In my case I sent an OUT report that was == maxPacketSize configured for the EP. The result was the device controller did not regard the transfer as complete, despite me trying to set ZeroLengthTermination = 0 for the EP. As it seems Win HID drivers do not send ZLP (http://www.microchip.com/forums/m485841-print.aspx), it would not work.

Instead I reconfigured the HID EP descriptor and device EP config to have maxPacketSize > largest OUT report. That worked and the report was delivered to my LPC4357 test app.

I do however still not know what the "technical limitations" are :S
0 Kudos