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,
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,
and we are done with initialization process, now we will jump to ISR,
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;
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,UART0 structure , this core structure is defined in uart_struct.h
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
Post a Comment