<?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>problems with transferring large datasets from computer to nRF over UARTE</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/78290/problems-with-transferring-large-datasets-from-computer-to-nrf-over-uarte</link><description>I am trying to use the nRF as an intermediary bootloader for another microcontroller. All that I need the nRF to do is accept a 64kB binary file from my computer (at the moment I do this over UART). Occasionally it works, but most of the time, I lose</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Wed, 11 Aug 2021 07:04:25 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/78290/problems-with-transferring-large-datasets-from-computer-to-nrf-over-uarte" /><item><title>RE: problems with transferring large datasets from computer to nRF over UARTE</title><link>https://devzone.nordicsemi.com/thread/324366?ContentTypeID=1</link><pubDate>Wed, 11 Aug 2021 07:04:25 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:c5bc4385-9bfa-4fda-8350-6bcdcf61af8f</guid><dc:creator>Susheel Nuguru</dc:creator><description>&lt;p&gt;seems you have a good control on this ahjr, Please do care to come back here to update me with your findings. I am confident that the UART should function correctly (especially when you are seeing no errors) . Could be a race condition somewhere in the logic.&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: problems with transferring large datasets from computer to nRF over UARTE</title><link>https://devzone.nordicsemi.com/thread/324056?ContentTypeID=1</link><pubDate>Mon, 09 Aug 2021 14:33:43 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:e2d569a5-3fbb-4721-8b12-8b62adff5c61</guid><dc:creator>ahjr</dc:creator><description>&lt;p&gt;Hi Susheel,&lt;/p&gt;
&lt;p&gt;Thanks for responding. UART_BUF_SIZE is&amp;nbsp;1 in my code. Sorry about the confusion, if it were anything else your addition would be necessary. For UARTE errors:&amp;nbsp;when I used certain baud rates (like 19200) I was&amp;nbsp;seeing a 1 in the error register. Once I changed the baud I no longer saw any errors, even when bytes were missing.&lt;/p&gt;
&lt;p&gt;I tried to simplify the code to try to isolate the problem. I removed the UART-based state machine and simply defaulted to the &amp;quot;load 64kB into RAM&amp;quot; state.&amp;nbsp;Once it receives 64kB, it resets the index to 0 and waits for 64kB new bytes. I tried it around 250 times and I missed zero bytes (CRC checked as well). It&amp;#39;s a temporary fix. I will continue to investigate the UART-based state machine. I know that the nRF can reliably receive 64kB over UART, and I know that the state machine works, but&amp;nbsp;when I combine the two it breaks in&amp;nbsp;ways that make no sense.&lt;/p&gt;
&lt;p&gt;I will also try flow control.&amp;nbsp;I have fairly robust error handling&amp;nbsp;with CRC, but flow control can&amp;#39;t hurt.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: problems with transferring large datasets from computer to nRF over UARTE</title><link>https://devzone.nordicsemi.com/thread/323910?ContentTypeID=1</link><pubDate>Mon, 09 Aug 2021 06:12:01 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:98bc282e-a178-4f3e-98dd-407d14e6d00b</guid><dc:creator>Susheel Nuguru</dc:creator><description>&lt;p&gt;Hi Ahjr,&lt;/p&gt;
&lt;p&gt;Thanks for clear description. Will definitely save us time as it is faster for me to understand the problem. Few thoughts while I am reading your information.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Not using flow control is ok as long as you have a solid error handling mechanism. It looks like all your ISR is doing at any error (EVENTS_ERROR) is that it is clearing that event and flushing RX. This flush will make you lose received bytes unless you have a mechanism to tell to the peer to retransmit those missed bytes. Also it would be interesting to see what error occurred (if any) before you flush out all bytes so that we might attempt to solve the source of this error.&lt;/li&gt;
&lt;li&gt;You are using UARTE (EasyDMA), so unless you have&amp;nbsp;UART_BUF_SIZE set to 1, your handling of data in the ISR is wrong. When you get EVENTS_ENDRX, it means that you have received UART_BUF_SIZE of new data in the receive buffer (which you set to&amp;nbsp;uart_buf_DK_RX). So you need to extract and process that many bytes for every EVENTS_ENDRX. So your ISR event processing could be something like below&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;void UARTE0_UART0_IRQHandler(void) {

    uint8_t uart_rx_byte;
    uint8_t count;

    // debug
    app_dbg.num_ISR_UARTE0_UART0_IRQHandler++;

    if (NRF_UARTE0-&amp;gt;EVENTS_ERROR == 0x00000001) {
        // clear the error and continue? (Susheel: This below code means loss of data)
        NRF_UARTE0-&amp;gt;EVENTS_ERROR = 0x00000000;
        NRF_UARTE0-&amp;gt;TASKS_FLUSHRX = 0x00000001;
        NRF_UARTE0-&amp;gt;TASKS_STARTRX = 0x00000001;
    }

    if (NRF_UARTE0-&amp;gt;EVENTS_ENDRX == 0x00000001) {
        // byte received from computer

        // clear
        NRF_UARTE0-&amp;gt;EVENTS_ENDRX = 0x00000000;

        // debug
        app_dbg.num_ISR_UARTE0_UART0_IRQHandler_ENDRX++;

        count = UART_BUF_SIZE;
        
        while(count-- != 0)
        {
        if(app_vars.programmer_state == PROGRAMMER_WAIT_4_CMD_ST) {
                uart_rx_byte = app_vars.uart_buf_DK_RX[0];
                app_vars.uart_RX_command_buf[app_vars.uart_RX_command_idx++] = uart_rx_byte;

                if((uart_rx_byte==&amp;#39;\n&amp;#39;)||(uart_rx_byte==&amp;#39;\r&amp;#39;)) { // \r for debugging w/ putty, \n for the python scripts
                    app_vars.uart_RX_command_idx = 0; // reset index to receive the next command
                    if(memcmp(app_vars.uart_RX_command_buf,UART_TRANSFERSRAM,sizeof(UART_TRANSFERSRAM))==0) { // enter transfer SRAM state
                        app_vars.programmer_state = PROGRAMMER_SRAM_LD_ST;
                        app_vars.uart_RX_command_idx = 0;
                        print_sram_started_msg();
                    }
                    // else - erroneous command, clear the buffer and reset to default state
                    else {
                        memset(app_vars.uart_RX_command_buf,0,sizeof(app_vars.uart_RX_command_buf));
                        app_vars.uart_RX_command_idx = 0;
                        app_vars.programmer_state = PROGRAMMER_WAIT_4_CMD_ST;
                    }
                }
                else if (app_vars.uart_RX_command_idx &amp;gt; MAX_COMMAND_LEN) { // max length exceeded w/out return character, reset buffer
                    memset(app_vars.uart_RX_command_buf,0,sizeof(app_vars.uart_RX_command_buf));
                    app_vars.uart_RX_command_idx = 0;
                    app_vars.programmer_state = PROGRAMMER_WAIT_4_CMD_ST;
                }
            }
            else if (app_vars.programmer_state == PROGRAMMER_SRAM_LD_ST) {
                uart_rx_byte = app_vars.uart_buf_DK_RX[0];
                app_vars.instruction_memory[app_vars.uart_RX_command_idx++] = uart_rx_byte;
                if(app_vars.uart_RX_command_idx == MEM_SIZE) { // finished w/ the 64kB memory
                    // after loading memory - reset state, index, and command buffer
                    app_vars.programmer_state = PROGRAMMER_SRAM_LD_DONE;
                    print_sram_done_msg();
                    app_vars.programmer_state = PROGRAMMER_WAIT_4_CMD_ST;
                    app_vars.uart_RX_command_idx = 0;
                    memset(app_vars.uart_RX_command_buf,0,sizeof(app_vars.uart_RX_command_buf));
                }
            }
        }
    }
}&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>