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?
Simple interrupt based serial terminal on esp32
Re: Simple interrupt based serial terminal on esp32
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);
}
#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);
}
Re: Simple interrupt based serial terminal on esp32
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.
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.
-
- Posts: 118
- Joined: Tue Jun 26, 2018 3:09 am
Re: Simple interrupt based serial terminal on esp32
Hi, lalleglad
I think you don't need to use callbacks. The following code may meet your needs:
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 116 guests