XC7Z012S UARTNS16550 Receive Interrupt in Freertos

Hi I am working Freertos with Zynq 7000 SOC XC7Z012S . I have added UARTNS16550 IP in vivado block diagram. I want to receive data from my UART device to Zynq Chip over interrupt.
I tried xPortInstallInterruptHandler function to handle interrupts from serial port. I have 3 uarts that are used for receiving data from other devices. But with this function only one uart interrupt is working…
how to handle multiple interrupts in XC7Z012S UARTNS16550 using freertos ?

Can you post the prototype of the interrupt handler. Is there a parameter that passes the interrupt number, or a structure that represents the instance of the UART?

u8 uart0Byte;
u8 uart1Byte;

void Uart0IntrHandler(void *prvParams)
{
	uart0Byte = XUartNs550_RecvByte(UART0_DEVICE_BASEADDR);
	// data processing, some small calculations
}

void Uart1IntrHandler(void *prvParams)
{
	uart1Byte = XUartNs550_RecvByte(UART1_DEVICE_BASEADDR);
	// data processing, some small calculations
}

void main()
{
	Status = CnUartNs550Init(&IntcInstance,
					&UartNs550_0_Instance,
					UART0_DEVICE_ID,
					UART0_INTR_ID);

	if (Status != XST_SUCCESS) {
		xil_printf("UartNs550_0_Instance Failed\r\n");
		return XST_FAILURE;
	}


	Status = CnUartNs550Init(&IntcInstance,
					&UartNs550_1_Instance,
					UART1_DEVICE_ID,
					UART1_INTR_ID);

	if (Status != XST_SUCCESS) {
		xil_printf("UartNs550_1_Instance Failed\r\n");
		return XST_FAILURE;
	}

	xStatus = xPortInstallInterruptHandler(UART0_INTR_ID, Uart0IntrHandler, &UartNs550_0_Instance);

	if(xStatus == pdPASS)
	{
		xil_printf("UART0 Interrupt Installed Successfully\r\n");
	}
	else
	{
		xil_printf("Interrupt Installed Failed with %d\r\n",xStatus);
	}

	vPortEnableInterrupt(UART0_INTR_ID);


	xStatus = xPortInstallInterruptHandler(UART1_INTR_ID, Uart1IntrHandler, &UartNs550_1_Instance);

	if(xStatus == pdPASS)
	{
		xil_printf("UART1 Interrupt Installed Successfully\r\n");
	}
	else
	{
		xil_printf("Interrupt Installed Failed with %d\r\n",xStatus);
	}

	vPortEnableInterrupt(UART1_INTR_ID);

        vTaskStartScheduler();

        for (; ;);
}

I have three devices:

  1. Device#1 → 1Mbps Baudrate, sends 16 bytes every 10ms.
  2. Device#2 → 1.8432Mbps Baudrate, sends 42 bytes every 2ms.
  3. Device#3 → 9600bps Baudrate, sends 68 bytes every 1000ms.

If I configure all the three interrupts then nothings is working.
If I configure for Device#3 i am able to parse out data.
But with device#1 and #2 i am receiving data but with lots of data being lost.

Does XUartNs550_RecvByte() also clear the interrupt? Or are you supposed to do that separately? If it isn’t clearing the interrupt could it be you are just continuously re-entering the interrupt handler?

I would suggest starting with a simple configuration to help identify where it is going wrong.
For example, what happens if you initialise, install and use one UART at a time? Do all three work when you use them individually?

XUartNs550_RecvByte() does not clear the interrupt.
I have to do it seperately.
Individually all three interrupts are working…I tested that.
How to clear the interrupts ?

You will need to look at the documentation and examples that come with the IP for that info. If you are using Xilinx provided BSP there will no doubt be an API for it. It will be similar to this example which is clearing the interrupt for a completely different peripheral.