Page 1 of 1

ESP32 WROOM (IDF) UART RX interrupt timeout

Posted: Mon Oct 11, 2021 1:42 pm
by oktheorignal
Hi to all,
Let me explain my setup. MCU 1 has to send 400 bytes to MCU 2. I am enabling interrupts to receive these 400 bytes via uart. The default FIFO hardware buffer is 128 bytes in the RAM which can not be increased. My implementation is reading 100 bytes on every interrupt call.
I am facing trouble with using RX interrupts in my code. I have enabled rx interrupts on uart_num_1. I set my uart FIFO full threshold to be 100 bytes. The interrupt does trigger when I send 100 bytes (FIFO FULL EVENT) but it does not trigger when I send 1-99 bytes(RX TIMEOUT EVENT). This 1 - 99 byte trigger is important as this will signal an out of sync state. My sending side sends 400 bytes at 0.5 second intervals. And at boot if only 301-399 bytes are received that indicates an unsynchronized MCU. But as my interrupt does not trigger if I send 1-99 bytes, I can not synchronize my receiving side.

My questions are as follows,
1. Why is my esp32 not registering an interrupt on reception of a packet less than FIFO size?
2. I am also unable to set the size of my tx ring buffer. As soon as I set it an upload, the esp32 crashes repeatedly with a "uart_driver_install error" What is the reason for this?

Code:
ISR plus variables:
char array[20] = {0};
uint8_t rxbuff[500];
int packetincr = 0;
uint8_t wipe;
bool packetrcv = 0;
char temp[40] = {0};

static void IRAM_ATTR uart_intr_handle(void *arg)
{
//ISR CALLED ON RX TIMEOUT AND ON FIFO FULL

uint16_t rx_fifo_len;
rx_fifo_len = UART1.status.rxfifo_cnt; // read number of bytes in UART buffer
sprintf(temp, "Length of fifo: %d", rx_fifo_len);
uart_write_bytes(Serial1, &temp, sizeof(temp));
vTaskDelay(1 / portTICK_PERIOD_MS);
if (rx_fifo_len < 100)
{
while (rx_fifo_len)
{
wipe = UART1.fifo.rw_byte;
rx_fifo_len--;
}
packetincr = 0; //reset packetcount
uart_clear_intr_status(Serial1, UART_RXFIFO_FULL_INT_CLR | UART_RXFIFO_TOUT_INT_CLR);
return;
}
if (packetincr == 0)
{
for (int i = 0; i < 100; i++)
{
rxbuff = UART1.fifo.rw_byte;
}
packetincr++;
}
else if (packetincr == 1)
{
for (int i = 100; i < 200; i++)
{
rxbuff = UART1.fifo.rw_byte;
}
packetincr++;
}
else if (packetincr == 2)
{
for (int i = 200; i < 300; i++)
{
rxbuff = UART1.fifo.rw_byte;
}
packetincr++;
}
else if (packetincr == 3)
{
for (int i = 300; i < 400; i++)
{
rxbuff = UART1.fifo.rw_byte;
}
packetincr = 0;
packetrcv = 1;
}

uart_clear_intr_status(Serial1, UART_RXFIFO_FULL_INT_CLR | UART_RXFIFO_TOUT_INT_CLR);
}

//UART SETTINGS. SERIAL 1 IS my second controller
void Initialise_UART()
{

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(Serial0, &uart_config));
//Set UART pins (using UART0 default pins ie no changes.)
ESP_ERROR_CHECK(uart_set_pin(Serial0, 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(Serial0, 1024, 0, 0, NULL, 0));

uart_config_t uart_config2 = {
.baud_rate = 38400,
.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_int_config2 = {
.intr_enable_mask = UART_RCV_INTEN,
.rx_timeout_thresh = 20, //threshold UNIT is the time passed equal to time taken for 1 bytes to arrive
.txfifo_empty_intr_thresh = 0,
.rxfifo_full_thresh = 100};

ESP_ERROR_CHECK(uart_param_config(Serial1, &uart_config2));
ESP_ERROR_CHECK(uart_set_pin(Serial1, 32, 33, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
ESP_ERROR_CHECK(uart_driver_install(Serial1, 1024, 0, 0, NULL, 0));
ESP_ERROR_CHECK(uart_isr_free(Serial1));
ESP_ERROR_CHECK(uart_isr_register(Serial1, uart_intr_handle, NULL, ESP_INTR_FLAG_IRAM, NULL));
ESP_ERROR_CHECK(uart_enable_rx_intr(Serial1));
ESP_ERROR_CHECK(uart_intr_config(Serial1, &uart_int_config2));
}

void app_main()
{
Initialise_GPIO();
Initialise_UART();

while (1)
{
blink_task();
if (packetrcv)
{
uart_write_bytes(Serial1, "\nD R", 4);
packetrcv = 0;
}
}
}