Use this forum to chat about hardware specific topics for the ESP8266 (peripherals, memory, clocks, JTAG, programming)

User avatar
By wjzhang
#5003 what's wrong with UART interrupt? i send data once. but got the receive task run many times and no stop.
in ISR:
{
.......
if(UART_RXFIFO_FULL_INT_ST == (READ_PERI_REG(UART_INT_ST(UART0)) & UART_RXFIFO_FULL_INT_ST))
{
//ETS_UART_INTR_DISABLE();
os_sprintf("Rx Full\r\n");
ETS_UART_INTR_DISABLE();
clearisr |= UART_RXFIFO_FULL_INT_CLR;
uart0_rx_data();
system_os_post(USER_TASK_PRIO_0, 0, 0);
}
//Rx time out
if(UART_RXFIFO_TOUT_INT_ST == (READ_PERI_REG(UART_INT_ST(UART0)) & UART_RXFIFO_TOUT_INT_ST))
{
//ETS_UART_INTR_DISABLE();
os_sprintf("Rx timeout\r\n");
ETS_UART_INTR_DISABLE();
clearisr |= UART_RXFIFO_TOUT_INT_CLR;
uart0_rx_data();
system_os_post(USER_TASK_PRIO_0, 0, 0);
}
.....
//clear interrupt flags
WRITE_PERI_REG(UART_INT_CLR(UART0), clearisr);
}
User avatar
By wjzhang
#5035 Thank you for tips! strolch. but the os_sprintf() is not root cause of this issue.
the import is "How can clear the UART interrupt".
User avatar
By igrr
#5108 Hey, i was just rewriting some of my UART code, and learned a few things about the way UART works on this chip. Here are two tips for you:

First, when handling UART_RXFIFO_FULL interrupt, you need to actually read all the bytes from the RX FIFO, and then clear the interrupt. Take a look at uart.c from Espressif IoT sample.

Next, UART_TXFIFO_EMPTY interrupts. These were a bit harder to figure out, because there wasn't any sample that used them. They act differently from what i've seen on other chips.

In your code you enable UART_TXFIFO_EMPTY interrupts, set the threshold, and your program stops... right, because TXFIFO_EMPTY interrupt occurs! It occurs whenever the TX FIFO level is less (maybe less or equal — don't know that for sure) than the threshold. On other chips, such interrupt would occur when you cross the threshold. On esp8266, it occurs when you are below the threshold. It doesn't matter that you clear this interrupt — it will still fire right after the previous TXFIFO_EMPTY interrupt finished running. In your case, your program is stuck in the interrupt handler because TXFIFO_EMPTY interrupt keeps firing.

So the way to work with TXFIFO_EMPTY interrupts is like this. Start with TXFIFO_EMPTY interrupt disabled. When you have data to put into the UART, determine if it fits into TX FIFO (128 bytes). If it does, just put it into the FIFO and forget about interrupts. If it doesn't, fill the TX FIFO, and then enable TXFIFO_EMPTY interrupt. When the interrupt fires, put more data into the FIFO. If there is no more data to send at the moment, disable TXFIFO_EMPTY interrupt by clearing the appropriate bit in the UART interrupt mask.

This seems to work for me, but may very well be wrong at some level... but as i said, it works for me :)