Using UARTE in nRF52832

Hi,

I want to receive some data in my nRF52832 from MATLAB over UART and send some other data from nRF52832 back to MATLAB. I need some bandwidth for data transfer from nRF to MATLAB so I'd like to use EasyDMA. 

I have started by trying to get some data from MATLAB. This is my code:

#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>

#include "app_uart.h"
#include "app_error.h"
#include "nrf_delay.h"
#include "nrf.h"
#include "nordic_common.h"
#include "bsp.h"
#include "boards.h"
#include "nrf_uarte.h"

#define UART_TX_BUFF_SIZE 128
#define UART_RX_BUFF_SIZE 128

void uart_config(void);
void uart_event_handler(app_uart_evt_t * p_event);

int main(void) {

  bsp_board_init(BSP_INIT_LEDS);

  uart_config();

  //printf("Hello\r\n");

  while(true) {
    bsp_board_led_invert(0);
    nrf_delay_ms(500);
  }

}

void uart_config(void) {

  uint32_t err_code;

  const app_uart_comm_params_t com_params = { RX_PIN_NUMBER, 
                                              TX_PIN_NUMBER,
                                              RTS_PIN_NUMBER,
                                              CTS_PIN_NUMBER,
                                              APP_UART_FLOW_CONTROL_DISABLED,
                                              false, 
                                              NRF_UARTE_BAUDRATE_115200 };

  APP_UART_FIFO_INIT(&com_params,
                     UART_RX_BUFF_SIZE,
                     UART_TX_BUFF_SIZE,
                     uart_event_handler,
                     APP_IRQ_PRIORITY_LOWEST,
                     err_code);

  APP_ERROR_CHECK(err_code);

}

void uart_event_handler(app_uart_evt_t * p_event) {

  uint8_t c;

  if (p_event->evt_type == APP_UART_COMMUNICATION_ERROR) {
    APP_ERROR_HANDLER(p_event->data.error_communication);
  }
  else if (p_event->evt_type == APP_UART_FIFO_ERROR) {
    APP_ERROR_HANDLER(p_event->data.error_code);
  }
  else if (p_event->evt_type == APP_UART_DATA_READY) {
    app_uart_get(&c);

    bsp_board_led_invert(1);
  }


}

When I try to connect over UART with SES's Terminal Emulator, I get this error:

MATLAB also throws an error when I try to send some data over UART.

Any help is much appreciated.

EDIT: I found that printf() was causing problems. The code I have attached is working but I am not using DMA, but reading every byte that is entering through UART. I found that nrf_libuarte_async is the proper library for handling UARTE communications, right?

PD: Just in case this opinion is useful for Nordic's SDK team. I am an analog integrated circuits designer. I have some minor experience writing firmware in PIC microcontrollers both in assembly language and C. With that background, developing even simple software in nRF52832 is being quite a nightmare. The SDK is all messy. As an example: searching for hints for the UART implementation, I found nrfx_uart.c, nrfx_uarte.c and app_uart_fifo.c. How can there be three libraries for one peripheral? Importing the correct libraries and headers into the project and configuring the sdk_config.h is also quite obscure.

  • Hello,

    I am sorry that your first impression of the SDK is not good. 

    I found that nrf_libuarte_async is the proper library for handling UARTE communications, right?

    That is correct. The libuarte library, which is demonstrated in the example found in SDK\examples\peripheral\libuarte is designed to collect multiple bytes into a string that either fills up the buffer size, or times out.

    Remember that there is no "message size" in UART. It is just a "simple" protocol sending byte by byte. One way to work around this, which is probably the most common way, is to have either a set message length, that you know that the other device will send, or to use some special byte to mark as the end of the string ('\n' is commonly used). If you have an option to do that, since you are sending the data yourself from Matlab, I would recommend to just keep receiving bytes, and look for the "stop" byte that you have decided on. This is more or less what the ble_app_uart (SDK\examples\ble_peripheral\ble_app_uart) example is doing. It will trigger on either the stop byte or when the buffer is full. 

    If that doesn't suit your use case, then you can use the libuarte. Just note that this driver demands some more resources to run (more timers). 

    Best regards,

    Edvin

  • Hello,

    Thank you very much for your response.

    I get that developing an SDK for an SoC/SoP must be really tough. Some people want high-level libraries and others prefer functions closer to the hardware level. However, I think that even simple firmware development is quite hard on the nRF SDK. Maybe the whole product is targeted to actual firmware developers (I am not).

    Getting to the actual point. I have a MATLAB app for passing some parameters to the nRF through UART. Then, the nRF programs and controls some electronics on my board. Also, I want to transfer some real-time data back to MATLAB. Thus, I guess that I better implement UARTE. I will take a look at the example in SDK\examples\peripheral\libuarte.

Related