<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://devzone.nordicsemi.com/cfs-file/__key/system/syndication/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/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Help understanding USB CDC ACM read flow</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/72752/help-understanding-usb-cdc-acm-read-flow</link><description>Hey all, I&amp;#39;m trying very hard to understand how UART over USB works by following through the USB CDC ACM example in SDK 17.0.2 on the nRF52840DK, but I&amp;#39;m still new to this so I&amp;#39;m missing something. I see that on APP_USBD_CDC_ACM_USER_EVT_PORT_OPEN , we</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Sun, 14 Mar 2021 20:37:56 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/72752/help-understanding-usb-cdc-acm-read-flow" /><item><title>RE: Help understanding USB CDC ACM read flow</title><link>https://devzone.nordicsemi.com/thread/299620?ContentTypeID=1</link><pubDate>Sun, 14 Mar 2021 20:37:56 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:49f453f7-d297-45e6-a6ac-77c9dba6ec54</guid><dc:creator>kv1980</dc:creator><description>&lt;p&gt;Ahhhh!&amp;nbsp; Once I see it I realize I&amp;#39;m dumb :-P&amp;nbsp; It&amp;#39;s all so clear now.&amp;nbsp; Thank you so much &lt;a href="https://devzone.nordicsemi.com/members/dmitryz"&gt;Dmitry&lt;/a&gt;!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Help understanding USB CDC ACM read flow</title><link>https://devzone.nordicsemi.com/thread/299619?ContentTypeID=1</link><pubDate>Sun, 14 Mar 2021 19:38:42 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:df5687f7-615e-42ec-beb7-3cafd699a0e5</guid><dc:creator>Dmitry</dc:creator><description>[quote userid="95738" url="~/f/nordic-q-a/72752/help-understanding-usb-cdc-acm-read-flow/299618#299618"]but the end of the do loop in the handler is &lt;code&gt;while (ret == NRF_SUCCESS)&lt;/code&gt; so how can I call &lt;code&gt;app_usbd_cdc_acm_write&lt;/code&gt; if I am stuck in the loop?[/quote]
&lt;p&gt;The code should look something like this:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;            do
            {
                /* here the next 64 bytes are in the buffer */
                app_usbd_cdc_acm_write(p_cdc_acm, m_rx_buffer[m_cdc_buffer_idx].buffer, READ_SIZE);
                if (++m_cdc_buffer_idx &amp;gt; ARRAY_LIST_SIZE) m_cdc_buffer_idx = 0;
                
                /* Fetch data until internal buffer is empty */
                ret = app_usbd_cdc_acm_read(p_cdc_acm,
                                            m_rx_buffer[m_cdc_buffer_idx].buffer,
                                            READ_SIZE);
            } while (ret == NRF_SUCCESS);

            /* last app_usbd_cdc_acm_read() returned IO_PENDING */&lt;/pre&gt;&lt;/p&gt;
