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

Libuarte

Hi I want to set up a simple uarte communication between a NRF52832 and a faulhaber mcdc 3002s motion controller using the libuarte. I have max3232 logic converter in between their respective Tx and rx because mcdc 3002s is an RS232 device.

I want to send the ASCII command "0GYTP/r" to the motion controller from NRF52832 and receive a response. 

The configuration of this setup should be 8 data bits, no parity, 1 stop bit, and no flow control and baudrate 9600

I edited the code a bit to fit mcdc 3002 baud rate configuration and I have a custom board connected to j-link mini edu so I had to change the tx and rx pin according to the custom board.

I am still unsure how to complete what I need to do. 

Things I need to achieve: 

1) Send ASCII transmission of "0GYTP/r"

2) Recieve the corresponding response of the transmission and print it using RTTviewer

Can someone edit the following code and explain in a way so that a beginner like me can understand. 

Thank you

#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[] = "0GYTP/r";
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);
            printf("Status: UARTE peripheral error");
            break;
        case NRF_LIBUARTE_ASYNC_EVT_RX_DATA: //Requested TX transfer completed.
            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);
            }
            printf("Status: case tx tranfer completed");
            m_loopback_phase = true;
            break;
        case NRF_LIBUARTE_ASYNC_EVT_TX_DONE: //Requested RX transfer completed.
            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));
                }
            }
            printf("status: case rx transfer completed");
            break;
        default:
            break;
    }
}

/**
 * @brief Function for main application entry.
 */
int main(void)
{   
    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     = 30,
            .rx_pin     = 31,
            .baudrate   = NRF_UARTE_BAUDRATE_9600,
            .parity     = NRF_UARTE_PARITY_EXCLUDED,
            .hwfc       = NRF_UARTE_HWFC_DISABLED,
            .timeout_us = 1000,
            .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();
    }
}


/** @} */

Parents
  • Hello,

    What you probably want to do is to trigger the sending using nrf_libuarte_async_tx() like it is used in this example. I don't know when you want to trigger it. Perhaps you want to start an app_timer and trigger the sending from the timeout handler, or set up a button handler and trigger it from there. 

    You don't need to use the queue library at all.

    Then, whenever the other device replies, it will trigger the NRF_LIBUARTE_ASyNC_EVT_RX_DATA event, containing the p_evt->data.rxtx.p_data, and p_evt->data.rxtx.length with the reply starting on the ...rxtx.p_data pointer, with the length = ...rxtx.length.

    If you want an example on how to set up and use the app_timer, I suggest you check out the ble_app_hrs example from SDK\examples\ble_peripheral\ble_app_hrs.

    Note: If you intend to use the libuarte library in an example that uses the softdevice (bluetooth stack), then please be aware that TIMER0 and RTC0 is used by the softdevice, so you need to adjust your NRF_LIBUARTE_ASYNC_DEFINE() in that case.  The macro expands to:

    #define NRF_LIBUARTE_ASYNC_DEFINE(_name, _uarte_idx, _timer0_idx,\
                                      _rtc1_idx, _timer1_idx,\
                                      _rx_buf_size, _rx_buf_cnt) \

    So parameter nr 3 is the timer instance, parameter 4 is the RTC instance and parameter 5 is the other timer instance. Note that the libuarte library is quite resource heavy. Unless you really need it, I would suggest you check out the ble_app_uart example from sdk\examples\ble_peripheral\ble_app_uart. It uses a UART library that is a bit more simple. If you have a reason to use the libuarte library, that is fine, but in case it was the first thing you stumbled upon, I suggest you check it out.

    Best regards,

    Edvin

Reply
  • Hello,

    What you probably want to do is to trigger the sending using nrf_libuarte_async_tx() like it is used in this example. I don't know when you want to trigger it. Perhaps you want to start an app_timer and trigger the sending from the timeout handler, or set up a button handler and trigger it from there. 

    You don't need to use the queue library at all.

    Then, whenever the other device replies, it will trigger the NRF_LIBUARTE_ASyNC_EVT_RX_DATA event, containing the p_evt->data.rxtx.p_data, and p_evt->data.rxtx.length with the reply starting on the ...rxtx.p_data pointer, with the length = ...rxtx.length.

    If you want an example on how to set up and use the app_timer, I suggest you check out the ble_app_hrs example from SDK\examples\ble_peripheral\ble_app_hrs.

    Note: If you intend to use the libuarte library in an example that uses the softdevice (bluetooth stack), then please be aware that TIMER0 and RTC0 is used by the softdevice, so you need to adjust your NRF_LIBUARTE_ASYNC_DEFINE() in that case.  The macro expands to:

    #define NRF_LIBUARTE_ASYNC_DEFINE(_name, _uarte_idx, _timer0_idx,\
                                      _rtc1_idx, _timer1_idx,\
                                      _rx_buf_size, _rx_buf_cnt) \

    So parameter nr 3 is the timer instance, parameter 4 is the RTC instance and parameter 5 is the other timer instance. Note that the libuarte library is quite resource heavy. Unless you really need it, I would suggest you check out the ble_app_uart example from sdk\examples\ble_peripheral\ble_app_uart. It uses a UART library that is a bit more simple. If you have a reason to use the libuarte library, that is fine, but in case it was the first thing you stumbled upon, I suggest you check it out.

    Best regards,

    Edvin

Children
No Data
Related