UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Observer lmeyerovich
Observer
253 Views
Registered: ‎05-08-2018

UART 16550 v2.0 In FIFO mode receives interrupt on every byte

I am running AXI UART 16550 implemented for ZCU102 evaluation board (UltraScale+). 

Only Rx interrupt is enabled (Tx is disabled). FIFO is configured for any thrigger level other than 1, I have tried 14, 8, 4. I have cretated an example to count number of interrupt received and figured out that an interrupt is triggered for every incoming byte

What am I doing wrong?

Thanks

 

Here is my initialization and IRQ function:

    /* Set word length, stop bits, and parity based off configuration */

    *REG_PTR(vaddr, LCR) |= (LCR_WLS(uart_conf->word_len) | (uart_conf->stop_bits * LCR_STB));

    if (uart_conf->parity != UART16650_PARITY_NO) {

        *REG_PTR(vaddr, LCR) |= (LCR_PEN | (uart_conf->parity * LCR_EPS));

    }

 

    *REG_PTR(vaddr, IIR);  // clear Tx interrupt

    *REG_PTR(vaddr, FCR) = FCR_FIFOEN | FCR_RCFR | FCR_XMFR | FCR_RFTL(3);

    *REG_PTR(m_vaddr, IER) = (IER_EFBFI | IER_ELSI);

And interrupt processing (this function gets called from IRQ handler:

int axi_process_interrupt(int uartIndex, char *pbuf, int *nbytes)

{

                unsigned int vLSR;

                ps_chardevice_t* d = uarts[uartIndex].dev;

                unsigned int vIIR = *REG_PTR(d->vaddr, IIR);

                if ((vIIR & INTERRUPT_PENDING_MASK) == 0)

                {// interrupt pending

                                unsigned int iir = (vIIR & INTERRUPT_ID_MASK) >> 1;

                                switch (iir)

                                {

                                case uart16550_RECEIVER_LINE_STATUS:

                                                // clear interrupt

                                                vLSR = *REG_PTR(d->vaddr, LSR);

                                                if ((vLSR & 0x80) != 0)

                                                return uart16550_RECEIVER_LINE_STATUS;

                                                break;

                                case uart16550_CHARACTER_TIMEOUT:

                                case uart16550_DATA_AVAILABLE:

                                                // read date from FIFO. This interrupt is cleared when the Receiver FIFO drops below the trigger level.

                                                *nbytes = 0;

                                                while (true)

                                                {

                                                                unsigned int vLSR = *REG_PTR(d->vaddr, LSR);

                                                                if ((vLSR & 0x2) != 0)

                                                                             return -1; // Overrun Error.

                                                                if ((vLSR & 0x1) == 0)

                                                                              break;

                                                                // data is available

                                                                pbuf[*nbytes] = (*REG_PTR(d->vaddr, RBR)) & 0xFF;

                                                                (*nbytes)++;

                                                }

                                                return uart16550_DATA_AVAILABLE;

                                                break;

                                case uart16550_TX_IS_EMPTY:

                                                return uart16550_TX_IS_EMPTY;

                                                break;

                                }

                }

                return -2;

}

0 Kudos