[quote userid="95738" url="~/f/nordic-q-a/72752/help-understanding-usb-cdc-acm-read-flow/299618#299618"]Sorry, but does this mean I just make one 64 byte buffer and just keep pointing it back into the &lt;code&gt;app_usbd_cdc_acm_read&lt;/code&gt;?&amp;nbsp; What if I want to do some processing on it?[/quote]
&lt;p&gt;What I mean - the buffer is not touched by USBD until you call&amp;nbsp;&lt;span&gt;app_usbd_cdc_acm_read() again - you can process it directly in&amp;nbsp;APP_USBD_CDC_ACM_USER_EVT_RX_DONE&amp;nbsp;handler, while the next data are received into the internal buffer. Of course, if circular buffer is more convenient in your case, it&amp;#39;s a good decision.&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Help understanding USB CDC ACM read flow</title><link>https://devzone.nordicsemi.com/thread/299618?ContentTypeID=1</link><pubDate>Sun, 14 Mar 2021 19:18:23 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:d59364c8-46b1-4fea-9eb1-8e0dedc813c3</guid><dc:creator>kv1980</dc:creator><description>&lt;p&gt;Thanks &lt;a href="https://devzone.nordicsemi.com/members/dmitryz"&gt;Dmitry&lt;/a&gt;, I think I&amp;#39;m getting there.&amp;nbsp; Just two little things I can&amp;#39;t quite wrap my brain around. You say&lt;/p&gt;
[quote userid="5418" url="~/f/nordic-q-a/72752/help-understanding-usb-cdc-acm-read-flow/299617#299617"]If the result of next app_usbd_cdc_acm_read() is NRF_SUCCESS, you can call app_usbd_cdc_acm_write() again.[/quote]
&lt;p&gt;but the end of the do loop in the handler is &lt;code&gt;while (ret == NRF_SUCCESS)&lt;/code&gt; so how can I call &lt;code&gt;app_usbd_cdc_acm_write&lt;/code&gt; if I am stuck in the loop?&lt;/p&gt;
&lt;p&gt;Also,&lt;/p&gt;
[quote userid="5418" url="~/f/nordic-q-a/72752/help-understanding-usb-cdc-acm-read-flow/299617#299617"]CDC ACM has two rx buffers internally, you don&amp;#39;t need to switch buffers in your code.[/quote]
&lt;p&gt;Sorry, but does this mean I just make one 64 byte buffer and just keep pointing it back into the &lt;code&gt;app_usbd_cdc_acm_read&lt;/code&gt;?&amp;nbsp; What if I want to do some processing on it?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Help understanding USB CDC ACM read flow</title><link>https://devzone.nordicsemi.com/thread/299617?ContentTypeID=1</link><pubDate>Sun, 14 Mar 2021 19:04:21 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:0839c279-2705-4815-9d3b-a440f2d8259b</guid><dc:creator>Dmitry</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;the &lt;a href="https://infocenter.nordicsemi.com/topic/sdk_nrf5_v17.0.2/lib_usbd_class_cdc.html?cp=7_1_3_56_8_3"&gt;documentation&lt;/a&gt; for CDC ACM module explains these things quite clear.&lt;/p&gt;
&lt;p&gt;In APP_USBD_CDC_ACM_USER_EVT_PORT_OPEN handler, you&amp;#39;re preparing to receive 64 bytes into the buffer. There is still no data, so you shouldn&amp;#39;t call app_usbd_cdc_acm_write() here - it will send some garbage.&lt;/p&gt;
&lt;p&gt;When APP_USBD_CDC_ACM_USER_EVT_RX_DONE comes, you have 64 bytes ready in your buffer - here you should call app_usbd_cdc_acm_write(). Then in the loop, you&amp;#39;re reading next chunks that may already have been received by USB peripheral. If the result of next app_usbd_cdc_acm_read() is NRF_SUCCESS, you can call app_usbd_cdc_acm_write() again. Otherwise it will return NRF_ERROR_IO_PENDING - data is not yet ready, but app_usbd_cdc_acm_read() prepares USBD to receive next 64 bytes - the following APP_USBD_CDC_ACM_USER_EVT_RX_DONE will have the buffer filled in.&lt;/p&gt;
&lt;p&gt;CDC ACM has two rx buffers internally, you don&amp;#39;t need to switch buffers in your code.&lt;/p&gt;
[quote userid="95738" url="~/f/nordic-q-a/72752/help-understanding-usb-cdc-acm-read-flow/299610#299610"]How do other people process variable length data from USB CDC ACM?[/quote]
&lt;p&gt;Eother by reading one byte at a time, or with&amp;nbsp;&lt;a href="https://infocenter.nordicsemi.com/topic/sdk_nrf5_v17.0.2/group__app__usbd__cdc__acm.html#ga6fc12b6b9b9633a56bf108d78386dd03"&gt;app_usbd_cdc_acm_read_any&lt;/a&gt;&amp;nbsp;function.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Help understanding USB CDC ACM read flow</title><link>https://devzone.nordicsemi.com/thread/299610?ContentTypeID=1</link><pubDate>Sun, 14 Mar 2021 14:18:41 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:937e280e-4420-4f6e-a946-34b638d6c47c</guid><dc:creator>kv1980</dc:creator><description>&lt;p&gt;After a little more testing, I think I am narrowing down the my question a little.&amp;nbsp; Here&amp;#39;s the sequence:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;On PORT_OPEN, the first read is executed, the buffer is empty (since no data has been sent), and the index of the buffer is incremented by one, so &lt;code&gt;m_cdc_buffer_idx = 1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;When I send the 662 bytes of data (this is the header for a standard WAV file) and I set a break, I see the beginning of the data get read into &lt;code&gt;m_rx_buffer[0]&lt;/code&gt;, and subsequent data read accordingly into &lt;code&gt;m_rx_buffer[1]&lt;/code&gt;, etc.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;How does this work?&amp;nbsp; When I send the data I do the read with the buffer located at &lt;code&gt;m_rx_buffer[m_cdc_buffer_idx]&lt;/code&gt; and &lt;code&gt;m_cdc_idx = 1&lt;/code&gt; - so shouldn&amp;#39;t the beginning of my data appear in &lt;code&gt;m_rx_buffer[1]&lt;/code&gt; instead of &lt;code&gt;m_rx_buffer[0]&lt;/code&gt;?&amp;nbsp; I&amp;#39;m guessing that since the index gets increased but the data read into previous buffers, that&amp;#39;s why it is not echoed to the terminal.&lt;/p&gt;
&lt;p&gt;Here is the test data I&amp;#39;m using:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;RIFF&amp;#252;ak&#x1;WAVEfmt &#x10;   &#x1; &#x1; D&amp;#172;  &amp;#204;&#x4;&#x2; &#x3; &#x18; bext[&#x2;                                                                                                                                                                                                                                                                  iZotope RX 7 Audio Editor       USIZT0037408408461551490069551812021-03-1115:51:49                                                                                                                                                                                                                                                                          datas_k&#x1;&amp;#255;&amp;#255;&amp;#255;&#x4;  &lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;I was planning on keeping track of which buffer I was on with the &lt;code&gt;m_cdc_buffer_idx&lt;/code&gt; variable, but if it isn&amp;#39;t on the current buffer, that kind of defeats the purpose.&amp;nbsp; How do other people process variable length data from USB CDC ACM?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>