<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://community.arm.com/utility/feedstylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>USB HID reports longer than 64 bytes on lpc2141</title><link>https://community.arm.com/developer/tools-software/tools/f/keil-forum/37885/usb-hid-reports-longer-than-64-bytes-on-lpc2141</link><description> 
Hi everyone, 

 
I&amp;#39;m working on a custom system monitoring device and have a
requirement for a USB HID input report longer than 64 bytes. From
what I&amp;#39;ve read, it&amp;#39;s possible to send it as multiple transactions but
I can&amp;#39;t figure out how to make Keil</description><dc:language>en-US</dc:language><generator>Telligent Community 10</generator><item><title>RE: USB HID reports longer than 64 bytes on lpc2141</title><link>https://community.arm.com/thread/135425?ContentTypeID=1</link><pubDate>Fri, 11 Jul 2008 03:16:00 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:a34aea95-06fb-49b7-88b3-c0d2614bb884</guid><dc:creator>Tsuneo Chinzei</dc:creator><description>&lt;p&gt;&lt;p&gt;
Sorry for my late response,&lt;/p&gt;

&lt;p&gt;
&lt;i&gt;&amp;quot;I also need to be able to send the controller long reports
(140 bytes) via a control transfer.&amp;quot;&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;
You can support OUT report over control transfer, but primarily
OUT report is handled by an OUT endpoint.&lt;br /&gt;
- For the firmware, handling of control transfer is heavy than
interrupt endpoint&lt;br /&gt;
- For Windows XP and Vista host app, WriteFile primarily goes to OUT
endpoint.&lt;/p&gt;

&lt;p&gt;
In this topic, we discussed about the way to add OUT endpoint to
HID.&lt;br /&gt;
You can extend this method for the greater report size than 64, as
you did it to the IN endpoint.&lt;/p&gt;

&lt;p&gt;
&amp;quot;LPC2148 usb controller&amp;quot;&lt;br /&gt;
&lt;a href="http://www.keil.com/forum/docs/thread11137.asp"&gt;http://www.keil.com/forum/docs/thread11137.asp&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;
Instead of OUT report, Feature report is primarily handled by
control transfer. If you want to exercise the control write transfer
implementation, I&amp;#39;ll guide you.&lt;/p&gt;

&lt;p&gt;
Tsuneo&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: USB HID reports longer than 64 bytes on lpc2141</title><link>https://community.arm.com/thread/124759?ContentTypeID=1</link><pubDate>Fri, 04 Jul 2008 14:41:14 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:e8197856-795f-4c9e-8655-56ec78ccab7d</guid><dc:creator>Jason Lewis</dc:creator><description>&lt;p&gt;&lt;p&gt;
Okay, another related question. I also need to be able to send the
controller long reports (140 bytes) via a control transfer. I&amp;#39;ve
verified that the report is being sent and the controller is
receiving them (64, 64, and 12). I can&amp;#39;t figure out how to modify the
HIDUSB code to parse the pieces together. Any help would be
appreciated.&lt;/p&gt;

&lt;p&gt;
Jason Lewis&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: USB HID reports longer than 64 bytes on lpc2141</title><link>https://community.arm.com/thread/114049?ContentTypeID=1</link><pubDate>Tue, 24 Jun 2008 09:12:47 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:24a11e44-ad7e-4573-ad1b-723823da33fb</guid><dc:creator>Jason Lewis</dc:creator><description>&lt;p&gt;&lt;p&gt;
Awesome, that did it. Turns out that I had all the code right
initially with the exception of USB_Endpoint1.&lt;/p&gt;

