How to reduce UART RX Latency

yudopplyr
Posts: 2
Joined: Tue Dec 18, 2018 3:15 pm

How to reduce UART RX Latency

Postby yudopplyr » Tue Dec 18, 2018 4:33 pm

Hi guys, I am implementing an interrupt handler for reception of data through the UART of the ESP32. Ive measured the response by sending the same data I recieve through the TX output of the UART. The problem is that I want to reduce the current latency time I have (2 ms). Is there any way of getting the UART data at less than 300 microseconds (for a baud rate of 38.4 kbs)?

Note: In general I need to respond to the incoming uart data in less or equal time of 11/baud_rate (which is the duration of sending a uart frame)

Image

Code: Select all

/*
  UART Interrupt Example
*/
#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "freertos/portmacro.h"
#include "driver/uart.h"
#include "esp_log.h"
#include "driver/gpio.h"
#include "sdkconfig.h"
#include "esp_intr_alloc.h"


#define EX_UART_NUM UART_NUM_1

#define BUF_SIZE (66)
uint8_t rxbuf[BUF_SIZE]; //Buffer for incoming data from UART
const int tx_GPIO = 22;
const int rx_GPIO = 21;

// Both definition are same and valid
//static uart_isr_handle_t *handle_console;
static intr_handle_t handle_console;

static void IRAM_ATTR uart_intr_handle(void *arg)
{
  uint16_t rx_fifo_len, status;
  status = UART1.int_st.val; // read UART interrupt Status
  rx_fifo_len = UART1.status.rxfifo_cnt; // read number of bytes in UART buffer
  for (int i = 0; i < rx_fifo_len; i++)
    rxbuf[i] = UART1.fifo.rw_byte; // read all bytes
  // after reading bytes from buffer clear UART interrupt status
  uart_clear_intr_status(EX_UART_NUM, UART_RXFIFO_FULL_INT_CLR | UART_RXFIFO_TOUT_INT_CLR);
  //Echo recieved buffer
  uart_write_bytes(EX_UART_NUM, (const char*) rxbuf, rx_fifo_len);
}


void app_main(void)
{
  uart_config_t uart_config = {
    .baud_rate = 38400,
    .data_bits = UART_DATA_8_BITS,
    .parity = UART_PARITY_EVEN,
    .stop_bits = UART_STOP_BITS_1,
    .flow_ctrl = UART_HW_FLOWCTRL_DISABLE
  };

  ESP_ERROR_CHECK(uart_param_config(EX_UART_NUM, &uart_config));
  //Set UART pins (using UART0 default pins ie no changes.)
  ESP_ERROR_CHECK(uart_set_pin(EX_UART_NUM, tx_GPIO, rx_GPIO, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
  //Install UART driver, and get the queue.
  ESP_ERROR_CHECK(uart_driver_install(EX_UART_NUM, BUF_SIZE * 2, 0, 0, NULL, 0));
  // release the pre registered UART handler/subroutine
  ESP_ERROR_CHECK(uart_isr_free(EX_UART_NUM));
  // register new UART subroutine
  ESP_ERROR_CHECK(uart_isr_register(EX_UART_NUM, uart_intr_handle, NULL, ESP_INTR_FLAG_IRAM, &handle_console));
  // enable RX interrupt
  ESP_ERROR_CHECK(uart_enable_rx_intr(EX_UART_NUM));
  while (1)
  {
    vTaskDelay(1000);
  }
}

ESP_Sprite
Posts: 9014
Joined: Thu Nov 26, 2015 4:08 am

Re: How to reduce UART RX Latency

Postby ESP_Sprite » Wed Dec 19, 2018 2:55 am

I think you're running into the UART receive thresholds. You can configure them differently with uart_intr_config.

yudopplyr
Posts: 2
Joined: Tue Dec 18, 2018 3:15 pm

Re: How to reduce UART RX Latency

Postby yudopplyr » Thu Dec 20, 2018 3:15 pm

Thanks for the info it worked, I am getting an interrupt after 8 us approx for each byte recieved. For future reference I added this to my code

Code: Select all

  uart_intr_config_t uart_intr = {
      .intr_enable_mask = UART_RXFIFO_FULL_INT_ENA_M
                          | UART_RXFIFO_TOUT_INT_ENA_M
                          | UART_FRM_ERR_INT_ENA_M
                          | UART_RXFIFO_OVF_INT_ENA_M
                          | UART_BRK_DET_INT_ENA_M
                          | UART_PARITY_ERR_INT_ENA_M,
      .rxfifo_full_thresh = 1,
      .rx_timeout_thresh = 10,
      .txfifo_empty_intr_thresh = 10
  };

Who is online

Users browsing this forum: No registered users and 104 guests