This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Zigbee and Serial communication issue

Hello Nordic!

I have been developing a Zigbee application and now, I need to connect via Serial communication with another device. I just need to listen to the port, not send any data. Unfortunately I don't have that device so I am simulating it with an Arduino Uno. It is configured as the original device at 19200baud, 8bit, 1 stop bit. First of al, is there any other better way to read data through RX/TX? Any other libraries instead of libuarte?

I found the libuarte example which I modified and make it work for my needs. It reads my Arduino via Serial communication correctly and I obtain the characters nicely. My problem occurs when I try to implement the libuarte code into mine. I have had several problems with the sdk_config file. But once the errors have faded out and the code have compiled, I have flashed it into the nrf52840DK board but the Zigbee and Serial communication suddenly stopped working. Could it be that they share some timer or some other peripheral?

I have tried changing the timer for the serial communication but achieved nothing. What may be causing this issue?

The modified code of the libuarte's example is as follows:

/**
 * Copyright (c) 2018 - 2020, Nordic Semiconductor ASA
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form, except as embedded into a Nordic
 *    Semiconductor ASA integrated circuit in a product or a software update for
 *    such product, must reproduce the above copyright notice, this list of
 *    conditions and the following disclaimer in the documentation and/or other
 *    materials provided with the distribution.
 *
 * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
 *    contributors may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * 4. This software, with or without modification, must only be used with a
 *    Nordic Semiconductor ASA integrated circuit.
 *
 * 5. Any software provided in binary form under this license must not be reverse
 *    engineered, decompiled, modified and/or disassembled.
 *
 * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */
/** @file
 * @defgroup libuarte_example_main main.c
 * @{
 * @ingroup libuarte_example
 * @brief Libuarte Example Application main file.
 *
 * This file contains the source code for a sample application using libuarte.
 *
 */

#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include "nrf_libuarte_async.h"
#include "nrf_drv_clock.h"
#include <bsp.h>
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"
#include "nrf_queue.h"

NRF_LIBUARTE_ASYNC_DEFINE(libuarte, 0, 0, 0, NRF_LIBUARTE_PERIPHERAL_NOT_USED, 255, 3);

static uint8_t text[] = "UART example started.\r\n Loopback:\r\n";
static uint8_t text_size = sizeof(text);
static volatile bool m_loopback_phase;

typedef struct {
    uint8_t * p_data;
    uint32_t length;
} buffer_t;

NRF_QUEUE_DEF(buffer_t, m_buf_queue, 10, NRF_QUEUE_MODE_NO_OVERFLOW);

void uart_event_handler(void * context, nrf_libuarte_async_evt_t * p_evt)
{
    nrf_libuarte_async_t * p_libuarte = (nrf_libuarte_async_t *)context;
    ret_code_t ret;

    switch (p_evt->type)
    {
        case NRF_LIBUARTE_ASYNC_EVT_ERROR:
            bsp_board_led_invert(0);
            break;
        case NRF_LIBUARTE_ASYNC_EVT_RX_DATA:
            ret = nrf_libuarte_async_tx(p_libuarte,p_evt->data.rxtx.p_data, p_evt->data.rxtx.length);
            if (ret == NRF_ERROR_BUSY)
            {
                buffer_t buf = {
                    .p_data = p_evt->data.rxtx.p_data,
                    .length = p_evt->data.rxtx.length,
                };

                ret = nrf_queue_push(&m_buf_queue, &buf);
                APP_ERROR_CHECK(ret);
            }
            else
            {
                APP_ERROR_CHECK(ret);
            }
            bsp_board_led_invert(1);
            m_loopback_phase = true;
            break;
        case NRF_LIBUARTE_ASYNC_EVT_TX_DONE:
            if (m_loopback_phase)
            {
                nrf_libuarte_async_rx_free(p_libuarte, p_evt->data.rxtx.p_data, p_evt->data.rxtx.length);
                if (!nrf_queue_is_empty(&m_buf_queue))
                {
                    buffer_t buf;
                    ret = nrf_queue_pop(&m_buf_queue, &buf);
                    APP_ERROR_CHECK(ret);
                    UNUSED_RETURN_VALUE(nrf_libuarte_async_tx(p_libuarte, buf.p_data, buf.length));
                }
            }
            bsp_board_led_invert(2);
            break;
        default:
            break;
    }
}

/**
 * @brief Function for main application entry.
 */
int main(void)
{
    bsp_board_init(BSP_INIT_LEDS);
    
    ret_code_t ret = nrf_drv_clock_init();
    APP_ERROR_CHECK(ret);
  
    nrf_drv_clock_lfclk_request(NULL);

    ret_code_t err_code = NRF_LOG_INIT(app_timer_cnt_get);
    APP_ERROR_CHECK(err_code);

    NRF_LOG_DEFAULT_BACKENDS_INIT();

    nrf_libuarte_async_config_t nrf_libuarte_async_config = {
            .tx_pin     = TX_PIN_NUMBER,
            .rx_pin     = RX_PIN_NUMBER,
            .baudrate   = NRF_UARTE_BAUDRATE_19200,
            .parity     = NRF_UARTE_PARITY_EXCLUDED,
            .hwfc       = NRF_UARTE_HWFC_DISABLED,
            .timeout_us = 100,
            .int_prio   = APP_IRQ_PRIORITY_LOW
    };

    err_code = nrf_libuarte_async_init(&libuarte, &nrf_libuarte_async_config, uart_event_handler, (void *)&libuarte);

    APP_ERROR_CHECK(err_code);

    nrf_libuarte_async_enable(&libuarte);

    err_code = nrf_libuarte_async_tx(&libuarte, text, text_size);
    APP_ERROR_CHECK(err_code);

    while (true)
    {
        NRF_LOG_FLUSH();
    }
}


