Framing error and noisy data when using UARTE at high baud rate

Hello, in my zephyr application, I have uart1 configured as receive only using uarte at 921600 baud rate. Below is the description node:

&uart1 {
	compatible = "nordic,nrf-uarte";
	label = "data_uart";
	current-speed = <921600>;
	status = "okay";
	rx-pin = <30>;
};
 

I have a device sending a uart packet every 50ms and although I can see the right number of bytes being received, the data itself is corrupted (some bytes are correct but some are not) and I get a framing error thrown by the IRQ for every packet. I scoped the signal and it is very clean. I have also connected a terminal software (minicom) and I was able to receive the expected data while nrf52833 cannot. I do have another uart running on the same SoC (uart0) and that one is working fine but it is running at 115200 baud rate. I am not sure if I have to do anything special due to the high baud rate. I thought the DMA should help and I have allocated a timer for the byte processing. Here are my config statements:

#uart
CONFIG_SERIAL=y
CONFIG_UART_ASYNC_API=y
CONFIG_UART_0_ASYNC=y
CONFIG_UART_0_NRF_HW_ASYNC=y
CONFIG_UART_0_NRF_HW_ASYNC_TIMER=2
CONFIG_UART_0_NRF_ASYNC_LOW_POWER=y
CONFIG_UART_1_ASYNC=y
CONFIG_UART_1_NRF_HW_ASYNC=y
CONFIG_UART_1_NRF_HW_ASYNC_TIMER=4
CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL=y 
CONFIG_CLOCK_CONTROL_NRF_K32SRC_20PPM=y

I thought maybe it is a clock issue but my understanding is the system automatically enables the HFCLK. The datasheet mentions a note about the pin drive strength for high baud rate but since I am not transmitting, I don't think this is related to my case. Please let me know if I am missing anything. Thank you.

Parents
  • Hello Moose,

    The baudrate 921600 is not supported as the the actual baud you get is too far ''off'' the target frequency. You can try with the 1M baud instead. 

    Best Regards,

    Kazi Afroza Sultana

  • The quoted values are not all correct so you will get much better performance if you bypass the value currently used; this table is a little dated now (some of the data sheets have a few corrections) but here are my detailed calculations:

    typedef struct {
       uint32_t QuotedRegisterValue;
       uint32_t RequiredBaudRate;
       uint32_t QuotedActualBaudRate;
       uint32_t CalculatedRegisterValue;
       uint32_t CalculatedActualBaudRate;
       char     DoesRegisterMatch[RESULT_STRING_LENGTH];
    } BaudCheck_t;
    // Quoted values from nRF52832 v1.4 datasheet
    static BaudCheck_t BaudCheck[] = {
    //  -------Documentation---------   -------Calculated---------
    //  Register    Required   Actual    Register    Actual    Ok?      Index
    //  ==========  ========   ======   ==========   ======   ====      =====
       {0x0004F000,     1200,    1205,  0x0004F000,    1205, " Ok"},  //  0
       {0x0009D000,     2400,    2396,  0x0009D000,    2395, " Ok"},  //  1
       {0x0013B000,     4800,    4808,  0x0013B000,    4806, " Ok"},  //  2
       {0x00275000,     9600,    9598,  0x00275000,    9597, " Ok"},  //  3
       {0x003AF000,    14400,   14401,  0x003B0000,   14404, "  -"},  //  4
       {0x004EA000,    19200,   19208,  0x004EA000,   19195, " Ok"},  //  5
       {0x0075C000,    28800,   28777,  0x0075F000,   28793, "  -"},  //  6
       {0x009D0000,    38400,   38369,  0x009D5000,   38406, "  -"},  //  7
       {0x00EB0000,    57600,   57554,  0x00EBF000,   57601, "  -"},  //  8
       {0x013A9000,    76800,   76923,  0x013A9000,   76797, " Ok"},  //  9
       {0x01D60000,   115200,  115108,  0x01D7E000,  115203, "  -"},  // 10
       {0x03B00000,   230400,  231884,  0x03AFB000,  230392, "  -"},  // 11
       {0x04000000,   250000,  250000,  0x04000000,  250000, " Ok"},  // 12
       {0x07400000,   460800,  457143,  0x075F7000,  460800, "  -"},  // 13
       {0x0F000000,   921600,  941176,  0x0EBEE000,  921600, "  -"},  // 14
       {0x10000000,  1000000, 1000000,  0x10000000, 1000000, " Ok"}}; // 15
    #define NUM_BAUD_TESTS (sizeof(BaudCheck)/sizeof(BaudCheck[0]))
    

    I posted the code I wrote required to generate this data here baudrate-register

Reply
  • The quoted values are not all correct so you will get much better performance if you bypass the value currently used; this table is a little dated now (some of the data sheets have a few corrections) but here are my detailed calculations:

    typedef struct {
       uint32_t QuotedRegisterValue;
       uint32_t RequiredBaudRate;
       uint32_t QuotedActualBaudRate;
       uint32_t CalculatedRegisterValue;
       uint32_t CalculatedActualBaudRate;
       char     DoesRegisterMatch[RESULT_STRING_LENGTH];
    } BaudCheck_t;
    // Quoted values from nRF52832 v1.4 datasheet
    static BaudCheck_t BaudCheck[] = {
    //  -------Documentation---------   -------Calculated---------
    //  Register    Required   Actual    Register    Actual    Ok?      Index
    //  ==========  ========   ======   ==========   ======   ====      =====
       {0x0004F000,     1200,    1205,  0x0004F000,    1205, " Ok"},  //  0
       {0x0009D000,     2400,    2396,  0x0009D000,    2395, " Ok"},  //  1
       {0x0013B000,     4800,    4808,  0x0013B000,    4806, " Ok"},  //  2
       {0x00275000,     9600,    9598,  0x00275000,    9597, " Ok"},  //  3
       {0x003AF000,    14400,   14401,  0x003B0000,   14404, "  -"},  //  4
       {0x004EA000,    19200,   19208,  0x004EA000,   19195, " Ok"},  //  5
       {0x0075C000,    28800,   28777,  0x0075F000,   28793, "  -"},  //  6
       {0x009D0000,    38400,   38369,  0x009D5000,   38406, "  -"},  //  7
       {0x00EB0000,    57600,   57554,  0x00EBF000,   57601, "  -"},  //  8
       {0x013A9000,    76800,   76923,  0x013A9000,   76797, " Ok"},  //  9
       {0x01D60000,   115200,  115108,  0x01D7E000,  115203, "  -"},  // 10
       {0x03B00000,   230400,  231884,  0x03AFB000,  230392, "  -"},  // 11
       {0x04000000,   250000,  250000,  0x04000000,  250000, " Ok"},  // 12
       {0x07400000,   460800,  457143,  0x075F7000,  460800, "  -"},  // 13
       {0x0F000000,   921600,  941176,  0x0EBEE000,  921600, "  -"},  // 14
       {0x10000000,  1000000, 1000000,  0x10000000, 1000000, " Ok"}}; // 15
    #define NUM_BAUD_TESTS (sizeof(BaudCheck)/sizeof(BaudCheck[0]))
    

    I posted the code I wrote required to generate this data here baudrate-register

Children
Related