UART21 can't receive RX data

I am using the nRF54L10 chip with NSC-V3.0.0, and I encounter an issue when using uart21 (p2.07–p2.08). If RTT is connected, UART transmission and reception both work normally. However, if RTT is not connected, data is often not received, even though I can see the correct RX waveform on an oscilloscope. If the nRF54L10 sends data and the slave device responds immediately, the nRF54L10 can receive the data. But if the nRF54L10 sends data and the slave device responds after a delay of about 10ms, the nRF54L10 cannot receive the data.

  • Additionally, I have found that my UART is not used in any thread. If I comment out all the k_msleep calls in another thread and let that thread run continuously, the UART works normally. However, if I keep the k_msleep calls, after the UART sends data, if the slave does not respond immediately, the UART on the nRF54 cannot receive the data and the interrupt is not triggered, even though the data waveform is correct.

  • I can use CTS/RTS, the config code is:
    &pinctrl {
        uart21_default: uart21_default {
            group1 {
                psels = <NRF_PSEL(UART_RX, 2, 7)>,
                        <NRF_PSEL(UART_TX, 2, 8)>;
            };
        };

        uart21_sleep: uart21_sleep {
            group1 {
                psels = <NRF_PSEL(UART_RX, 2, 7)>,
                        <NRF_PSEL(UART_TX, 2, 8)>;
                low-power-enable;
            };
        };
    };

    &uart21 {
        status = "okay";
        pinctrl-0 = <&uart21_default>;
        pinctrl-1 = <&uart21_sleep>;
        pinctrl-names = "default", "sleep";
        current-speed = <115200>;  
    };
  • the init function is:

    void hal_app_usart_init(uint32_t baud, hal_app_usart_rx_callback callback)
    {
      int ret = 0;
      if (!device_is_ready(uart))
      {
        LOG_ERR("UART device not ready");
      }
     
      const struct uart_config uart_cfg =
      {
        .baudrate = baud,
        .parity = UART_CFG_PARITY_NONE,
        .stop_bits = UART_CFG_STOP_BITS_1,
        .data_bits = UART_CFG_DATA_BITS_8,
        .flow_ctrl = UART_CFG_FLOW_CTRL_NONE
      };
      ret = uart_configure(uart, &uart_cfg);  
      if (ret == -ENOSYS)
      {
        LOG_ERR("UART configure failed");
      }
      ret = uart_callback_set(uart, uart_cb, NULL);
      if (ret)
      {
        LOG_ERR("UART callback set failed");
      }
    }
    the send function is:
    void hal_app_usart_data_send(uint8_t const *buf, uint16_t len)
    {
        int ret;
        NRF_POWER->TASKS_CONSTLAT = 1;
        ret = uart_tx(uart, buf, len, SYS_FOREVER_MS);
        if (ret)
        {
          LOG_ERR("UART TX failed");
        }
        else
        {
        }
    }
    the receive function is:
    static void uart_cb(const struct device *dev, struct uart_event *evt, void *user_data)
    {
      switch (evt->type)
      {  
        case UART_RX_RDY:
        {
          const uint8_t *buf = evt->data.rx.buf + evt->data.rx.offset;
          size_t len = evt->data.rx.len;
          for (size_t i = 0; i < len; i++)
          {
            _usart_rx_callback(buf[i]);
          }
        }
        break;
        case UART_RX_DISABLED:
          uart_rx_enable(dev, _uart_rx_buffer, sizeof(_uart_rx_buffer), RECEIVE_TIMEOUT);
          s_uart_rx_is_enabled = true;
        break;  
        case UART_TX_DONE:
          uart_rx_enable(dev, _uart_rx_buffer, sizeof(_uart_rx_buffer), RECEIVE_TIMEOUT);
        break;
     
        default:
        break;
      }
    }
  • Can try to use interrupt driven UART instead of async if you need to receive data during sleep?

Related