UART TX Interrupt - How to use UART_TX_DONE_INT
Posted: 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)
{
}
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)
{
}