/** @} */

Thanks to all in advance!

Cheers!

  • Hello Edvin!

    I finally made it, I have the Serial communication working but I still have some doubts...

    - I receive data via Serial correctly but sometimes I get some communication errors. The most frequent is the error code 1. What does it mean? Where can I find a table/list of the error codes and the associated explanation?

    - When I set the Serial communication, the BLE stops working. I remember seeing something about RTT in my sdk_config file, is this related?. What may be causing this issue? Right now it's not a big problem but I will need to implement BLE in the future so I need to fix this.

    - I also had to delete the APP_ERROR_HANDLER call in the APP_UART_COMMUNICATION_ERROR case in uart_event_handle() function when an error occurs because it was stopping my code. I will have to handle the errror codes manually. For me, there is no problem, but for the board? Is it better to use the error_handler or the error_check than to do it manually?

    Thanks for all your help. As you said, the ble_app_uart gave me the inspiration I needed. OOnce I've cleared my doubts, I will verify the answer and finish this thread.

    Thanks again!

    Cheers!

  • I have continued testing and debugging and I have found something strange... 

    I have tried to follow the path why BLE and UART are not compatible and I have found that they can be compatible, but once some time has passed, the UART communication ends and BLE and Zigbee start working as usual.

    I am not able to understand why this happens....

  • Hi Alejandro,

    Edvin is on leave so I am taking over this thread and will try to assist you. I am not an expert in Zigbee, but I have good understanding on the UART related issues which hopefully will be useful in this case.

    mazis said:
    - I receive data via Serial correctly but sometimes I get some communication errors. The most frequent is the error code 1. What does it mean? Where can I find a table/list of the error codes and the associated explanation?

    I think what you are seeing is somewhat similar to this error. There was a bug where the communication which does not translate the internal hardware error src to library specific error. Probably you should figure out what this error was and how to handle this specific error in your case. 

     

    mazis said:
    - I also had to delete the APP_ERROR_HANDLER call in the APP_UART_COMMUNICATION_ERROR case in uart_event_handle() function when an error occurs because it was stopping my code. I will have to handle the errror codes manually. For me, there is no problem, but for the board? Is it better to use the error_handler or the error_check than to do it manually?

    It is good idea that you handle this errors manually but I recommend you to do it inside the error_handler to make it architecturally same as before.

     

    mazis said:
    Thanks for all your help. As you said, the ble_app_uart gave me the inspiration I needed. OOnce I've cleared my doubts, I will verify the answer and finish this thread.

     Thanks for the kind words and again sorry for the late reply.

  • Hello Susheel!

    From what I read, the problem is that I am not reading the registers fast enough, right? I am not using the FIFO rergister, I don't know if that is relevant. Anyway, I will try to fix it as soon as possible. What do you think is the best approach to solve the issue?

    It is good idea that you handle this errors manually but I recommend you to do it inside the error_handler to make it architecturally same as before.

    What do you mean? Modify the SDK API error_handler function? Would you mind elaborate on this a bit more? I find it pretty interesting to me.

    Furthermore, did you see the last comment I posted? The one below me about the issue with Zigbee and BLE.

    Cheers!

  • mazis said:
    From what I read, the problem is that I am not reading the registers fast enough, right? I am not using the FIFO rergister, I don't know if that is relevant. Anyway, I will try to fix it as soon as possible. What do you think is the best approach to solve the issue?

     Use flow control if possible (change NRF_UARTE_HWFC_DISABLED to NRF_UARTE_HWFC_ENABLED)

    Also try with application uart priority APP_IRQ_PRIORITY_HIGH instead of APP_IRQ_PRIORITY_LOW.

    I think that you are doing a lot of uart post processing, which is causing the hardware FIFO to overflow causing overrun errors. Enabling hardware flow control will greatly reduce the chance of this overrun error. 

     

    mazis said:
    What do you mean? Modify the SDK API error_handler function? Would you mind elaborate on this a bit more? I find it pretty interesting to me.

     No need to change any SDK API, what I mean to say is that when you get any errors and your application is notified using NRF_DRV_UART_EVT_ERROR, then you need to handle it properly. Sometimes you might have to read an extra char from the FIFO to restart the state machine of the underlying driver. Please look at other examples in the SDK that handle this NRF_DRV_UART_EVT_ERROR event.

     

    mazis said:
    Furthermore, did you see the last comment I posted? The one below me about the issue with Zigbee and BLE.

    Not really, that is strange, can you repost the question about Zigbee and BLE? I do not find your specific question regarding the issue with this combo. 

Related