&lt;p&gt;
Thanks Tsuneo!&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: USB HID reports longer than 64 bytes on lpc2141</title><link>https://community.arm.com/thread/100791?ContentTypeID=1</link><pubDate>Mon, 23 Jun 2008 17:06:59 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:c6961f23-ed4f-44c9-a3b0-5f13199d1d2e</guid><dc:creator>Tsuneo Chinzei</dc:creator><description>&lt;p&gt;&lt;p&gt;
&lt;i&gt;&amp;quot;Should MAXPACKET_SIZE be the two bytes (my report is 100
bytes) added together?&amp;quot;&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;
You don&amp;#39;t need to touch MAXPACKET_SIZE of USB_ConfigEP.&lt;br /&gt;
Please note, wMaxPacketSize means the division unit for
transactions.&lt;br /&gt;
It doesn&amp;#39;t mean the transfer size itself.&lt;br /&gt;
Transfer size is defined by the HID_ReportCount() on the report
descriptor.&lt;br /&gt;
And the wMaxPacketSize for full-speed interrupt and bulk transfer is
limited to 64 bytes by the USB spec.&lt;/p&gt;

&lt;p&gt;
Recently, I wrote about the relation of &amp;quot;Transfer - transaction -
packet&amp;quot; in this post. It describes how wMaxPacketSize works on the
USB protocol.&lt;br /&gt;
It is applied to bulk and interrupt (HID) transfer.&lt;/p&gt;

&lt;p&gt;
&amp;quot;C8051F340 USB_Bulk example question&amp;quot; on SiLabs Forum&lt;br /&gt;
&lt;a href="http://www.cygnal.org/ubb/Forum9/HTML/001627.html"&gt;www.cygnal.org/.../001627.html&lt;/a&gt;&lt;br /&gt;

&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;&amp;quot;Report Descriptor&amp;quot;&lt;/i&gt;&lt;/p&gt;

&lt;pre&gt;
HID_ReportID(0x11),      // Input Report 11
&lt;/pre&gt;

&lt;p&gt;
As the report descriptor has just single definition of input
report, you can do without the report ID.&lt;br /&gt;
Of course, you can apply report ID as you wrote, too.&lt;br /&gt;
If you have plan to add more input reports, the report ID will ease
the extension.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;&amp;quot;Endpoint Descriptor&amp;quot;&lt;/i&gt;&lt;/p&gt;

&lt;pre&gt;
0x40,&lt;b&gt;0x24&lt;/b&gt;,                         /* wMaxPacketSize */
&lt;/pre&gt;

&lt;p&gt;
This is the problem. Set wMaxPacketSize to 64 (LSB first, as usual
on USB).&lt;/p&gt;

&lt;pre&gt;
0x40,0x00,                         /* wMaxPacketSize = 64 */
&lt;/pre&gt;

&lt;p&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;&amp;quot;USB_EndPoint1&amp;quot;&lt;/i&gt;&lt;/p&gt;

&lt;pre&gt;
DWORD byte_count = 0;
&lt;/pre&gt;

&lt;p&gt;
Make byte_count to static, or global.&lt;br /&gt;
USB_EndPoint1() is called by the USB ISR every time a transaction
finishes.&lt;br /&gt;
Anyway, I think this byte_count is not useful in your code, because
you does it with report_block_number.&lt;/p&gt;

&lt;p&gt;
In this implementation, your device continuously puts the input
report at the rate defined by the endpoint descriptor (bInterval). As
it is 32 ms, the first transaction (64 bytes) and later one (32
bytes) are sent to the host alternately, in this rate. (The entire
transfer takes 64 ms).&lt;/p&gt;

&lt;p&gt;
If you want to send the report just when the device detects a
change on the target, rewrite it as described in above post.&lt;/p&gt;

&lt;p&gt;
Tsuneo&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: USB HID reports longer than 64 bytes on lpc2141</title><link>https://community.arm.com/thread/76409?ContentTypeID=1</link><pubDate>Mon, 23 Jun 2008 12:23:49 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:3fd20591-46f5-4fe2-9806-34a62935fc21</guid><dc:creator>Jason Lewis</dc:creator><description>&lt;p&gt;&lt;p&gt;
Thanks for the response Tsuneo! I gave it a try but it still
doesn&amp;#39;t seem to be working. I think it may have something to do with
USB_ConfigEP that deals with the Endpoint descriptor. The code
is:&lt;/p&gt;

