This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

The problem of using UART to communicate between nRF160 and nRF2833 on nRF Connect SDK.

Hello, All,

When using UART on nRF Connect SDK to communicate between nrf9160DK and nRF2833DK, I found that the data length of a packet sent by the UART on both sides is different.

When using nRF9160 to send, a data packet can reach more than 1K; but when using nRF2833 to send, it is found that a data packet can only send about 250 bytes.

WHY?

Are there any restrictions?

Is it restricted by DMA?

Where is the explanation about this part?

The sending function I use is: "uart_tx()".

Even if I change the value of the macro CONFIG_UART_0_NRF_TX_BUFFER_SIZE, it has no effect.

Parents
  • Sorry, I was wrong. What I tested was not nRF52833DK but nRF52840DK, because currently nRF52833 will report an error "Not able to allocate UART receive buffer".

    And why does nRF52833 report this problem while nRF52840 is normal?

  • Hi

    Are you saying the nRF52833 will fail even if it uses exactly the same code and the same project configuration?

    How large is the buffer that the nRF52833 fails to allocate?

    Could you try to increase the CONFIG_HEAP_MEM_POOL_SIZE setting in prj.conf and see if the problem goes away?

    Best regards
    Torbjørn

  • Hi 

    I was able to reproduce the issue based on your code, and after debugging this for a bit it seems that the issue is indirectly caused by the UART driver never freeing any of the buffers. 

    The buf_release variable is never set to true in mt_uart.c, and for this reason the receive buffers are never freed by the UART_RX_BUF_RELEASED event. 

    Why this only happens for the nRF52833 and not the nRF52840 I do not understand, the issue should be the same for both. 

    I will spend some more time with this tomorrow and try to get to the bottom of it. 

    By the way, there seems to be a bug in the UART_RX_RDY event, where the following two lines were changed from the original example:

                } else if ((evt->data.rx.buf[rx_buf->len - 1] == '\r'&&
                           (evt->data.rx.buf[rx_buf->len - 1] == '\n')) {
    The original example used or, while this was changed to and. (&& instead of ||)
    I tried to change this, but it did not help with the memory free issue. 
    Best regards
    Torbjørn
  • Okay, I overlooked this change, but this does not affect the error. I know it may be caused by memory, but I haven't identified the problem and haven't found how to solve it.

    Hope you can help to solve it as soon as possible, thank you very much!

  • Hi 

    I spent some more time with it today. It appears the UART_RX_DISABLED event occurs extremely frequently when running the example on the nRF52833, and this is causing a lot more buffers to be allocated than you free. Eventually this will lead to the heap filling up, and you won't be able to allocate any more buffers. 

    Why the UART driver behaves like this on the nRF52833 I do not yet know. I tested it on the nRF52840 as well and confirmed that this device does not exhibit the same behavior. 

    Tomorrow I will try to set up a more simple UART example in order to debug what is happening with the UART driver when running it on the nRF52833. 

    Best regards
    Torbjørn

  • Hi 

    Sorry for the long delay. It has been some very busy weeks, and I only had limited time to test this out. 

    After doing more testing on my side it seems like most of the issues I have seen are caused a couple of factors:

    1) The fact that the nRF9160DK runs at 1.8V by default. In order to configure the board to 3.0V (to be compatible with the nRF52 kits) the SW1 switch must be set to the 3V setting. 

    2) When running UART communication without the external high frequency clock you will eventually encounter a framing errors, which causes problems for reception when using the Zephyr driver. 

    I solved this issue by making sure to request the high accuracy HF crystal to be enabled in order to ensure that the UART baudrate is as accurate as possible:

    int clocks_start(void)
    {
    	int err;
    	int res;
    	struct onoff_manager *clk_mgr;
    	struct onoff_client clk_cli;
    
    	clk_mgr = z_nrf_clock_control_get_onoff(CLOCK_CONTROL_NRF_SUBSYS_HF);
    	if (!clk_mgr) {
    		printk("Unable to get the Clock manager\n");
    		return -ENXIO;
    	}
    
    	sys_notify_init_spinwait(&clk_cli.notify);
    
    	err = onoff_request(clk_mgr, &clk_cli);
    	if (err < 0) {
    		printk("Clock request failed: %d\n", err);
    		return err;
    	}
    
    	do {
    		err = sys_notify_fetch_result(&clk_cli.notify, &res);
    		if (!err && res) {
    			printk("Clock could not be started: %d\n", res);
    			return res;
    		}
    	} while (err);
    
    	printk("HF clock started\n");
    	return 0;
    }

    2b) I believe the memory allocation scheme used in the example doesn't handle UART framing errors very well, as it will not free all the previously allocated memory when this happens. 

    In case of framing errors it is necessary to ensure that the receive buffers are freed, and the UART must be enabled again. 

    That said, if you follow my advice above hopefully the framing errors will not occur like they did before. 

    Best regards
    Torbjørn

  • Sorry, I didn't see your reply until recently due to some other reasons, I'll try it when I have time.

    Thanks very much!

Reply Children
Related