Xilinx Zynq console rx not working

Chris Johns chrisj at rtems.org
Tue Aug 17 05:13:13 UTC 2021


On 17/8/21 8:59 am, Chris Johns wrote:
> On 16/8/21 11:03 pm, Kinsey Moore wrote:
>> On 8/16/2021 04:45, Chris Johns wrote:
>>> On 16/8/21 6:38 pm, Chris Johns wrote:
>>>> I have taken a closer look at the driver. I am receiving RX interrupts and the
>>>> characters are being queued however the receive FIFO trigger interrupt is only
>>>> raised when the FIFO reaches the set threshold of half the FIFO size. I suspect
>>>> there is an assumption the RX timeout will fire but it is not.
>>>>
>>> Doing this is questionable ....
>>>
>>> https://git.rtems.org/rtems/tree/bsps/shared/dev/serial/zynq-uart.c#n222
>>>
>>> You cannot send a character when touching the attributes. Where is this hardware
>>> bug documented by Xilinx?
>> The attributes are done being touched and the TX/RX enable flags are set again
>> before sending the character. I was seeing the same behavior on Zynq QEMU even
>> with this code removed.
>>
>> I couldn't find the hardware bug documented anywhere, but out of the 3 ZynqMP
>> boards I have one requires this consistently.
> 
> I suggest we use chip maker errata when documenting hardware bugs as it could
> turn out to be a bug in a our code.
> 
> This smells to me like a set up problem.
> 
>>>
>>> My application does this ...
>>>
>>>      if (tcgetattr(fileno(stdout), &term) < 0)
>>>          error_message();
>>>      cfsetispeed (&term, B115200);
>>>      cfsetospeed (&term, B115200);
>>>      if (tcsetattr (fileno(stdout), TCSADRAIN, &term) < 0)
>>>          error_message();
>>>      if (tcgetattr(fileno(stdin), &term) < 0)
>>>          error_message();
>>>      cfsetispeed (&term, B115200);
>>>      cfsetospeed (&term, B115200);
>>>      if (tcsetattr (fileno(stdin), TCSADRAIN, &term) < 0)
>>>          error_message();
>>>
>>> and this kills the receive interrupts.
>>
>> Does removing the null character kick restore functionality for you in this case?
> 
> No it did not.

I have read the Zynq-7000 TRM and the Versal ACAP TRM and there is a difference
in the wording around the RX timeout. It seems the RX timeout has evolved in the
Versal to a timer that can interrupt if data has entered the FIFO then no more
within the timeout period and the FIFO trigger level has not been reached. The
timer on the Zynq does not do this. It is something that can handle inter-gap
checks for those serial protocols that require this and there a few of them.
They delimit frames using time domain signalling. To make it work on a zynq-7000
I think you need to receive the first character (rtrig=1) then in the interrupt
handler raise the FIFO trigger level and prime the timer to achieve the Versal
timer functionality. I cannot be bothered doing this.

All we have is a console and that is a pretty basic use case for a UART. As a
result I have lowered the RX trigger level to 1 and disabled the RX timer. I
have also added support to send a FIFO full of data.

The solution is not as optimal as it could be with the Versal UART. If this
becomes a problem and someone wants a lower interrupt count we can look
specialising the driver based on the variant of the UART or implement the timer
protocol I outlined above.

I will create a patch and test on qemu and the Versal then post.

Chris



More information about the devel mailing list