[SOLVED] INTERRUPT UART example work only one time and after hold

gpezzella
Posts: 52
Joined: Sun Jan 27, 2019 8:04 pm

[SOLVED] INTERRUPT UART example work only one time and after hold

Postby gpezzella » Mon Apr 01, 2019 11:51 am

Hello
I'm testing your ISR UART code and it work but ONLY ONE TIME!
After it hold and not receive nothing. Why??

Next question:
How save in string variable received data??

Code: Select all

String Received_Data = ??? (dtmp)
Please reply me soon.
Thanks in advice


Code: Untitled.cpp Select all


/*
* https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/uart.html#uart-api-setting-communication-pins
*/




#include "driver/uart.h"

#define NUMERO_PORTA_SERIALE UART_NUM_2
#define BUF_SIZE (1024 * 2)
#define RD_BUF_SIZE (1024)
static QueueHandle_t uart2_queue;

static const char * TAG = "";

#define U2RXD 33
#define U2TXD 32


void setup() {

Serial.begin(115200);

//Configuro la porta Serial2 (tutti i parametri hanno anche un get per effettuare controlli)
uart_config_t Configurazione_UART2 = {
.baud_rate = 9600,
.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(NUMERO_PORTA_SERIALE, &Configurazione_UART2);



//Firma: void esp_log_level_set(const char *tag, esp_log_level_tlevel)
esp_log_level_set(TAG, ESP_LOG_INFO);



//Firma: esp_err_tuart_set_pin(uart_port_tuart_num, int tx_io_num, int rx_io_num, int rts_io_num, int cts_io_num)
uart_set_pin(NUMERO_PORTA_SERIALE, U2TXD, U2RXD, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);


//Firma: uart_driver_install(UART_NUM_2, uart_buffer_size, uart_buffer_size, 10, &uart_queue, 0));
// uart_driver_install(Numero_porta, RXD_BUFFER, TXD_Buffer, event queue handle and size, flags to allocate an interrupt)
uart_driver_install(NUMERO_PORTA_SERIALE, BUF_SIZE, BUF_SIZE, 20, &uart2_queue, 0);


//Create a task to handler UART event from ISR
xTaskCreate(UART_ISR_ROUTINE, "UART_ISR_ROUTINE", 2048, NULL, 12, NULL);

}



void loop() {
Serial.println("Waiting data from SERIAL 2....");
delay(1000);
}




static void UART_ISR_ROUTINE(void *pvParameters){

uart_event_t event;
size_t buffered_size;
uint8_t* dtmp = (uint8_t*) malloc(RD_BUF_SIZE);

Serial.println("INSIDE ISR");

if(xQueueReceive(uart2_queue, (void * )&event, (portTickType)portMAX_DELAY)) {

bzero(dtmp, RD_BUF_SIZE);

ESP_LOGI(TAG, "uart[%d] event:", EX_UART_NUM);


if (event.type==UART_DATA){

//ESP_LOGI(TAG, "[UART DATA]: %d", event.size);

uart_read_bytes(NUMERO_PORTA_SERIALE, dtmp, event.size, portMAX_DELAY);

Serial.println("DATA= ");

//ESP_LOGI(TAG, "[DATA EVT]:");

//uart_write_bytes(NUMERO_PORTA_SERIALE, (const char*) dtmp, event.size);

}// if event.type



}//if xQuequeReceive


free(dtmp);
dtmp = NULL;
vTaskDelete(NULL);

}

Last edited by gpezzella on Tue Apr 02, 2019 10:15 am, edited 1 time in total.

gpezzella
Posts: 52
Joined: Sun Jan 27, 2019 8:04 pm

Re: INTERRUPT UART example work only one time and after hold

Postby gpezzella » Mon Apr 01, 2019 2:18 pm

update 1:

I have change the code inside UART_ISR_ROUTINE in this way and it return me:
ISR Status= 0
RX FIFO LEN=0
Why?

Code: Untitled.cpp Select all


uart_event_t event;
uint16_t rx_fifo_len=0, ISR_Status=0, i=0;


Serial.println("INSIDE ISR");

if(xQueueReceive(uart2_queue, (void * )&event, (portTickType)portMAX_DELAY)) {



if (event.type==UART_DATA){




ISR_Status = UART2.int_st.val; // read UART interrupt Status
Serial.print("ISR Status= ");Serial.println(ISR_Status);

rx_fifo_len = UART2.status.rxfifo_cnt; // read number of bytes in UART buffer
Serial.print("RX FIFO LEN= ");Serial.println(rx_fifo_len);

while(rx_fifo_len){
rxbuf[i++] = UART2.fifo.rw_byte; // read all bytes
Serial.print(rxbuf[i++]);
rx_fifo_len--;
}

// after reading bytes from buffer clear UART interrupt status
uart_clear_intr_status(NUMERO_PORTA_SERIALE, UART_RXFIFO_FULL_INT_CLR|UART_RXFIFO_TOUT_INT_CLR);


}// if event.type



}//if xQuequeReceive

vTaskDelete(NULL);

Dazza0
Espressif staff
Espressif staff
Posts: 308
Joined: Fri Jun 02, 2017 6:50 am

Re: INTERRUPT UART example work only one time and after hold

Postby Dazza0 » Mon Apr 01, 2019 3:36 pm

Because you're creating a Task instead of an ISR? The task simply receives form the queue once, then deletes itself.
//Create a task to handler UART event from ISR
xTaskCreate(UART_ISR_ROUTINE, "UART_ISR_ROUTINE", 2048, NULL, 12, NULL);

...

free(dtmp);
dtmp = NULL;
vTaskDelete(NULL);
If you are implementing a task to continuously receive from a UART event queue, it should be implemented as some form of loop

gpezzella
Posts: 52
Joined: Sun Jan 27, 2019 8:04 pm

Re: INTERRUPT UART example work only one time and after hold

Postby gpezzella » Mon Apr 01, 2019 3:46 pm

Hi ESP_dazz

could you gently show me the correct way?
I'm new with ESP32 and for this reason I reuse code of example without understand every line of code.

In any case with update 1 code my output is:
ISR_Status=0
rx_fifo_len=0

Thanks in advice

Dazza0
Espressif staff
Espressif staff
Posts: 308
Joined: Fri Jun 02, 2017 6:50 am

Re: INTERRUPT UART example work only one time and after hold

Postby Dazza0 » Mon Apr 01, 2019 4:15 pm

A FreeRTOS task should be implemented as an infinite loop.

Code: task_example.cpp Select all


static void UART_ISR_ROUTINE(void *pvParameters)
{
uart_event_t event;
size_t buffered_size;
uint8_t* dtmp = (uint8_t*) malloc(RD_BUF_SIZE);
bool exit_condition = false;

//Infinite loop to run main bulk of task
while (1) {
//Loop will continually block (i.e. wait) on event messages from the event queue
if(xQueueReceive(uart2_queue, (void * )&event, (portTickType)portMAX_DELAY)) {
//Handle received event
if (event.type == UART_DATA) {
//Handle your uart reading here
}
else if (event.type == UART_FRAME_ERR) {
//Handle frame error event
}
... //Keep adding else if statements for each UART event you want to support
else {
//Final else statement to act as a default case
}
}

//If you want to break out of the loop due to certain conditions, set exit condition to true
if (exit_condition) {
break;
}
}

//Out side of loop now. Task needs to clean up and self terminate before returning
free(dtmp);
dtmp = NULL;
vTaskDelete(NULL);
}
As to why the ISR_Status=0 and rx_fifo_len=0, it could be because you are receive different events other than UART_DATA, so I suggest you check for the type of event that you are receiving.

EDIT: Didn't see you checked for ISR_Status=0 and rx_fifo_len=0 after checking UART_DATA. Are you trying to use the Arduino UART driver or the ESP-IDF UART driver?

gpezzella
Posts: 52
Joined: Sun Jan 27, 2019 8:04 pm

Re: INTERRUPT UART example work only one time and after hold

Postby gpezzella » Mon Apr 01, 2019 4:31 pm

Hi ESP_Dazz

now it work in continuous mode!!

I use Arduino for UART0 (debug) and idf for UART2

I replace Serial.print("DATA= ") with follow code but cannot read nothing...why?

Code: Untitled.cpp Select all


  rx_fifo_len = UART2.status.rxfifo_cnt; // read number of bytes in UART buffer
Serial.print("DATA= ");
while(rx_fifo_len){
rxbuf[i++] = UART2.fifo.rw_byte; // read all bytes
Serial.print(rxbuf[i]);
rx_fifo_len--;
}

Dazza0
Espressif staff
Espressif staff
Posts: 308
Joined: Fri Jun 02, 2017 6:50 am

Re: INTERRUPT UART example work only one time and after hold

Postby Dazza0 » Mon Apr 01, 2019 4:46 pm

Well I'm not exactly sure why you are checking the values of hardware registers (i.e. UART2.status.rxfifo_cnt). The driver should already handle the transfer of data from the hardware FIFO to a software ring buffer. I suggest you take a look at the existing UART examples on how to use the IDF UART driver API properly.

gpezzella
Posts: 52
Joined: Sun Jan 27, 2019 8:04 pm

[SOLVED] INTERRUPT UART example work only one time and after hold

Postby gpezzella » Tue Apr 02, 2019 10:14 am

FINAL WORKING PROGRAM
IT READ DATA FROM UART2 IN INTERRUPT MODE AND SEND TO UART0:

Code: Untitled.cpp Select all


/*
* https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/uart.html#uart-api-setting-communication-pins
*/




#include "driver/uart.h"

#define NUMERO_PORTA_SERIALE UART_NUM_2
#define BUF_SIZE (1024 * 2)
#define RD_BUF_SIZE (1024)
static QueueHandle_t uart2_queue;

static const char * TAG = "";

#define U2RXD 33
#define U2TXD 32

uint8_t rxbuf[256]; //Buffer di ricezione
uint16_t rx_fifo_len; //Lunghezza dati


void setup() {

Serial.begin(115200);

//Configuro la porta Serial2 (tutti i parametri hanno anche un get per effettuare controlli)
uart_config_t Configurazione_UART2 = {
.baud_rate = 9600,
.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(NUMERO_PORTA_SERIALE, &Configurazione_UART2);



//Firma: void esp_log_level_set(const char *tag, esp_log_level_tlevel)
esp_log_level_set(TAG, ESP_LOG_INFO);



//Firma: esp_err_tuart_set_pin(uart_port_tuart_num, int tx_io_num, int rx_io_num, int rts_io_num, int cts_io_num)
uart_set_pin(NUMERO_PORTA_SERIALE, U2TXD, U2RXD, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);


//Firma: uart_driver_install(UART_NUM_2, uart_buffer_size, uart_buffer_size, 10, &uart_queue, 0));
// uart_driver_install(Numero_porta, RXD_BUFFER, TXD_Buffer, event queue handle and size, flags to allocate an interrupt)
uart_driver_install(NUMERO_PORTA_SERIALE, BUF_SIZE, BUF_SIZE, 20, &uart2_queue, 0);


//Create a task to handler UART event from ISR
xTaskCreate(UART_ISR_ROUTINE, "UART_ISR_ROUTINE", 2048, NULL, 12, NULL);

}



void loop() {
Serial.println("Waiting data from SERIAL 2....");
delay(1000);
}



static void UART_ISR_ROUTINE(void *pvParameters)
{
uart_event_t event;
size_t buffered_size;
bool exit_condition = false;

//Infinite loop to run main bulk of task
while (1) {

//Loop will continually block (i.e. wait) on event messages from the event queue
if(xQueueReceive(uart2_queue, (void * )&event, (portTickType)portMAX_DELAY)) {

//Handle received event
if (event.type == UART_DATA) {

uint8_t UART2_data[128];
int UART2_data_length = 0;
ESP_ERROR_CHECK(uart_get_buffered_data_len(UART_NUM_2, (size_t*)&UART2_data_length));
UART2_data_length = uart_read_bytes(UART_NUM_2, UART2_data, UART2_data_length, 100);

Serial.println("LEN= ");Serial.println(UART2_data_length);

Serial.print("DATA= ");
for(byte i=0; i<UART2_data_length;i++) Serial.print((char)UART2_data[i]);
Serial.println("");

}

//Handle frame error event
else if (event.type == UART_FRAME_ERR) {
//TODO...
}

//Keep adding else if statements for each UART event you want to support
//else if (event.type == OTHER EVENT) {
//TODO...
//}


//Final else statement to act as a default case
else {
//TODO...
}
}

//If you want to break out of the loop due to certain conditions, set exit condition to true
if (exit_condition) {
break;
}
}

//Out side of loop now. Task needs to clean up and self terminate before returning
vTaskDelete(NULL);
}


IOTCure
Posts: 1
Joined: Wed Sep 11, 2019 12:54 pm

Re: [SOLVED] INTERRUPT UART example work only one time and after hold

Postby IOTCure » Wed Sep 11, 2019 1:04 pm

Hello gpezella,

I tried to run your code, it compiles successfully but UART2 is not working working in Interrupt mode for RX.

when I tried to debug with serial monitor, I found the provided ISR function static void UART_ISR_ROUTINE(void *pvParameters) is executed only one time at start rest never call again in program.

i tried to send data on UART2 and looking for same data on UART0, but it is not working.

kindly help, what i am missing here.

Thanks In Advance.

Regards,
Cure

JJ_Bras
Posts: 3
Joined: Wed Dec 01, 2021 1:30 pm

Re: [SOLVED] INTERRUPT UART example work only one time and after hold

Postby JJ_Bras » Wed Dec 01, 2021 1:34 pm

Hi everyone, I am with the same problem. I think that it is stoped into "xQueueReceive(uart2_queue, (void * )&event, (portTickType)portMAX_DELAY)"

Who is online

Users browsing this forum: Google [Bot], Qwantbot and 2 guests