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

User avatar
By wjzhang
#5125 Here is my leaning when rewrite UART driver:
1) for UART_TXFIFO_EMPTY_INT, as igrr tips. don't init at start. when write data and exceed FIFO size,then set. when no, need disable
2) using variable to check interrupt running. no os_printf(). as strolch tip. because the os_printf() no output at all.
3) using WRITE_PERI_REG(UART_INT_CLR(UART0), source) to clean the each interrupt source.
4) for UART_RXFIFO_FULL_INT/UART_RXFIFO_TOUT_INT. as igrr tips. you need read all data. did not just do : first read Rx FIFO data number, then read the numbers of data.
you driver need real RX FIFO complete. then call WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_TOUT_INT_CLR)/WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_FULL_INT_CLR) to clean interrupt.
User avatar
By 3s1d
#8658 Hi,

could somebody please post a complete UART TX FIFO INTERRUPT based example.
I'm trying to get it working for UART1, however it fails the second I write something to the threshold (even with disabled tx fifo interrupt).

Initialization:

Code: Select allETS_UART_INTR_DISABLE();

[config UART1]

//overload uart int handler
ETS_UART_INTR_ATTACH(intr_handler,  NULL);

//set tx fifo trigger
WRITE_PERI_REG(UART_CONF1(UART1), 54 << UART_TXFIFO_EMPTY_THRHD_S); //gives us 200uS to reakt

//disable tx_interrupt
CLEAR_PERI_REG_MASK(UART_INT_ENA(UART1), UART_TXFIFO_EMPTY_INT_ENA);

//clear all interrupt
WRITE_PERI_REG(UART_INT_CLR(UART1), 0xffff);

ETS_UART_INTR_ENABLE();


So far I have not set the UART_TXFIFO_EMPTY_INT_ENA bit. But it stops right now.

In the interrupt handle I do to following

Code: Select allLOCAL void ICACHE_RAM_ATTR intr_handler(void *para)
{
   /* uart0 and uart1 intr combine together, when interrupt occur, see reg 0x3ff20020, bit2, bit0 represents
    * uart1 and uart0 respectively
    */
   if(READ_PERI_REG(UART_INT_ST(UART1)))   //any UART1 stuff
   {
      if(UART_TXFIFO_EMPTY_INT_ST == (READ_PERI_REG(UART_INT_ST(UART1)) & UART_TXFIFO_EMPTY_INT_ST))
         fill_fifo();

      //clr int
//      WRITE_PERI_REG(UART_INT_CLR(UART1), UART_TXFIFO_EMPTY_INT_CLR);
      WRITE_PERI_REG(UART_INT_CLR(UART1), 0xffff);   //just to be sure :)
   }

   if(READ_PERI_REG(UART_INT_ST(UART0)))   //any UART0 stuff
   {
      uart0_rx_intr_handler(&(UartDev.rcv_buff));
   }
}



The idea would be that the interrupt handler is doing nothing for UART1 nothing until I say:
Code: Select all   //enable tx_interrupt
   SET_PERI_REG_MASK(UART_INT_ENA(1), UART_TXFIFO_EMPTY_INT_ENA);


However, it fails right after the init.

Any Ideas?
Juergen
User avatar
By 3s1d
#8723 Hi

I figured it out. The uart.c provided by the ESP guys set the rx-fifo-full bit which was continuously triggering the interrupt as soon as I set a new TX threshold. Don't know why...

Anyway, if somebody is interested in my code:
https://github.com/3s1d/WiFiYaala/blob/ ... d/ws28xx.c

Here I am driving WS2811/WS2812(B) or WS2801 LED of the UART2 pin. The fifo allows for a glitch free timing even when the CPU is under heave interrupt load.

For the WS281x an additional mosfet + pull-up (for inverting the signal) is required. For the ws2801 you need an ATtiny85 to generate the SCL signal. See my code in the same repository. Note that the code for the AVR is also capable of acting as an inverter for the WS281X.

Regards,
Juergen