&lt;pre&gt;
void USB_ConfigEP (USB_ENDPOINT_DESCRIPTOR *pEPD) {
  DWORD num;

  num = EPAdr(pEPD-&amp;gt;bEndpointAddress);
  REALIZE_EP |= (1 &amp;lt;&amp;lt; num);
  EP_INDEX = num;
  MAXPACKET_SIZE = pEPD-&amp;gt;wMaxPacketSize;
  while ((DEV_INT_STAT &amp;amp; EP_RLZED_INT) == 0);
  DEV_INT_CLR = EP_RLZED_INT;
}
&lt;/pre&gt;

&lt;p&gt;
It assumes that the max packet size a word. Should MAXPACKET_SIZE
be the two bytes (my report is 100 bytes) added together?&lt;/p&gt;

&lt;p&gt;
The important bits of my code are:&lt;/p&gt;

&lt;p&gt;
Report Descriptor&lt;/p&gt;

&lt;pre&gt;
  HID_UsagePageVendor(0xFF),   // ESA Config
  HID_Usage(0x03),                             // ESA Water Cooling

  HID_Collection(HID_Application),
    HID_ReportID(0x11),      // Input Report 11
    //HID_UsagePage(0xFF),
    HID_Usage(0x04),
    HID_LogicalMin(0),
    HID_LogicalMax(255),
    HID_ReportCount(99),
    HID_ReportSize(8),
    HID_Input(HID_Data | HID_Array | HID_Absolute),
  HID_EndCollection,
&lt;/pre&gt;

&lt;p&gt;
Endpoint Descriptor&lt;/p&gt;

&lt;pre&gt;
/* Endpoint, HID Interrupt In */
  USB_ENDPOINT_DESC_SIZE,            /* bLength */
  USB_ENDPOINT_DESCRIPTOR_TYPE,      /* bDescriptorType */
  USB_ENDPOINT_IN(1),                /* bEndpointAddress */
  USB_ENDPOINT_TYPE_INTERRUPT,       /* bmAttributes */
  0x40,0x24,                         /* wMaxPacketSize */
  0x20,          /* 32ms */          /* bInterval */
&lt;/pre&gt;

&lt;p&gt;
USB_EndPoint1&lt;/p&gt;

&lt;pre&gt;
void USB_EndPoint1 (DWORD event) {

  DWORD byte_count = 0;

  set_chb_err_led(FALSE);
  switch (event) {
    case USB_EVT_IN:
      // Alternate which report we output so we don&amp;#39;t stomp the buffer
      switch (report_block_number) {
        case 0:
          GetInReportMCC();
          byte_count = USB_WriteEP(0x81, InReport, 64);
          report_block_number = 1;
          break;

        case 1:
          byte_count = USB_WriteEP(0x81, InReport, 36);
          report_block_number = 0;
          break;
      }
      if (byte_count &amp;gt; 0)
        set_usb_status(0);
      if (byte_count == 0)
        set_usb_status(1);
      break;
  }
}
&lt;/pre&gt;

&lt;p&gt;
Does this look correct? Thanks again for all the help. I&amp;#39;m on a
really tight timeline so it&amp;#39;s appreciated.&lt;/p&gt;

&lt;p&gt;
Jason Lewis&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: USB HID reports longer than 64 bytes on lpc2141</title><link>https://community.arm.com/thread/50079?ContentTypeID=1</link><pubDate>Fri, 20 Jun 2008 10:30:01 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:27ae987c-071d-459f-8263-c0f964853f1e</guid><dc:creator>Tsuneo Chinzei</dc:creator><description>&lt;p&gt;&lt;p&gt;
&lt;b&gt;Report Descriptor&lt;/b&gt;&lt;br /&gt;
This report descriptor defines 191 bytes Input and 150 bytes Output
report&lt;/p&gt;

&lt;pre&gt;
#define INREPORT_SIZE    191
#define OUTREPORT_SIZE   150

