UART TX Interrupt - How to use UART_TX_DONE_INT

Pablo Silva
Posts: 2
Joined: Wed Jul 03, 2019 2:36 pm

UART TX Interrupt - How to use UART_TX_DONE_INT

Postby Pablo Silva » Wed Jul 03, 2019 2:59 pm

Hello,

I'm using some ESP32 resources, like: Timer, UART and Interrupts.
Basically, I send a standard UART frame stream each 500ms. Until now, no problem. But, when I try get UART_TX_DONE_INT event via interrupt, I can not. I need this to get moment of transmitter send out all TX_FIFO data bytes. In this way, the handler is not being called.

See my main code (in the attachment has all the code):

/* Headers includes */
#include "main.h"

/* Main Data of Module */
MainData mainData;
/* Setting variables to TIMER pripheral of Module ESP32 */
hw_timer_t *timer = NULL;
timer_config_t timer_config;
/* Setting variables to UART pripheral of Module ESP32 */
uart_config_t uart_config = {.baud_rate = 19200, .data_bits = UART_DATA_8_BITS, .parity = UART_PARITY_DISABLE, .stop_bits = UART_STOP_BITS_1, .flow_ctrl = UART_HW_FLOWCTRL_DISABLE};
uart_intr_config_t uart_intr;
static intr_handle_t handle_console;
/* Variables into this scope (this file *.c) */
static int Counter1Of10ms = 0;
static int Counter2Of10ms = 0;
static int Counter3Of10ms = 0;


/* CallBack Timer runs every 10ms */
static void IRAM_ATTR TIMER_Group0_ISR(void *pParam)
{
/* Simple instructions */
Counter1Of10ms++;
Counter2Of10ms++;
Counter3Of10ms++;
/* Instructions to Timer peripheral */
TIMERG0.int_clr_timers.t0 = 1; /* Clear the interrupt */
TIMERG0.hw_timer[TIMER_ID].config.alarm_en = TIMER_ALARM_EN; /* Enable alarm of Timer again */
}


static void UART2_Interrpt_Handler(void *arg)
{
Serial.println("Ponto 1");
uart_clear_intr_status(UART_ID, UART_TX_DONE_INT_ENA_M | 0x00000000ULL);
//uart_disable_intr_mask(UART_ID, UART_INTR_MASK);
}


void setup()
{
Serial.begin(19200);
pinMode(LED_ON_BOARD, OUTPUT);
WiFi.disconnect();

Serial.printf("\nSDK version using ESP object: %s", ESP.getSdkVersion()); /* Using ESP object */
Serial.printf("\nSDK version using low level function: %s", esp_get_idf_version()); /* Using low level function */


/* Setting TIMER0 - Used to define base time (tick) of 100ms */
timer_config.divider = 80; timer_config.counter_dir = TIMER_COUNT_UP; timer_config.counter_en = TIMER_PAUSE;
timer_config.alarm_en = TIMER_ALARM_EN; timer_config.intr_type = TIMER_INTR_LEVEL; timer_config.auto_reload = TRUE;
timer_init(TIMER_GROUP_0, TIMER_ID, &timer_config);
timer_set_counter_value(TIMER_GROUP_0, TIMER_ID, 0x00000000ULL); /* Start value to Timer */
timer_set_alarm_value(TIMER_GROUP_0, TIMER_ID, 10000); /* Alarm value to Timer */
timer_enable_intr(TIMER_GROUP_0, TIMER_ID);
timer_isr_register(TIMER_GROUP_0, TIMER_ID, TIMER_Group0_ISR, (void *) TIMER_ID, ESP_INTR_FLAG_IRAM, NULL);
timer_start(TIMER_GROUP_0, TIMER_ID);

/* Setting UART2 - Used to serial communication whith slaves modules */
uart_param_config(UART_ID, &uart_config); /* Setting communication parameters */
uart_set_pin(UART_ID, TXD_PIN, RXD_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); /* Setting communication pins */
uart_driver_install(UART_ID, RX_BUF_SIZE, TX_BUF_SIZE, 0, NULL, ESP_INTR_FLAG_EDGE); /* Driver installation */
uart_set_line_inverse(UART_ID, UART_INVERSE_TXD); /* Invert level of Tx line */
gpio_set_pull_mode(RXD_PIN, GPIO_FLOATING); /* Turn-off pull-up and pull-down of UART RX pin */
uart_flush(UART_ID); /* Clear RX buffer */

/* Setting UART2 interrupts */
uart_enable_intr_mask(UART_ID, UART_TX_DONE_INT_ENA_M | 0x00000000ULL);
uart_isr_register(UART_ID, UART2_Interrpt_Handler, NULL, ESP_INTR_FLAG_EDGE, &handle_console); /* Register new UART ISR subroutine */

/* Create Schedule Table */
mainData.scheduleTable = Comm_appl_Create_Schedule_Table();
}


void loop()
{
if(Counter1Of10ms >= T10ms){
Counter1Of10ms = 0;
Task10ms(); /* call Task10ms() */
}
if(Counter2Of10ms >= T500ms){
Counter2Of10ms = 0;
Task500ms(); /* call Task500ms() */
}
if(Counter3Of10ms >= T1000ms){
Counter3Of10ms = 0;
Task1000ms(); /* call Task1000ms() */
}
}


void Task10ms(void)
{
Comm_appl_FSRM(&mainData);
}


void Task500ms(void)
{
digitalWrite(LED_ON_BOARD, !digitalRead(LED_ON_BOARD));
Comm_appl_Request_ChangeOf_FSRM_State(&mainData, FSRM_State_Send);
}


void Task1000ms(void)
{

}
Attachments
main.zip
(5.97 KiB) Downloaded 425 times

WiFive
Posts: 3529
Joined: Tue Dec 01, 2015 7:35 am

Re: UART TX Interrupt - How to use UART_TX_DONE_INT

Postby WiFive » Thu Jul 04, 2019 5:38 am

uart_driver_install will setup it's own interrupt handler so you should not overwrite it. You can either modify it or use uart_wait_tx_done.

Pablo Silva
Posts: 2
Joined: Wed Jul 03, 2019 2:36 pm

Re: UART TX Interrupt - How to use UART_TX_DONE_INT

Postby Pablo Silva » Fri Jul 05, 2019 5:03 pm

Thanks for reply,

I understood you said. I would like overwrite handler. I tried use uart_isr_free() after uart_drive_intall(), then use uart_isr_register(), but this did not work as I would like, also the timer interruption stopped.

You have some idea how solve this?

Who is online

Users browsing this forum: Bing [Bot], forrest, REEASD, snutw_ and 145 guests