• 0
Ajeeth_kumar

Facing problem on usage of four uart16550 in Zybo

Question

Hi, 

I am working on a project where i use four UART for an application, all four uart lines sends and receives approx. 20 bytes of characters and expects 20 bytes o  character in every 16 milliseconds. And the data transfer will be continuous. 

NOTE All four UARTs, are on PL side and controlled by PS of my zynq SoC..

NODE B : Zybo

NODE A : Subsystem

The UART communication is between NODE A and NODE B. NODE A sends data to  NODE B, in turn NODE B should receive the data and reply with an acknowledgement. In this case NODE B is my Zybo Node A is another subsystem.

So the data transmission is initiated by NODE A and the control is with NODE A. NODE A will Enable the data transmission for all four UARTs.

Now the problem which i am facing is, when NODE A enables the transmission for any two of the UART lines the data transmission is smooth, the problem arises only when i enable the other two. Which means the zybo is not capable of attending to those interrupts which is simultaneously coming from NODE A through four UART lines.

My data contains Start byte and Stop byte, Both Start and stop byte are same character. I will attach a my Interrupt handler for reference. 

 

**************NOTE**************

UART IP on PL side : UART16550

Type of UART : Interrupt driven.

Software used : Vivado 2018.3 and SDK 

Bare metal software.

UART interrupt priority : equal priority for all four UARTs.

**********************************

I am not very sure about how to use four UARTs efficiently with my Zybo .

Please help me with the problem, any inputs from your side will be appreciated. 

 

 

 

The following is my UART interrupt handler.

***************************************************************************

static void RW1RecvHandler(void *CallBackRef, unsigned int EventData)
{

    int i, ch, RecvCount, index;
    RecvCount = EventData;

    // repeat this loop for all chars received, i.e., for all ReceivedCount

    i = 0;
    while (i < RecvCount) {

        ch = RW1_RecieveBuffer[i++];  // get the received char from the buffer

        if(RW1_Start_byte_flag == 1)
        {

                // Stop Byte Check for RW1

                if (ch == 0xc0)
                {
                    // Ignore one of the two successive start byte characters
                    if (RW1_ReceivedCount > 1)
                    {
                        RW1_Start_byte_flag = 0;
                        RW1_Buffer[RW1_ReceivedCount++] = ch;
                        RW1_Frame_complete_flag = 1;

                    }

                }
                else
                {
                    if ((index = RW1_ReceivedCount) < TEST_BUFFER_SIZE) {
                        RW1_Buffer[index] = ch;
                        RW1_ReceivedCount++;


                    }
                    else
                        RW1_Start_byte_flag = 0;
                }

        }
        // Start Byte Check for RW1

        else if (ch == 0xc0)
                {
                    RW1_Start_byte_flag = 1;
                    RW1_ReceivedCount   = 0;
                    RW1_Buffer[RW1_ReceivedCount++] = ch;

                    // Note the cpu time when first character is received
                    XTime_GetTime(&t_start_RW1);

                    RW1_Frame_complete_flag = 0;


                }
    }
    if(RW1_Frame_complete_flag == 0)
    {
        // set up the buffer for next char in interrupt mode

        XUartNs550_Recv(&RW1, RW1_RecieveBuffer, 1);
    }
}

 

 

Thanks & Regards

Ajeeth Kumar 

Share this post


Link to post
Share on other sites

6 answers to this question

Recommended Posts

  • 0

Hi @Ajeeth_kumar,

Sound like an interesting project. I have not set up an fpga project using multiple uart interrupts. Here, here, here and here are forum threads that deal with a couple of different topics using the uartlite IP that i think would be useful.  I would also suggest looking through the xilinx material here: C:\Xilinx\SDK\2019.1\data\embeddedsw\XilinxProcessorIPLib\drivers\uartlite_v3_2.

best regards,

Jon

Share this post


Link to post
Share on other sites
  • 0

Hi @Ajeeth_kumar,

I'm sorry that I didn't notice the 16550 portion of your post. I haven't worked much with the UART16550 IP. I would suggest looking through the xilinx documentation C:\Xilinx\SDK\2018.3\data\embeddedsw\XilinxProcessorIPLib\drivers\uartns550_v3_5 which includes the interrupt example here. Here is a xilinx forum thread discussing zynq priority for interrupts.

best regards,

Jon

Share this post


Link to post
Share on other sites
  • 0

Hi @jpeyron,

As you suggested to start with this C:\Xilinx\SDK\2018.3\data\embeddedsw\XilinxProcessorIPLib\drivers\uartns550_v3_5.

I have already gone through that example provided by xilinx and tried running it.

With this example as a base, I have started my project.

So just by having a look at the example project is not going to help me out I guess.

Regards

Ajeeth Kumar

 

Share this post


Link to post
Share on other sites
  • 0
On 7/11/2019 at 2:08 AM, Ajeeth_kumar said:

All four UARTs, are on PL side and controlled by PS of my zynq SoC..

@Ajeeth_kumar

OK, I admit that I haven't quite grasped your design. From the above statement I draw the conclusion that you've mapped some of the PS UART ports though the PL. Later on you say that you are using UART 16650 IP. So does that mean that some of your UARTs are implemented in the PL? If so how are they connected. I've never had experience doing exactly what I you are doing and I use a different approach to ZYNQ design so my experience might not be relevant.

This isn't clear to me; are you trying to bond UART channels and need to maintain some sort of data coherence in hardware? You haven't described the issues in sufficient detail for me to wrap my mind around it.

If you're running a bare metal application you shouldn't be having an issue servicing interrupts for 4 UARTs. You don't mention baud rates. If communications are periodic you might want to consider how you handle interrupts; that is service all of the UARTs in one interrupt if that's possible. 20 bytes per UART every 16 ms doesn't seem to be too optimistic. What's not clear is if your system can tolerate larger Rx/Tx data buffers and hence latency in data transfer. You'll have to figure that out. I have seen issues with the SDK switching UART names when I've added new UARTs but I doubt that this is a problem for you.

It's easy to think that if you just make every interface in a system interrupt driven the processor(s) will take care of issues that you don't want to worry about. A well thought out timing plan using 1 interrupt or perhaps even just polling might be easier and work better. Bigger buffers help processing bottlenecks but introduce latency issues. Latency issues usually are resolved on a system design level.

Sorry if none of this helps....

 

Edited by zygot

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now