/* HID Report Descriptor */
const BYTE HID_ReportDescriptor[] = {
  HID_UsagePageVendor( 0x00                                   ),
  HID_Usage(           0x01                                   ),
  HID_Collection(      HID_Application                        ),
    HID_LogicalMin(    0                                      ),
    HID_LogicalMaxS(   0xFF                                   ),
    HID_ReportSize(    8                                      ),  // bits
    HID_ReportCount(   INREPORT_SIZE                          ),  // bytes
    HID_Usage(         0x01                                   ),
    HID_Input(         HID_Data | HID_Variable | HID_Absolute ),
    HID_ReportCount(   OUTREPORT_SIZE                         ),  // bytes
    HID_Usage(         0x01                                   ),
    HID_Output(        HID_Data | HID_Variable | HID_Absolute ),
  HID_EndCollection,
};
&lt;/pre&gt;

&lt;p&gt;
HID_ReportCount() macro supports upto 255 (single byte) as its
parameter.&lt;br /&gt;
For more bytes (up to 0xFFFF), apply this HID_ReportCount&lt;b&gt;S&lt;/b&gt;()
macro (two bytes)&lt;/p&gt;

&lt;pre&gt;
#define HID_ReportCountS(x)     0x96,(x&amp;amp;0xFF),((x&amp;gt;&amp;gt;8)&amp;amp;0xFF)
&lt;/pre&gt;

&lt;p&gt;
I don&amp;#39;t know what is the reliable maximum report size on Windows,
but I recommend you less than or equal to 4 Kbytes (page size of PCI
bus).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Split the input report&lt;/b&gt;&lt;br /&gt;
The report is split by wMaxPacketSize (endpoint descriptor) of the
endpoint. It&amp;#39;s usually 64 bytes for full-speed HID device, but
confirm your descriptor definition.&lt;/p&gt;

&lt;p&gt;
Above 191 bytes report is split into three transactions,&lt;/p&gt;

&lt;p&gt;
64, 64, 63&lt;/p&gt;

&lt;p&gt;
Above report descriptor defines no report ID. Then, this division
is fine.&lt;br /&gt;
If you use any report ID for more input-report formats, the report is
preceded by the report ID, the division becomes as follows.&lt;/p&gt;

&lt;p&gt;
(1byte report ID + 63), 64, 64&lt;/p&gt;

&lt;p&gt;
If any other input report longer than this one is defined, this
report transfer should be terminated by ZLP (Zero-Length Packet),
because the last transaction matches to wMaxPacketSize&lt;/p&gt;

&lt;p&gt;
(1byte report ID + 63), 64, 64, ZLP&lt;/p&gt;

&lt;p&gt;
The largest report don&amp;#39;t need to terminate with ZLP, even when it
ends up with wMaxPacketSize transaction.&lt;/p&gt;

&lt;p&gt;
Complicated? :-)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Endpoint handling&lt;/b&gt;&lt;br /&gt;
When the hardware finishes to collect whole data for the report, the
firmware makes up the entire report on a buffer. The first
transaction (64 bytes) is put to the endpoint buffer using
USB_WriteEP(), in the data acquisition routine. See this post for the
details.&lt;/p&gt;

&lt;p&gt;
&amp;quot;HID Mouse keeps sending unneeded data!&amp;quot;&lt;br /&gt;
&lt;a href="http://www.keil.com/forum/docs/thread11531.asp"&gt;http://www.keil.com/forum/docs/thread11531.asp&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;
The second and later transactions are handled in the endpoint ISR,
USB_EndPoint&lt;b&gt;N&lt;/b&gt;. This ISR is called when the endpoint buffer
becomes empty by a successful transaction. Every time the
USB_EndPoint&lt;b&gt;N&lt;/b&gt; is called, put the next transaction, if any, by
USB_WriteEP().&lt;/p&gt;

&lt;p&gt;
You have to fiddle several flags and counter to make this work as
expected.&lt;/p&gt;

&lt;p&gt;
Tsuneo&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>