<?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>Flow control of BULK OUT endpoint</title><link>https://community.arm.com/developer/tools-software/tools/f/keil-forum/29432/flow-control-of-bulk-out-endpoint</link><description> 
Hi All, 

 
I&amp;#39;ve got an issue with flow control of a bulk OUT endpoint I&amp;#39;m
struggling with. I&amp;#39;m using the NXP LPC1343, and the device code is
based on their CDC class example. On the Host side, I&amp;#39;m using linux
with libusb to do usb_bulk_write() . 
</description><dc:language>en-US</dc:language><generator>Telligent Community 10</generator><item><title>RE: Flow control of BULK OUT endpoint</title><link>https://community.arm.com/thread/79505?ContentTypeID=1</link><pubDate>Wed, 17 Aug 2011 16:47:04 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:8f2a7efc-5436-4fb0-b6fb-1f2d17dcb0a1</guid><dc:creator>Peter von Konigsmark</dc:creator><description>&lt;p&gt;&lt;p&gt;
Hi Tsuneo,&lt;/p&gt;

&lt;p&gt;
Thanks very much for the reply, nice idea putting the check in the
SOF event handler.&lt;/p&gt;

&lt;p&gt;
By doing &lt;i&gt;bulk_out_count++&lt;/i&gt; it seems I get 1 more
&lt;i&gt;bulk_out_count&lt;/i&gt; than necessary, and get stuck in USB_ReadEP()
in this loop:&lt;/p&gt;

&lt;pre&gt;

    do
    {
        cnt = LPC_USB-&amp;gt;RxPLen;
    }
    while ((cnt &amp;amp;PKT_DV) == 0);

&lt;/pre&gt;

&lt;p&gt;
By changing &lt;i&gt;bulk_out_count++&lt;/i&gt; to &lt;i&gt;bulk_out_count=1&lt;/i&gt; in
CDC_BulkOut() things are working really well.&lt;/p&gt;

&lt;p&gt;
Thanks again,&lt;br /&gt;
Peter&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Flow control of BULK OUT endpoint</title><link>https://community.arm.com/thread/59732?ContentTypeID=1</link><pubDate>Tue, 16 Aug 2011 20:31:28 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:2c1be796-3c1e-4cab-b415-cafbd0efe45a</guid><dc:creator>Chinzei Tsuneo</dc:creator><description>&lt;p&gt;&lt;p&gt;
&lt;i&gt;&amp;gt; When there is data available on the endpoint, I
USB_ReadEP() it out into a circular buffer IF I&amp;#39;ve got room in that
buffer. If there&amp;#39;s no room (ie the device is still processing old
data), I don&amp;#39;t do the USB_ReadEP() and hence the CMD_CLR_BUF bit does
not get set in the peripheral.&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;
It&amp;#39;s right on the rail, so far. But,&lt;/p&gt;

&lt;p&gt;
&lt;i&gt;&amp;gt; I would have expected the Host to retry sending that
packet some time later, at which point I would have room and read the
endpoint and everyone would be happy. ... I can see at this time
there are no interrupts being generated from the USB
peripheral&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;
This is a wrong assumption.&lt;br /&gt;
On the device side, the endpoint interrupt occurs just when a
transaction completes successfully. But as the endpoint buffer is
still occupied by the last transaction, the endpoint keeps NAKing to
the OUT transactions. You have to call USB_ReadEP() to unload the
data from the endpoint buffer, to receive the next transaction. The
bulk endpoint has double buffer. It may keep two transactions, at
most, pending on the buffer.&lt;/p&gt;

&lt;p&gt;
The outline of the code flow is as follows, based on USBCDC
example of this samples.&lt;/p&gt;

&lt;p&gt;
Sample Code Bundle for LPC13xx Peripherals using Keil&amp;#39;s MDK-ARM
V1.06 (Jun 8, 2011)&lt;br /&gt;

&lt;a href="http://ics.nxp.com/support/documents/microcontrollers/zip/code.bundle.lpc13xx.keil.zip"&gt;ics.nxp.com/.../code.bundle.lpc13xx.keil.zip&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;
1) A global variable, say U8 bulk_out_count, is declared and
initialized to 0.&lt;br /&gt;
2) bulk_out_count is cleared in Set_Configuration handler&lt;/p&gt;

&lt;pre&gt;
usbuser.c

#if USB_CONFIGURE_EVENT
void USB_Configure_Event (void) {

  if (USB_Configuration) {                  /* Check if USB is configured */
    /* add your code here */
    bulk_out_count = 0;      // &amp;lt;---------
  }
}
#endif
&lt;/pre&gt;

&lt;p&gt;
3) Read out bulk transaction in CDC_BulkOut(), when there is
enough room for the packet. Else, count up bulk_out_count.&lt;/p&gt;

&lt;pre&gt;
cdcuser.c

void CDC_BulkOut(void) {
  int numBytesRead;

  if ( _there_is_room_on_the_buffer_ ) {
    // read out the data to the buffer using USB_ReadEP()
  } else {
    ++bulk_out_count;
  }
}
&lt;/pre&gt;

&lt;p&gt;
4) The buffer is periodically checked in SOF handler.&lt;/p&gt;

&lt;pre&gt;
usbcfg.h

#define USB_SOF_EVENT       1

usbuser.c

#if USB_SOF_EVENT
void USB_SOF_Event (void) {
  if ( bulk_out_count ) {
    // check the room on the buffer
    // if there is enough room, read a packet using USB_ReadEP()
    // and decrement bulk_out_count by one
  }
}
#endif
&lt;/pre&gt;

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