[Solved]UART rx ISR not working

blackpearl21
Posts: 12
Joined: Wed Feb 21, 2018 4:28 pm

[Solved]UART rx ISR not working

Postby blackpearl21 » Sat May 05, 2018 6:53 pm

Hi,
i am trying to work with UART on esp32, using esp-idf. i modified UART event sample code so that i can register UART IRQ routine and receive data directly, below is modified code,

Code: Select all

void app_main()
{
    esp_log_level_set(TAG, ESP_LOG_INFO);

    /* 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
    };
    uart_param_config(EX_UART_NUM, &uart_config);

    //Set UART log level
    esp_log_level_set(TAG, ESP_LOG_INFO);
    //Set UART pins (using UART0 default pins ie no changes.)
    uart_set_pin(EX_UART_NUM, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
    //Install UART driver, and get the queue.
    uart_driver_install(EX_UART_NUM, BUF_SIZE * 2, 0, 0, NULL, 0);

//    //Set uart pattern detect function.
//    uart_enable_pattern_det_intr(EX_UART_NUM, '+', PATTERN_CHR_NUM, 10000, 10, 10);
//    //Reset the pattern queue length to record at most 20 pattern positions.
//    uart_pattern_queue_reset(EX_UART_NUM, 20);

	// Register ISR routine for RX interrupt
    uart_isr_register(EX_UART_NUM,uart_intr_handle, NULL, ESP_INTR_FLAG_LOWMED, handle_console);

    uart_enable_rx_intr(EX_UART_NUM);
    //Create a task to handler UART event from ISR
    //xTaskCreate(uart_event_task, "uart_event_task", 2048, NULL, 12, NULL);
}
// --- UART ISR Routine
static void IRAM_ATTR uart_intr_handle()
{
	uart_write_bytes(EX_UART_NUM, (const char*) "RX Done", 7);
}
i got this code from this FORUM, however mine is not working, i don't receive anything, as you can see i have written UART_Write on invoking of interrupt routine, but it doesnt work.

i would like to know whats wrong with this code.

Thanks Sushant
Last edited by blackpearl21 on Fri May 18, 2018 4:59 pm, edited 1 time in total.

User avatar
kolban
Posts: 1683
Joined: Mon Nov 16, 2015 4:43 pm
Location: Texas, USA

Re: UART rx ISR not working

Postby kolban » Sun May 06, 2018 1:03 am

I would first recommend that you rework your code to check the return codes from all the ESP32 functions and validate that they are all returning ESP_OK and, if not, what code they are returning.
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32

blackpearl21
Posts: 12
Joined: Wed Feb 21, 2018 4:28 pm

Re: UART rx ISR not working

Postby blackpearl21 » Sun May 06, 2018 4:38 am

kolban wrote:I would first recommend that you rework your code to check the return codes from all the ESP32 functions and validate that they are all returning ESP_OK and, if not, what code they are returning.
Thank your for reply and your time,

uart_isr_register, returns ESP_FAIL, error code is 0x105

ESP_ERROR_CHECK failed: esp_err_t 0x105 at 0x400d23e9
file: "C:/esp32/esp-idf/examples/peripherals/uart_events/main/uart_events_example_main.c" line 152
func: app_main
expression: uart_isr_register(EX_UART_NUM,uart_intr_handle, NULL, ESP_INTR_FLAG_LOWMED, handle_console)

As per definition its
#define ESP_ERR_NOT_FOUND 0x105,
however i dont understand what is NOT FOUND error.

User avatar
kolban
Posts: 1683
Joined: Mon Nov 16, 2015 4:43 pm
Location: Texas, USA

Re: UART rx ISR not working

Postby kolban » Sun May 06, 2018 4:44 am

In your code snippet, I think you are saying that this call is failing:

Code: Select all

uart_isr_register(EX_UART_NUM,uart_intr_handle, NULL, ESP_INTR_FLAG_LOWMED, handle_console);
In the snippet, you didn't show what the value of EX_UART_NUM was nor did we see the definition of "handle_console".
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32

blackpearl21
Posts: 12
Joined: Wed Feb 21, 2018 4:28 pm

Re: UART rx ISR not working

Postby blackpearl21 » Sun May 06, 2018 5:06 am

kolban wrote:In your code snippet, I think you are saying that this call is failing:

Code: Select all

uart_isr_register(EX_UART_NUM,uart_intr_handle, NULL, ESP_INTR_FLAG_LOWMED, handle_console);
In the snippet, you didn't show what the value of EX_UART_NUM was nor did we see the definition of "handle_console".
Sorry for inconvenience, the complete code is as below,

Code: Select all

/* UART Events Example

   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "driver/uart.h"
#include "esp_log.h"

static const char *TAG = "uart_events";

/**
 * This example shows how to use the UART driver to handle special UART events.
 *
 * It also reads data from UART0 directly, and echoes it to console.
 *
 * - Port: UART0
 * - Receive (Rx) buffer: on
 * - Transmit (Tx) buffer: off
 * - Flow control: off
 * - Event queue: on
 * - Pin assignment: TxD (default), RxD (default)
 */

#define EX_UART_NUM UART_NUM_0
#define PATTERN_CHR_NUM    (3)         /*!< Set the number of consecutive and identical characters received by receiver which defines a UART pattern*/

#define BUF_SIZE (1024)
#define RD_BUF_SIZE (BUF_SIZE)
static QueueHandle_t uart0_queue;

uart_isr_handle_t *handle_console;

static void uart_event_task(void *pvParameters)
{
    uart_event_t event;
    size_t buffered_size;
    uint8_t* dtmp = (uint8_t*) malloc(RD_BUF_SIZE);
    for(;;) {
        //Waiting for UART event.
        if(xQueueReceive(uart0_queue, (void * )&event, (portTickType)portMAX_DELAY)) {
            bzero(dtmp, RD_BUF_SIZE);
            ESP_LOGI(TAG, "uart[%d] event:", EX_UART_NUM);
            switch(event.type) {
                //Event of UART receving data
                /*We'd better handler data event fast, there would be much more data events than
                other types of events. If we take too much time on data event, the queue might
                be full.*/
                case UART_DATA:
                    ESP_LOGI(TAG, "[UART DATA]: %d", event.size);
                    uart_read_bytes(EX_UART_NUM, dtmp, event.size, portMAX_DELAY);
                    ESP_LOGI(TAG, "[DATA EVT]:");
                    uart_write_bytes(EX_UART_NUM, (const char*) dtmp, event.size);
                    break;
                //Event of HW FIFO overflow detected
                case UART_FIFO_OVF:
                    ESP_LOGI(TAG, "hw fifo overflow");
                    // If fifo overflow happened, you should consider adding flow control for your application.
                    // The ISR has already reset the rx FIFO,
                    // As an example, we directly flush the rx buffer here in order to read more data.
                    uart_flush_input(EX_UART_NUM);
                    xQueueReset(uart0_queue);
                    break;
                //Event of UART ring buffer full
                case UART_BUFFER_FULL:
                    ESP_LOGI(TAG, "ring buffer full");
                    // If buffer full happened, you should consider encreasing your buffer size
                    // As an example, we directly flush the rx buffer here in order to read more data.
                    uart_flush_input(EX_UART_NUM);
                    xQueueReset(uart0_queue);
                    break;
                //Event of UART RX break detected
                case UART_BREAK:
                    ESP_LOGI(TAG, "uart rx break");
                    break;
                //Event of UART parity check error
                case UART_PARITY_ERR:
                    ESP_LOGI(TAG, "uart parity error");
                    break;
                //Event of UART frame error
                case UART_FRAME_ERR:
                    ESP_LOGI(TAG, "uart frame error");
                    break;
                //UART_PATTERN_DET
                case UART_PATTERN_DET:
                    uart_get_buffered_data_len(EX_UART_NUM, &buffered_size);
                    int pos = uart_pattern_pop_pos(EX_UART_NUM);
                    ESP_LOGI(TAG, "[UART PATTERN DETECTED] pos: %d, buffered size: %d", pos, buffered_size);
                    if (pos == -1) {
                        // There used to be a UART_PATTERN_DET event, but the pattern position queue is full so that it can not
                        // record the position. We should set a larger queue size.
                        // As an example, we directly flush the rx buffer here.
                        uart_flush_input(EX_UART_NUM);
                    } else {
                        uart_read_bytes(EX_UART_NUM, dtmp, pos, 100 / portTICK_PERIOD_MS);
                        uint8_t pat[PATTERN_CHR_NUM + 1];
                        memset(pat, 0, sizeof(pat));
                        uart_read_bytes(EX_UART_NUM, pat, PATTERN_CHR_NUM, 100 / portTICK_PERIOD_MS);
                        ESP_LOGI(TAG, "read data: %s", dtmp);
                        ESP_LOGI(TAG, "read pat : %s", pat);
                    }
                    break;
                //Others
                default:
                    ESP_LOGI(TAG, "uart event type: %d", event.type);
                    break;
            }
        }
    }
    free(dtmp);
    dtmp = NULL;
    vTaskDelete(NULL);
}
static void IRAM_ATTR uart_intr_handle()
{
	uart_write_bytes(EX_UART_NUM, (const char*) "RX Done", 7);
}
void app_main()
{
	int ret;
    esp_log_level_set(TAG, ESP_LOG_INFO);

    /* 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
    };
    ESP_ERROR_CHECK(uart_param_config(EX_UART_NUM, &uart_config));

    //Set UART log level
    esp_log_level_set(TAG, ESP_LOG_INFO);
    //Set UART pins (using UART0 default pins ie no changes.)
    ESP_ERROR_CHECK(uart_set_pin(EX_UART_NUM, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, 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));

//    //Set uart pattern detect function.
//    uart_enable_pattern_det_intr(EX_UART_NUM, '+', PATTERN_CHR_NUM, 10000, 10, 10);
//    //Reset the pattern queue length to record at most 20 pattern positions.
//    uart_pattern_queue_reset(EX_UART_NUM, 20);
    ESP_ERROR_CHECK(uart_isr_register(EX_UART_NUM,uart_intr_handle, NULL, ESP_INTR_FLAG_LOWMED, handle_console));

    //ESP_LOGI(TAG, "Return from UART ISR %X", ret);
    ESP_ERROR_CHECK(uart_enable_rx_intr(EX_UART_NUM));
    //Create a task to handler UART event from ISR
    //xTaskCreate(uart_event_task, "uart_event_task", 2048, NULL, 12, NULL);
}
it was working example of UART_EVENTS, i modified it for ISR routine, i didnt change much.
added these 2 lines
ESP_ERROR_CHECK(uart_isr_register(EX_UART_NUM,uart_intr_handle, NULL, ESP_INTR_FLAG_LOWMED, handle_console));

//ESP_LOGI(TAG, "Return from UART ISR %X", ret);
ESP_ERROR_CHECK(uart_enable_rx_intr(EX_UART_NUM));

EDITS: earlier post was trial and error for argument,edited for original.
ESP_ERROR_CHECK(uart_isr_register(EX_UART_NUM,uart_intr_handle, argISR, ESP_INTR_FLAG_LOWMED, handle_console));

User avatar
kolban
Posts: 1683
Joined: Mon Nov 16, 2015 4:43 pm
Location: Texas, USA

Re: UART rx ISR not working

Postby kolban » Sun May 06, 2018 5:28 am

Just a guess, but if I am reading your code correctly, we have:

Code: Select all

uart_isr_handle_t *handle_console;
...
uart_isr_register(EX_UART_NUM,uart_intr_handle, NULL, ESP_INTR_FLAG_LOWMED, handle_console)
I can't help wondering if the following might not be the correct pattern:

Code: Select all

uart_isr_handle_t handle_console;
...
uart_isr_register(EX_UART_NUM,uart_intr_handle, NULL, ESP_INTR_FLAG_LOWMED, &handle_console)
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32

blackpearl21
Posts: 12
Joined: Wed Feb 21, 2018 4:28 pm

Re: UART rx ISR not working

Postby blackpearl21 » Sun May 06, 2018 6:05 am

kolban wrote:Just a guess, but if I am reading your code correctly, we have:

Code: Select all

uart_isr_handle_t *handle_console;
...
uart_isr_register(EX_UART_NUM,uart_intr_handle, NULL, ESP_INTR_FLAG_LOWMED, handle_console)
I can't help wondering if the following might not be the correct pattern:

Code: Select all

uart_isr_handle_t handle_console;
...
uart_isr_register(EX_UART_NUM,uart_intr_handle, NULL, ESP_INTR_FLAG_LOWMED, &handle_console)
Sorry didnt help,

ESP_ERROR_CHECK failed: esp_err_t 0x105 at 0x400d23e1
file: "C:/esp32/esp-idf/examples/peripherals/uart_events/main/uart_events_example_main.c" line 152
func: app_main
expression: uart_isr_register(EX_UART_NUM,uart_intr_handle, NULL, ESP_INTR_FLAG_LOWMED, &handle_console)

Shouldn't this &handle_console be a double pointer ?

chegewara
Posts: 2364
Joined: Wed Jun 14, 2017 9:00 pm

Re: UART rx ISR not working

Postby chegewara » Sun May 06, 2018 6:16 am

Im not sure you can use UART0, its serial port used to debug.

Like kolban said its better to use this line that way:

Code: Select all

static uart_isr_handle_t handle_console;
....
ESP_ERROR_CHECK(uart_isr_register(EX_UART_NUM,uart_intr_handle, NULL, ESP_INTR_FLAG_LOWMED, &handle_console));
or you have to initialize *handle_console before you can use it.

blackpearl21
Posts: 12
Joined: Wed Feb 21, 2018 4:28 pm

Re: UART rx ISR not working

Postby blackpearl21 » Sun May 06, 2018 6:35 am

chegewara wrote:Im not sure you can use UART0, its serial port used to debug.

Like kolban said its better to use this line that way:

Code: Select all

static uart_isr_handle_t handle_console;
....
ESP_ERROR_CHECK(uart_isr_register(EX_UART_NUM,uart_intr_handle, NULL, ESP_INTR_FLAG_LOWMED, &handle_console));
or you have to initialize *handle_console before you can use it.
Thank you for reply and your time,

Why static, its already a global definition, and if it is defined in another file shouldnt compilation error be thown ?

ERROR has changed now

ESP_ERROR_CHECK failed: esp_err_t 0x102 at 0x400d23e3
file: "C:/esp32/esp-idf/examples/peripherals/uart_events/main/uart_events_example_main.c" line 155
func: app_main
expression: uart_isr_register(EX_UART_NUM,uart_intr_handle, NULL, ESP_INTR_FLAG_HIGH, &handle_console)

Backtrace: 0x40087510:0x3ffb4670 0x400879a1:0x3ffb4690 0x400d23e3:0x3ffb46b0 0x400d09f6:0x3ffb46f0

Complete code,

Code: Select all

/* UART Events Example

   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "driver/uart.h"
#include "esp_log.h"

static const char *TAG = "uart_events";

/**
 * This example shows how to use the UART driver to handle special UART events.
 *
 * It also reads data from UART0 directly, and echoes it to console.
 *
 * - Port: UART0
 * - Receive (Rx) buffer: on
 * - Transmit (Tx) buffer: off
 * - Flow control: off
 * - Event queue: on
 * - Pin assignment: TxD (default), RxD (default)
 */

#define EX_UART_NUM UART_NUM_0
#define PATTERN_CHR_NUM    (3)         /*!< Set the number of consecutive and identical characters received by receiver which defines a UART pattern*/

#define BUF_SIZE (1024)
#define RD_BUF_SIZE (BUF_SIZE)
static QueueHandle_t uart0_queue;

static uart_isr_handle_t handle_console;

uint8_t argISR;

static void uart_event_task(void *pvParameters)
{
    uart_event_t event;
    size_t buffered_size;
    uint8_t* dtmp = (uint8_t*) malloc(RD_BUF_SIZE);
    for(;;) {
        //Waiting for UART event.
        if(xQueueReceive(uart0_queue, (void * )&event, (portTickType)portMAX_DELAY)) {
            bzero(dtmp, RD_BUF_SIZE);
            ESP_LOGI(TAG, "uart[%d] event:", EX_UART_NUM);
            switch(event.type) {
                //Event of UART receving data
                /*We'd better handler data event fast, there would be much more data events than
                other types of events. If we take too much time on data event, the queue might
                be full.*/
                case UART_DATA:
                    ESP_LOGI(TAG, "[UART DATA]: %d", event.size);
                    uart_read_bytes(EX_UART_NUM, dtmp, event.size, portMAX_DELAY);
                    ESP_LOGI(TAG, "[DATA EVT]:");
                    uart_write_bytes(EX_UART_NUM, (const char*) dtmp, event.size);
                    break;
                //Event of HW FIFO overflow detected
                case UART_FIFO_OVF:
                    ESP_LOGI(TAG, "hw fifo overflow");
                    // If fifo overflow happened, you should consider adding flow control for your application.
                    // The ISR has already reset the rx FIFO,
                    // As an example, we directly flush the rx buffer here in order to read more data.
                    uart_flush_input(EX_UART_NUM);
                    xQueueReset(uart0_queue);
                    break;
                //Event of UART ring buffer full
                case UART_BUFFER_FULL:
                    ESP_LOGI(TAG, "ring buffer full");
                    // If buffer full happened, you should consider encreasing your buffer size
                    // As an example, we directly flush the rx buffer here in order to read more data.
                    uart_flush_input(EX_UART_NUM);
                    xQueueReset(uart0_queue);
                    break;
                //Event of UART RX break detected
                case UART_BREAK:
                    ESP_LOGI(TAG, "uart rx break");
                    break;
                //Event of UART parity check error
                case UART_PARITY_ERR:
                    ESP_LOGI(TAG, "uart parity error");
                    break;
                //Event of UART frame error
                case UART_FRAME_ERR:
                    ESP_LOGI(TAG, "uart frame error");
                    break;
                //UART_PATTERN_DET
                case UART_PATTERN_DET:
                    uart_get_buffered_data_len(EX_UART_NUM, &buffered_size);
                    int pos = uart_pattern_pop_pos(EX_UART_NUM);
                    ESP_LOGI(TAG, "[UART PATTERN DETECTED] pos: %d, buffered size: %d", pos, buffered_size);
                    if (pos == -1) {
                        // There used to be a UART_PATTERN_DET event, but the pattern position queue is full so that it can not
                        // record the position. We should set a larger queue size.
                        // As an example, we directly flush the rx buffer here.
                        uart_flush_input(EX_UART_NUM);
                    } else {
                        uart_read_bytes(EX_UART_NUM, dtmp, pos, 100 / portTICK_PERIOD_MS);
                        uint8_t pat[PATTERN_CHR_NUM + 1];
                        memset(pat, 0, sizeof(pat));
                        uart_read_bytes(EX_UART_NUM, pat, PATTERN_CHR_NUM, 100 / portTICK_PERIOD_MS);
                        ESP_LOGI(TAG, "read data: %s", dtmp);
                        ESP_LOGI(TAG, "read pat : %s", pat);
                    }
                    break;
                //Others
                default:
                    ESP_LOGI(TAG, "uart event type: %d", event.type);
                    break;
            }
        }
    }
    free(dtmp);
    dtmp = NULL;
    vTaskDelete(NULL);
}

static void IRAM_ATTR uart_intr_handle()
{
	uart_write_bytes(EX_UART_NUM, (const char*) "RX Done", 7);
}
void app_main()
{
	int ret;
    esp_log_level_set(TAG, ESP_LOG_INFO);

    /* 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
    };
    ESP_ERROR_CHECK(uart_param_config(EX_UART_NUM, &uart_config));

    //Set UART log level
    esp_log_level_set(TAG, ESP_LOG_INFO);
    //Set UART pins (using UART0 default pins ie no changes.)
    ESP_ERROR_CHECK(uart_set_pin(EX_UART_NUM, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, 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));

//    //Set uart pattern detect function.
//    uart_enable_pattern_det_intr(EX_UART_NUM, '+', PATTERN_CHR_NUM, 10000, 10, 10);
//    //Reset the pattern queue length to record at most 20 pattern positions.
//    uart_pattern_queue_reset(EX_UART_NUM, 20);
    ESP_ERROR_CHECK(uart_isr_register(EX_UART_NUM,uart_intr_handle, NULL, ESP_INTR_FLAG_HIGH, &handle_console));

    //ESP_LOGI(TAG, "Return from UART ISR %X", ret);
    ESP_ERROR_CHECK(uart_enable_rx_intr(EX_UART_NUM));
    //Create a task to handler UART event from ISR
    //xTaskCreate(uart_event_task, "uart_event_task", 2048, NULL, 12, NULL);
}


chegewara
Posts: 2364
Joined: Wed Jun 14, 2017 9:00 pm

Re: UART rx ISR not working

Postby chegewara » Sun May 06, 2018 2:47 pm

Time to learn how to use GDB to translate this:

Code: Select all

Backtrace: 0x40087510:0x3ffb4670 0x400879a1:0x3ffb4690 0x400d23e3:0x3ffb46b0 0x400d09f6:0x3ffb46f0
into something more human readable or use this tool:
https://github.com/me-no-dev/EspExceptionDecoder

Who is online

Users browsing this forum: Majestic-12 [Bot] and 75 guests