This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

UART connection's Rx error when BT enabled

Hi,

I have been using an UART connection for serial communication but it stops working when I enable the Bluetooth module and initialize it. The error I receive is the same as if I connected the UART's Rx pin to GND.

UART overlay definition, also tried using the uart2 but it also fails.

&uart1 {
    status = "okay";
    tx-pin = <34>;   //For pins P1.0 through P1.31, add 32 to the pin number.
    rx-pin = <33>;   //For pins P1.0 through P1.31, add 32 to the pin number.
};

Bluetooth configuration

CONFIG_BT=y
CONFIG_BT_SMP=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_ATT_PREPARE_COUNT=5
CONFIG_BT_SETTINGS=y
CONFIG_BT_PRIVACY=y
CONFIG_BT_DIS=y
CONFIG_BT_BAS=y

UART Error Messages

<err> : UART rx stopped, reason: 4
<err> : UART rx stopped, reason: 8

I even tried connecting directly the power source pin to the RX pin but it still fails.

  • Hi there,

    What other peripherals do you initialize in your project? Could you share more of your code which shows where the UART functions are called.

    regards

    Jared 

  • Hi,

    Besides the UART_1 I only initialize some buttons and leds, also the log console (UART_0) is enabled.

    Code for the UART initialization:
    #define UART_BUF_SIZE (uint8_t)128
    #define UART_RX_MSG_QUEUE_SIZE (uint8_t)16
    #define UART_RX_TIMEOUT_MS (uint16_t)1000
    
    static uint8_t uart_double_buffer[2][UART_BUF_SIZE];
    static uint8_t *uart_buf_next = uart_double_buffer[1];
    
    static void uart_async_callback(const struct device *uart_dev, struct uart_event *evt, void *user_data)
    {
        static struct uart_msg_queue_item_t new_message;
        int rc;
    
        LOG_DBG("New Uart Event %d", evt->type);
    
        switch (evt->type)
        {
        case UART_TX_DONE:
            // Free up the written bytes in the TX FIFO
            ring_buf_get_finish(&app_tx_fifo, bytes_claimed);
    
            // If there is more data in the TX fifo, start the transmission
            if (uart_tx_get_from_queue() == ReturnCode_ok)
            {
                // Or release the semaphore if the TX fifo is empty
                k_sem_give(&tx_done);
            }
            break;
    
        case UART_RX_RDY:
            memcpy(new_message.bytes, evt->data.rx.buf + evt->data.rx.offset, evt->data.rx.len);
            new_message.length = evt->data.rx.len;
    
            if (k_msgq_put(&uart_rx_msgq, &new_message, K_NO_WAIT) != 0)
            {
                LOG_ERR("Error: Uart RX message queue full!");
            }
    
            break;
    
        case UART_RX_BUF_REQUEST:
            rc = uart_rx_buf_rsp(gDev_uart, uart_buf_next, UART_BUF_SIZE);
            if (rc != 0)
            {
                LOG_ERR("Failed UART rx, error=%d", rc);
                return;
            }
            break;
    
        case UART_RX_BUF_RELEASED:
            uart_buf_next = evt->data.rx_buf.buf;
            break;
    
        case UART_RX_DISABLED:
            break;
        case UART_RX_STOPPED:
            // ERROR RECEIVED HERE
            LOG_ERR("UART rx stopped, reason: %d", evt->data.rx_stop.reason);
            break;
        default:
            break;
        }
    }
    
    int uart_init()
    {
        // Get device reference
        gDev_uart = device_get_binding("UART_1");
        if (gDev_uart == NULL)
        {
            LOG_ERR("Failed to get UART binding");
            return -1;
        }
    
        // Configure the UART device
        struct uart_config uart_config = {.baudrate = 115200, .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};
        int rc = uart_configure(gDev_uart, &uart_config);
        if (rc != 0)
        {
            LOG_ERR("Failed to set UART configuration, error=%d", rc);
            return rc;
        }
    
        rc = uart_callback_set(gDev_uart, uart_async_callback, NULL);
        if (rc != 0)
        {
            LOG_ERR("Failed to set UART callback, error=%d", rc);
            return rc;
        }
    
        return 0;
    }
    
    int uart_enable()
    {
        int rc = uart_rx_enable(gDev_uart, uart_double_buffer[0], UART_BUF_SIZE, UART_RX_TIMEOUT_MS);
        if (rc != 0)
        {
            LOG_ERR("Failed to enable UART rx, error=%d", rc);
            return rc;
        }
    
        LOG_INF("The UART connection has been enabled");
    
        return 0;
    }
    Code for the bluetooth:
    int bt_init()
    {
        int rc = bt_enable(NULL);
        if (rc)
        {
            LOG_ERR("BT init failed (err %d)\n", rc);
            return rc;
        }
    
        LOG_DBG("Bluetooth initialized");
    
        bt_conn_cb_register(&conn_callbacks);
    
        rc = bt_conn_auth_cb_register(&conn_auth_callbacks);
        if (rc)
        {
            LOG_ERR("Failed to register authorization callbacks\n");
            return rc;
        }
    
        return 0;
    }
    
    int bt_adv_start()
    {
        int rc = bt_le_adv_start(BT_LE_ADV_CONN_NAME, ad, ARRAY_SIZE(ad), NULL, 0);
        if (rc)
        {
            LOG_ERR("Advertising failed to start (err %d)\n", rc);
            return rc;
        }
    
        LOG_DBG("Advertising successfully started\n");
    
        return 0;
    }
    The execution order of the methods above in the main function is bt_init, bt_adv_start, uart_init and uart_enable. The Error is received in the UART callback almost immediately.
    I am using the SDK 1.8.0.

    regards

    Erasmo
  • Hi,

    Error 8 and 4 is framing and break errors, and is usually due to floating RX pins. Could you check what core that is assigned to pin 34 and 35 by reading out the G field of CNF register for pin 34 and 35? 

    regards
    Jared 

  • Hi,

    I executed this code before and after the UART is enabled to get the values you asked for (in both cases the result is the same).

    Code:

    uint32_t pin_33 = 33; // rx pin
    uint32_t pin_34 = 34; // tx pin
    uint32_t pin_35 = 35;
    NRF_GPIO_Type *reg;
    
    reg = nrf_gpio_pin_port_decode(&pin_33); // pin number is reduced by 32, modified to be the index of the array
    
    LOG_INF("Pin [%d], CNF value [%d], G field value [%d]", pin_33 + 32,
            reg->PIN_CNF[pin_33], (uint32_t)((reg->PIN_CNF[pin_33] & GPIO_PIN_CNF_MCUSEL_Msk) >> GPIO_PIN_CNF_MCUSEL_Pos));
    
    reg = nrf_gpio_pin_port_decode(&pin_34); // pin number is reduced by 32, modified to be the index of the array
    
    LOG_INF("Pin [%d], CNF value [%d], G field value [%d]", pin_34 + 32,
            reg->PIN_CNF[pin_34], (uint32_t)((reg->PIN_CNF[pin_34] & GPIO_PIN_CNF_MCUSEL_Msk) >> GPIO_PIN_CNF_MCUSEL_Pos));
    
    reg = nrf_gpio_pin_port_decode(&pin_35); // pin number is reduced by 32, modified to be the index of the array
    
    LOG_INF("Pin [%d], CNF value [%d], G field value [%d]", pin_35 + 32,
            reg->PIN_CNF[pin_35], (uint32_t)((reg->PIN_CNF[pin_35] & GPIO_PIN_CNF_MCUSEL_Msk) >> GPIO_PIN_CNF_MCUSEL_Pos));

    Result:

    PIN [33], CNF value [268435456], G field value [1]
    PIN [34], CNF value [3], G field value [0]
    PIN [35], CNF value [2], G field value [0]

    It seems that the RX pin is managed by the Network MCU, should I change the pin's selected MCU? or does is recommendable not to change it and use another pin?

    regards

    Erasmo

  • Erasmo said:
    It seems that the RX pin is managed by the Network MCU, should I change the pin's selected MCU? or does is recommendable not to change it and use another pin?

    Interesting, this means that the pins are used by the fw that is flashed on the network core. I would suggest that you use other pins then these for your uart on the app core. Can you try to change pins and see if it still asserts?

    regards

    Jared

Related