Simple interrupt based serial terminal on esp32

lalleglad
Posts: 9
Joined: Tue Feb 25, 2020 1:12 pm

Simple interrupt based serial terminal on esp32

Postby lalleglad » Tue Mar 17, 2020 9:19 am

I am trying to build a serial terminal on my esp32 with esp32-idf and have looked at the 'uart_echo' example.

I would however like to make without an infinite while loop in a Task, but instead interrupt driven so I started look into uart_isr_register().

I would like to get one character at a time in a callback, eg. originating from a Tera Term terminal, and I would like to independently send characters to the terminal from any place in my code.
I am using UART_NUM_0 with Tx=GPIO_NUM_1 and Rx=GPIO_NUM_3.

I have made it before on STM32 with HAL, but now I can't seem to make it work.

Now I am developing on an ESP32_DevKitC_V4, and expect eventually to use a ESP32-WROOM-32D.

Please let me know if you have any pointers?

lalleglad
Posts: 9
Joined: Tue Feb 25, 2020 1:12 pm

Re: Simple interrupt based serial terminal on esp32

Postby lalleglad » Tue Mar 17, 2020 2:01 pm

I mean, playing around a bit with the uart_echo example, the following at least splits the read and write, but should make no one happy:

#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/uart.h"
#include "driver/gpio.h"

#define ECHO_TEST_TXD (GPIO_NUM_1)
#define ECHO_TEST_RXD (GPIO_NUM_3)
#define ECHO_TEST_RTS (UART_PIN_NO_CHANGE)
#define ECHO_TEST_CTS (UART_PIN_NO_CHANGE)

#define BUF_SIZE 1024

char data[2]={'\0'};

static void echo_read_task(void *arg)
{
while (1) {
// Read data from the UART
int len = uart_read_bytes(UART_NUM_0, (uint8_t*)data, 2, 20 / portTICK_RATE_MS);
}
}

static void echo_write_task(void *arg)
{
while (1) {
// Write data back to the UART
if(strlen(data)>0) {
uart_write_bytes(UART_NUM_0, (const char *) data, 1);
data[0]='\0';
}
vTaskDelay(1);
}
}

void app_main(void)
{
/* Configure parameters of an UART driver,
* communication pins and install the driver */

uart_config_t uart_config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.source_clk = UART_SCLK_APB,
};
uart_driver_install(UART_NUM_0, BUF_SIZE * 2, 0, 0, NULL, 0);
uart_param_config(UART_NUM_0, &uart_config);
uart_set_pin(UART_NUM_0, ECHO_TEST_TXD, ECHO_TEST_RXD, ECHO_TEST_RTS, ECHO_TEST_CTS);

xTaskCreate(echo_read_task, "uart_echo_read_task", 1024, NULL, 10, NULL);
xTaskCreate(echo_write_task, "uart_echo_write_task", 1024, NULL, 10, NULL);
}

boarchuz
Posts: 315
Joined: Tue Aug 21, 2018 5:28 am

Re: Simple interrupt based serial terminal on esp32

Postby boarchuz » Wed Mar 18, 2020 4:16 am


lalleglad
Posts: 9
Joined: Tue Feb 25, 2020 1:12 pm

Re: Simple interrupt based serial terminal on esp32

Postby lalleglad » Wed Mar 18, 2020 8:20 am

Thank you for the suggestion.
I did look into that one, but it is way too heavy.

I just want the simplest and leanest way to get in characters from a keyboard and to send characters out to a display, in a terminal program like Tera Term.

ESP_houwenxiang
Posts: 118
Joined: Tue Jun 26, 2018 3:09 am

Re: Simple interrupt based serial terminal on esp32

Postby ESP_houwenxiang » Thu Apr 09, 2020 11:15 am

Hi, lalleglad

I think you don't need to use callbacks. The following code may meet your needs:

Code: Select all

#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/queue.h"
#include "freertos/task.h"
#include "driver/uart.h"
#include "driver/gpio.h"

#define ECHO_TEST_TXD (GPIO_NUM_1)
#define ECHO_TEST_RXD (GPIO_NUM_3)
#define ECHO_TEST_RTS (UART_PIN_NO_CHANGE)
#define ECHO_TEST_CTS (UART_PIN_NO_CHANGE)

#define BUF_SIZE 1024
#define ECHO_QUEUE_LEN   (50)

static QueueHandle_t echo_queue = NULL;


static void echo_read_task(void *arg)
{
    uint8_t recv = 0;
    while (1) {
        uart_read_bytes(UART_NUM_0, (uint8_t*)&recv, 1, (TickType_t)portMAX_DELAY);
        xQueueSend(echo_queue, &recv, (TickType_t)portMAX_DELAY);
    }
}

static void echo_write_task(void *arg)
{
    uint8_t send = 0;
    while (1) {
        xQueueReceive(echo_queue, &send, (TickType_t)portMAX_DELAY);
        uart_write_bytes(UART_NUM_0, (const char *)&send, 1);
   }
}

void app_main(void)
{
    echo_queue = xQueueCreate(ECHO_QUEUE_LEN, sizeof(uint8_t));
    if(!echo_queue) {
        printf("echo queue create fail\n");
        while(1);
    }
    uart_config_t uart_config = {
        .baud_rate = 115200,
        .data_bits = UART_DATA_8_BITS,
        .parity = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
        .source_clk = UART_SCLK_APB,
    };
    uart_driver_install(UART_NUM_0, BUF_SIZE * 2, 0, 0, NULL, 0);
    uart_param_config(UART_NUM_0, &uart_config);
    uart_set_pin(UART_NUM_0, ECHO_TEST_TXD, ECHO_TEST_RXD, ECHO_TEST_RTS, ECHO_TEST_CTS);
    xTaskCreate(echo_read_task, "uart_echo_read_task", 1024, NULL, 10, NULL);
    xTaskCreate(echo_write_task, "uart_echo_write_task", 1024, NULL, 10, NULL);
}
wookooho

Who is online

Users browsing this forum: No registered users and 43 guests