Can't change UART parity

How to change the parity bit on UART on NRF54L15?

prj.conf includes:

CONFIG_SERIAL=y
CONFIG_UART_20_NRF_PARITY_BIT=y

DT overlay includes:

&uart20 {
    parity = "even";
};

Also tried:

const struct uart_config uart_cfg = {
    .baudrate = 115200,
    .parity = UART_CFG_PARITY_EVEN,
    .stop_bits = UART_CFG_STOP_BITS_1,
    .data_bits = UART_CFG_DATA_BITS_8,
    .flow_ctrl = UART_CFG_FLOW_CTRL_NONE
};

Then..
    while(!device_is_ready(uart_dev));

    int err = uart_configure(uart_dev, &uart_cfg);
    while(err == -ENOSYS);

..but err = -134 (-ENOSUP?)

Using Polling:

    //Test 1
    //Check for UART traffic
    unsigned char uartRxBuff[20];
    uartRxBuff[0] = 0;
    int n = uart_poll_in(uart_dev, &uartRxBuff[0]);
    if(uartRxBuff[0] != 0)
    //if(uartRxBuff[0] == 0x79)
    {
        uartRxBuff[0] = 0x9f;
        uart_poll_out(uart_dev, uartRxBuff[0]);
    }

With Even parity on the other UART device it receives: 0x1f, if I send 0x1f in above code the other device receives 0x9f!  Same deal with data received by NRF54L15 - the MSBit is flipped.  If I switch the other device to parity=NONE (test FW - the actual FW is fixed at EVEN parity) the data comes thru correctly.

I was also unable to change the default UART20 RX/TX pins with the overlay - maybe it's the same problem??  It seems the overlay is ignored regarding UART20.

Is changing parity supported?  Is there some conflict with TF-M or logging?  How to change parity?  The 'other' device uses EVEN parity and it cannot be changed. 

Thanks!

Parents
  • Hi,

    Thanks for contacting us. Changing the parity for UART communication is supported. Please check DevAcademy to see if there is anything missing in your configuration.: UART Driver - Nordic Developer Academy
    Also please try to have either of below lines in your configuration file, I don't see any of them:

    CONFIG_UART_INTERRUPT_DRIVEN=y
    CONFIG_UART_ASYNC_API=y

    Also try to use both secure and non secure builds in build configuration, to see if you see any difference:



    * Are you able to change other settings like baud rate ? or it is just parity? 


    Best regards,
    Ressa



  • Thanks for your reply!

    I included:

    CONFIG_UART_INTERRUPT_DRIVEN=y

    CONFIG_UART_ASYNC_API=y

    Couldn't receive anything on UART, so these made things worse.  Maybe because I'm using POLLING?
    so tried:
    CONFIG_UART_INTERRUPT_DRIVEN=n
    CONFIG_UART_ASYNC_API=n
    But no help.  Can receive and send, but not with EVEN parity.
    Tried "secure" and "non-secure" builds... no change.
    The Academy Lesson 5 mentions configuring the UART, but then it isn't included in the exercise code.  Without any context, it isn't clear how to configure with the method mentioned, which is different than changing it in Devicetree.  Two different methods, which one is correct?  .. it seems neither work for me.
    I can change the baud rate in Devicetree.  115200 and 9600 both work.
  • I also tried using NRFX:

    #include "nrfx_uarte.h"

    static const nrfx_uarte_t uarte20 = NRFX_UARTE_INSTANCE(20);

    #define UART20_TX_PIN  NRF_GPIO_PIN_MAP(1,4)
    #define UART20_RX_PIN  NRF_GPIO_PIN_MAP(1,5)

    void uart20_init(void)
    {

        nrfx_uarte_config_t config = NRFX_UARTE_DEFAULT_CONFIG(UART20_TX_PIN, UART20_RX_PIN);
        config.baudrate = NRF_UARTE_BAUDRATE_115200;   // choose your baud rate
        config.parity = NRF_UARTE_PARITY_INCLUDED;     // <<-- parity included = EVEN on Nordic

        ret_code_t err = nrfx_uarte_init(&uarte20, &config, uarte20_event_handler);
        if (err != NRFX_SUCCESS) {
            /* handle error */
        }

    }

    But UART is still using parity=NONE. 

  • Hi,

    After setting the parity mode, can you check the below register value by reading it directly from nRFUTIL, not sure if you are testing it on DK or not though, it gives good insight to see what is happening behind:
    UARTE — Universal asynchronous receiver/transmitter with EasyDMA

    The register address for UART20 setting is: 0x500C656C, by reading the value you can decode it by looking at above link. Or just share it here.



    You can also directly write to this register using nrfutil

    * Regarding the below lines, I meant to use one of them at a time not both, so still worth to try:

    CONFIG_UART_INTERRUPT_DRIVEN=y

    or

    CONFIG_UART_ASYNC_API=y


    Best regards,
    Ressa


Reply Children
  • Thanks again!

    I've given up on UART with EVEN parity on the NRF54L15.  I already removed all the UART code from my project, so I'm unable to check the register.

    If I did check that register and the EVEN parity bit was set (or the "included" bit if that's the bit we're interested in) then what?  Or if the opposite was true and the bit was not set after all the different methods I used, then what?

    I also tried (before I gave up):

    void uarte20_set_even_parity(void)
    {
        // Stop ongoing transfers and disable peripheral before changing CONFIG
        //NRF_UARTE20->TASKS_STOPRX = 1;
        //NRF_UARTE20->TASKS_STOPTX = 1;
        // Wait for STOP tasks to take effect if needed (poll EVENTS_STOPPED), or ensure app logic is idle.

        // If the peripheral has an ENABLE register, disable it first (optional but safe):
        NRF_UARTE20->ENABLE = UARTE_ENABLE_ENABLE_Disabled;

        // Set parity to "Included" (even). These macros come from the device header:
        NRF_UARTE20->CONFIG = (NRF_UARTE20->CONFIG & ~UARTE_CONFIG_PARITY_Msk)
                              | (UARTE_CONFIG_PARITY_Included << UARTE_CONFIG_PARITY_Pos);

        // Re-enable peripheral if you need to:
        NRF_UARTE20->ENABLE = UARTE_ENABLE_ENABLE_Enabled;
    }
    AND:

    void uarte20_set_even_parity_alt(void)
    {
        //NRF_UARTE20->TASKS_STOPRX = 1;
        //NRF_UARTE20->TASKS_STOPTX = 1;
        NRF_UARTE20->ENABLE = UARTE_ENABLE_ENABLE_Disabled;

        // Some headers also provide NRF_UARTE_PARITY_INCLUDED (nrfx naming).
        NRF_UARTE20->CONFIG = (NRF_UARTE20->CONFIG & ~UARTE_CONFIG_PARITY_Msk)
                              | (NRF_UARTE_PARITY_INCLUDED << UARTE_CONFIG_PARITY_Pos);

        NRF_UARTE20->ENABLE = UARTE_ENABLE_ENABLE_Enabled;
    }

  • Hi, 

    I will try to replicate it from scratch on my side. Will get back to you soon. 

    Best regards,
    Ressa

Related