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 Steve,

    When you tried to change the parity settings in run time, did you add "CONFIG_UART_USE_RUNTIME_CONFIGURE=y" ? By adding this line to prj.conf of l5_e1_sol source code from DevAcademy, I am able to change the UART settings in runtime and verify them by reading back directly the hardware register related to that, without adding this line to prj.conf it is not possible.



    in main file:









    Reading back directly the register settings value:



    Which exactly holds the settings we set in run time. I intentionally put odd parity as it is represented by 1 in register. Tried even and this bit turned to 0 as expected.




    Hopefully it helps to solve your issue.

    Best regards,
    Ressa

  • Thanks for checking!!  Yes, I tried "CONFIG_UART_USE_RUNTIME_CONFIGURE=y" too.  I never checked the register however, only the UART comms which were never using EVEN parity no matter what I tried.  Did you check that UART was actually using the parity ODD or EVEN as you selected?

    By moving things around on my design I've been able to free up an i2c port on the "other" device so I will be using i2c instead of UART... a better chip-to-chip protocol than UART, imo.

  • Hi,

    It did change the data format as the terminal app I use on windows was not able to get the data correctly. But I have not checked it with logic analyzer on the pin directly to verify it bit by bit. I will check it with logic analyzer soon to verify the changes. 
    But for chip to chip communication, I2C is definitely preferred over UART. 

    Best regards,
    Ressa

  • Hi Ressa,

    I'm having similar problems. I'm configuring uart dynamically using:

    static const struct uart_config uart_cfg = {
        .baudrate = 1200,
        .parity = UART_CFG_PARITY_EVEN,
        .stop_bits = UART_CFG_STOP_BITS_1,
        .data_bits = UART_CFG_DATA_BITS_7,
        .flow_ctrl = UART_CFG_FLOW_CTRL_NONE,
    };


    My logic analyzer correctly detects the serial data on rx (7E1, 1200):

    But my uart callback raises parity and frame errors:

    Because of these issues I checked the CONFIG register as you recommended:
    ```

     nrfutil device x-read --x-family nrf54l --address 0x500C656C --width 32 --direct
    1057771197
    0x500C656C: 0000500E                              |.P..|

    ```
    `0101 0000 0000 1110` means:

    1. A = 0 => no hardware control White check mark
    2. BBB = 111 => parity included White check mark
    3. C=0 => one stop bity White check mark
    4. D=0 => even parity White check mark
    5. EEEE=1000=8 => 8 data bits Warning
    6. F️=0 => MSB end trimming White check mark
    7. G=1 => timeout enabledWhite check mark

    Seemingly the frame size seems to be the problem here. I'm not sure how to solve this...

    Manually writing EEEE=1111 fixed the issue (nrfutil device x-write --x-family nrf54l --address 0x500C656C --value 0x00004E0E --direct), but this isn't a good solution.

    Any help would be greatly appreciated!

  • Hey, I found the issue. The nrfx driver does not support 7 data bits, even though the hardware does. I fixed this by changing:

    if (cfg->data_bits != UART_CFG_DATA_BITS_8) {
            return -ENOTSUP;
    }

    to 

    #if NRF_UARTE_HAS_FRAME_SIZE
        switch (cfg->data_bits) {
        case UART_CFG_DATA_BITS_7:
            uarte_cfg.frame_size = NRF_UARTE_FRAME_SIZE_7_BIT;
            break;
        case UART_CFG_DATA_BITS_8:
            uarte_cfg.frame_size = NRF_UARTE_FRAME_SIZE_8_BIT;
            break;
        default:
            return -ENOTSUP;
        }
    #else
        if (cfg->data_bits != UART_CFG_DATA_BITS_8) {
            return -ENOTSUP;
        }
    #endif

    in uart_nrfx_uarte.c. Added to that I removed the line setting uarte_cfg.frame_size to 8.

Reply
  • Hey, I found the issue. The nrfx driver does not support 7 data bits, even though the hardware does. I fixed this by changing:

    if (cfg->data_bits != UART_CFG_DATA_BITS_8) {
            return -ENOTSUP;
    }

    to 

    #if NRF_UARTE_HAS_FRAME_SIZE
        switch (cfg->data_bits) {
        case UART_CFG_DATA_BITS_7:
            uarte_cfg.frame_size = NRF_UARTE_FRAME_SIZE_7_BIT;
            break;
        case UART_CFG_DATA_BITS_8:
            uarte_cfg.frame_size = NRF_UARTE_FRAME_SIZE_8_BIT;
            break;
        default:
            return -ENOTSUP;
        }
    #else
        if (cfg->data_bits != UART_CFG_DATA_BITS_8) {
            return -ENOTSUP;
        }
    #endif

    in uart_nrfx_uarte.c. Added to that I removed the line setting uarte_cfg.frame_size to 8.

Children
No Data
Related