Skip to main content

ESP32: UART interrupt Handling

I am Sushant, from Mumbai, India. I am an embedded firmware engineer,
i love to write code for micro controllers. This may not be a professional post, you may have to tolerate my unprofessional writing skills. Anyways todays topic in ESP32, a very commonly and trending MCU. I had come across project where there was a need to write my own code for UART, i tried or you can searched google even on page 2, but could find any sample code or example. I found the solution, not easy way, had to put in some hours, but i would like to put this example in blog so everybody can use it or understand it,

It is simple code for UART receive interrupt,

So Lets start,

Everybody must be aware of how to initialise UART to use as RTOS task in ESP32, oh yeah and also i have used ESP-IDF to demostrate this code, so for arduino geeks this may not help, not a arduino FAN :).

Firstly,  Configuring parameters of an 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(EX_UART_NUM, &uart_config));
//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));

Registering UART ISR;

This is normal UART init as per ESP32 library, now comes the fun part, as you install UART driver, it initializes interrupt and registers interrupt handler, so if you try to register new interrupt handler is will through out and error or fault, for this you have to release pre registered interrupt handler, below is code for it;
// release the pre registered UART handler/subroutine
   ESP_ERROR_CHECK(uart_isr_free(EX_UART_NUM));       

// register new UART ISR subroutine
  ESP_ERROR_CHECK(uart_isr_register(EX_UART_NUM,uart_intr_handle, NULL, ESP_INTR_FLAG_IRAM, &handle_console));

here as you can find the prototype for uart_isr_register in uart.h,

and finally you have to indicate interrupt type, i have set receive interrupt for Timeout and RX fifo full,
//ESP_LOGI(TAG, "Return from UART ISR %X", ret);
  ESP_ERROR_CHECK(uart_enable_rx_intr(EX_UART_NUM));

and we are done with initialization process, now we will jump to ISR,

Interrupt Subroutine,

In UART isr, you will have to find interrupt status, if it is rx interrupt, number of bytes received and you need to collect those bytes from core library, for that purpose you will need to use
UART0 structure , this core structure is defined in uart_struct.h

Following is the code for UART ISR,
static void IRAM_ATTR uart_intr_handle(void *arg)
{
  uint16_t rx_fifo_len, status;
  uint16_t i;
  
  status = UART0.int_st.val; // read UART interrupt Status

  rx_fifo_len = UART0.status.rxfifo_cnt; // read number of bytes in UART buffer
  
  while(rx_fifo_len){
  rxbuf[i++] = UART0.fifo.rw_byte; // read all bytes
  rx_fifo_len--;
  }
  
  // after reading bytes from buffer clear UART interrupt status
  uart_clear_intr_status(EX_UART_NUM, UART_RXFIFO_FULL_INT_CLR|UART_RXFIFO_TOUT_INT_CLR);

  // a test code or debug code to indicate UART receives successfully,
  // you can redirect received byte as echo also
  uart_write_bytes(EX_UART_NUM, (const char*) "RX Done", 7);
}


So, it turn out to be easy task anyway, just need some guidelines, everybody does.

you can find the full working code on github as ESP32-UART-interrupt-handling

Comments

Popular posts from this blog

ESP32: Webserver using esp-idf SDK

Web-Server or Web-socket oe http socket is most commonly used method to read or write data from Ethernet or now as we move to new technology WiFi in embedded universe. It was already there, but with cheap and easily available ESP modules it has taken a big leap forward. Here in this topic, i will explain you to added Web Server to ESP32 module using eclipse. If you are new to ESP32 using eclipse you start from here for adding ESP32 in eclipse. Ok lets start with ESP32 Webserver, initialization, struct netconn *conn, *newconn; err_t err; conn = netconn_new(NETCONN_TCP); // Create TCP socket netconn_bind(conn, IP_ADDR_ANY, 80); // bind socket netconn_listen(conn); Now, write the main body to accept web client connection and to decrypt http frame. do { err = netconn_accept(conn, &newconn); // accept incoming connection if (err == ERR_OK) { ESP_LOGI(TAG, "Accepted Conn %d\n", err); http_server_netconn_serve(n