UART_RX_STOPPED in NCS 2.7.0 nRF52832

Hello,

I have an application that I have been working on that is based off of the peripheral_uart example.  I plan on attaching the device to a computer with a serial cable to perform a configuration and calibration operation.  The process consists of several messages that go back and forth from the PC to the board and back to the PC.  Typing commands to the device, the device seems to work fine and I can get the responses I expect.  When I am using the PC application, after a period of time, I see the device get the UART_RX_STOPPED event.  In the peripheral_uart example there is no case for the UART_RX_STOPPED. 

What is the best method for resetting or re-enabling the UART so the device will receive more transmissions? 

Parents Reply Children
  • Hello,

    In my code, for some reason I had removed

    disable_req = true;
    uart_rx_disable(uart);

    Replacing those lines made the application do much better at parsing incoming messages. 

    As part of my calibration, the device has analog voltage applied to the device and monitors the this signals.  As the device, is progressing through the calbration step in my application, the device will transmit (via UART) the analog value it measured.  I can see my device go through this process but at some point it seems like the device stops responding to messages that should be seen on the UART RX pins.  The device is still sending out TX messages so I can tell that the UART is still transmitting. I have tried to look and see what the UART register settings are prior to starting the calibration process and also what the settings are once the device stops responding to data on the RX lines but I don't see what is wrong.


    EDIT

    Looking at the registers after/during my calibration, the only difference that I see is that SHORTS register is all 0, instead of being 0x0000 0020.  This looks to be the Shortcut between Events_ENDRX and Tasks_STARTRX.

  • So one item I failed to share is that I was attempting to do some debugging my code so instead of using the Bluetooth connection, I had commented out the functionality that enabled the Bluetooth.


        err = bt_enable(NULL);
        if (err) {
            error();
        }

        LOG_INF("Bluetooth initialized");

        k_sem_give(&ble_init_ok);

        if (IS_ENABLED(CONFIG_SETTINGS)) {
            settings_load();
        }

        err = bt_nus_init(&nus_cb);
        if (err) {
            LOG_ERR("Failed to initialize UART service (err: %d)", err);
            return 0;
        }

        err = bt_le_adv_start(BT_LE_ADV_CONN, ad, ARRAY_SIZE(ad), sd,
                      ARRAY_SIZE(sd));
        if (err) {
            LOG_ERR("Advertising failed to start (err %d)", err);
            return 0;
        }

    Looking at a different post, the Nordic support made mention that the peripheral_uart example was doing a read of the UART in the ble_write_thread.

    void ble_write_thread(void)
    {
        /* Don't go any further until BLE is initialized */
        k_sem_take(&ble_init_ok, K_FOREVER);
        struct uart_data_t nus_data = {
            .len = 0,
        };

        for (;;) {
            /* Wait indefinitely for data to be sent over bluetooth */
            struct uart_data_t *buf = k_fifo_get(&fifo_uart_rx_data,
                                 K_FOREVER);

            int plen = MIN(sizeof(nus_data.data) - nus_data.len, buf->len);
            int loc = 0;

            while (plen > 0) {
                memcpy(&nus_data.data[nus_data.len], &buf->data[loc], plen);
                nus_data.len += plen;
                loc += plen;

                if (nus_data.len >= sizeof(nus_data.data) ||
                   (nus_data.data[nus_data.len - 1] == '\n') ||
                   (nus_data.data[nus_data.len - 1] == '\r')) {
                    if (bt_nus_send(NULL, nus_data.data, nus_data.len)) {
                        LOG_WRN("Failed to send data over BLE connection");
                    }
                    nus_data.len = 0;
                }

                plen = MIN(sizeof(nus_data.data), buf->len - loc);
            }

            k_free(buf);
        }
    }

    K_THREAD_DEFINE(ble_write_thread_id, STACKSIZE, ble_write_thread, NULL, NULL,
            NULL, PRIORITY, 0, 0);

    Looking at code, it looks like this ble_write_thread was calling a function to free up the buffer used for UART RX. 

    If I want to be able to debug the code, what is the best method for freeing up the buffer used for the UART RX?

    My goal was to get all of the UART functionality working (without Bluetooth working) so I could stop and start the code without having to restart over and over.

    Thanks.

  • Hi,

    jablackann said:
    Looking at the registers after/during my calibration, the only difference that I see is that SHORTS register is all 0, instead of being 0x0000 0020.  This looks to be the Shortcut between Events_ENDRX and Tasks_STARTRX.

    Ok, so somehow the ENDRX and STARTRX is disabled and this results in the RX being disabled. 

    If you search for k_free in the code, then you'll see that the buffer is freed several places in the sample. 

    If you share your sample, then I can take a look at it and see if I can find anything that would cause the RX to stop.

    regards

    Jared

Related