This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Problem communicating via UART in non-blocking mode with higher baud rates

Hi,

I am trying to communicate with a Wi-Fi module external to nRF52840 via UART. I am using the nrf_serial_read() API. I have tried different values for UART baud rate from 115200 to 921600 but nothing works in the non-blocking mode(timeout_ms = 0).

The only working combinations between 115200 and 921600 are:
Baud rate                   Timeout         

115200                      125ms
230400                      100ms

Q1) Is the timeout necessary to make the UART communication work with a high baud rate?

Q2) I need to achieve a baud rate of 921600 for a smoother application with a minimum timeout in ms. Is there a way to achieve it? 

Thanks,
Akhil

Parents
  • Hi,

     

    1. How does it not work? 
    2. Do you check the return code of nrf_serial_read()?
    3. Does it return an error? 
    4. Do you have a logic analyzer?

    I don't think the timeout should matter. Note though, that you won't achieve 921600 exactly, but 941176,a so you are likely to get framing errors which can be problematic. 

     

     

  • Hi

    I got the nrf_serial_read working. I see that the communication is successful but I get framing errors and cannot receive complete data even with 115200 baud rate at timeout = 0.
    Same is the case with all other baud rates till 921600. 

    But, for baud rate 115200, I see reliable communication without any framing error for timeout = 125ms. 

    I guess you're right, the timeout shouldn't matter but the timeout is playing some role here and I am confused about that.

  • 1. Yes, It is a 2 way communication. It's called command mode on Zentri with an open com port, I send 
        commands from nRF52840 and receive response from the Zentri AMW007.
    2. There are a set of commands associated with Zentri OS that I can send to set the baud rate and also
        read it back. Here's the link to the resource: 
    3. docs.zentri.com/.../uart
    4. I have an Zentri Eval board with AMW007. I have tested it by connecting it to a PC and sending the       
        same commands with all available baud rates. It works perfectly fine without any timeout.
        Also, The communication doesn't work if the baud rate is not same. I receive no response at the
        Nordic end and which is very much expected for UART communication. 

        NOTE: For baud rate 921600, I do not receive complete data even if the timeout is anywhere
                    between 2000 ms and 5000 ms.

    5.  I have a diagnostics Shell running for user(CLI) and the code flow is like this: 
         I receive a command from the CLI and forward that command to Zentri module using       
         nrf_serial_write()       API and similarly read the data on the bus(response from Zentri) using
         nrf_serial_read() API.

         Here're the code snippet for TX the command to Zentri and RX the response: 

    ret_code_t wlan_serial_tx(void const * p_data, size_t size)
    {
        ret_code_t ret;

        ret = nrf_serial_write(&wlan_serial_uart,
             p_data, size, NULL, 500);

       return ret;
    }


    ret_code_t wlan_serial_read(void * p_data, size_t size, size_t* bytes_read, uint32_t ms_wait)
    {
        ret_code_t ret;

        if (ms_wait)
       {
             ret = nrf_serial_read(&wlan_serial_uart, p_data, size, bytes_read, ms_wait);
       } else {
              ret = nrf_serial_read(&wlan_serial_uart, p_data, size, bytes_read, 1000);
       }
    return ret;
     }

       void wlan_send_to_zentri(char* command)
     {
        ret_code_t ret;
       char full_response[ZENTRI_UART_MAX_BYTES] = {0};
       size_t strsize, bytes_read;
       strsize = strlen(command);

       ret = wlan_serial_tx(command, strsize);
       APP_ERROR_CHECK(ret);

      /* Try to read everything */
      wlan_serial_read(full_response, ZENTRI_UART_MAX_BYTES, &bytes_read, uart_ms_timeout);

      printf("\n%s", full_response);

      /* Flush out the UART */
      while(bytes_read)
      {
         wlan_serial_read(full_response, ZENTRI_UART_MAX_BYTES, &bytes_read);
         if (bytes_read)
        {
           printf("%s", full_response);
        }
      }
     }



    Thanks,
    Akhil


  • Hi,

    So the Zentri eval board works with all baudrates, but if you connect a module directly to the nRF52 only a few baud rates work?

    It could be that the nRF52 isn't able to provide an accurate enough baud rate for your module. As you can see in the specification, the baud rate you want isn't always the baud rate you get. 

    Desired baud rate Actual baud rate Error
    9600 9598 -0.02 %
    14400 14414 0.10 %
    19200 19208 0.04 %
    28800 28829 0.10 %
    38400 38462 0.16 %
    57600 57762 0.28 %
    76800 76923 0.16 %
    115200 115942 0.64 %
    230400 231884 0.64 %
    250000 250000 0.00 %
    460800 470588 2.08 %
    921600 941176 2.08 %

    In addition to the errors here, you will have to factor in the accuracy of the HF clock in your nRF52. This is because the digital logic in the UART is driven by the HF clock and the clock accuracy will hence directly affect the baud rate accuracy. Unless you tell it otherwise, the HF clock is generated by the internal RC oscillator (HFINT) with an accuracy that could be as bad as +-6 %. You can try to force the HF clock to utilize the external crystal (HFXO) as a source instead to increase the accuracy (typ 40 ppm or less). You can turn on the crystal like this:

    NRF_CLOCK->TASKS_HFCLKSTART = 1;
    while(NRF_CLOCK->EVENTS_HFCLKSTARTED == 0)
    {
        ;
    }

    or with the function sd_clock_hfclk_request() if you are using a Softdevice and BLE. 

    I suspect that your Zentri Eval board has an FTDI (UART-to-USB) chip on board with better baud rate accuracy, and maybe that is why they seem to work. 

  • Martin,
    Thank you so much for the info, that was really helpful. I have a few more questions regarding calibrating the Internal RC.

    My hardware setup has 2 nRF52840s- 1 Main and 1 Secondary connected via SPI. The Main chip alone has the external crystals connected and Secondary Nordic (Without external crystal) connected to the Zentri module over UART. Here's a block diagram:


    Do you think there's a way for me to calibrate the Internal RC of secondary chip with main nordic chip's clock? Doing this, I believe will help me to make the communication much more reliable at a baud rate= 921600. 


    Best,
    Akhil
     

  • Happy to help.

    Do you think there's a way for me to calibrate the Internal RC of secondary chip with main nordic chip's clock?
    Unfortunately this is not possible. And note that if you plan to use the radio on your Secondary nRF52840 it will need a HF crystal too. Radio protocols like BLE for example, needs very accurate clock sources (<40 ppm). 

  •  in the specification that you gave, it shows that 1M Baud has 0 error.  But, if we don't use an external HF crystal, is it possible to achieve that? Or will that still be affected by the +-6% error?

    We tried with 1M and it seemed to be more reliable for a longer time, but eventually it breaks down and we seemed to have missed some bytes.  Is it very likely that it's caused by this error?

Reply Children
Related