Skip to content

UART communication issues between 2 Pico's, random bytes missing and phantom byte at startup #1144

@chrisckc

Description

@chrisckc

The Test Setup:

I have 2 Pico's wired together to test UART communications, I am using UART0, pins GP0 -> GP1, GP1 -> GP0 , GND and VSYS wired together.

I built a Test Harness based on these examples:
https://github.com/raspberrypi/pico-examples/tree/master/spi/spi_master_slave
https://github.com/raspberrypi/pico-examples/blob/master/uart/uart_advanced/uart_advanced.c

I modified the way it operates so that it first sends a separate, single byte, data transfer before the buffer is transferred. The output and input buffers have also been reduced from 256 bytes to 255 so I can send the buffer size as a single byte before sending the buffer.

I increased the send rate from 1 per second to 10 per second.
There is also a lot of extra serial output and error capturing and reporting has been added.
I deliberately did not add any start synchronisation to the transfers, it is simply a game of ping pong between the 2 Pico's, the sender sends the buffer size followed by the buffer, the receiver checks to make sure it has received what is expected and sends back its own buffer in the same way, which is a reversed copy of the buffer sent to it. The sender then checks to make sure the response from the receiver is as expected. After 100 milliseconds the process is repeated.

The code is here:
https://github.com/chrisckc/TestHarness-UART-Pico-SDK
In order to properly view the serial output you will need to use a proper terminal emulator, ie. one that supports ANSI control characters. I use iTerm2 on MacOS with a command to launch screen against the usb tty.

The issues:

There are 2 issues:

Issue 1, phantom byte at startup:

The receiver always sees an extraneous interrupt after startup, well before any data is actually sent to it. Inside the interrupt, uart_is_readable(uart0) returns true and then uart_getc(uart0) returns a null byte. This happens regardless of baud rate or whether the FIFO is enabled or not. This results in the receiver initially reporting an empty page being received before data is actually sent to it. Data only starts to be sent to the receiver 1 second after it is ready and waiting to receive it (refer to the delay code at the start of main for both the receiver and sender).

Issue 2, random bytes missing:

The sender is unable to reliably receive a response from the receiver at baud rates above 115200, the higher the baud rate the higher the error rate.

At 230400 baud the error rate is around 1.1%

At 460800 baud the error rate is around 95%

At 921600 baud the error rate is 100%

The error seems to be in some way related to the use of the USB serial during the reception of data on UART0, if I disable the part of the test code which is outputting some results from the UART0 send operation while the UART0 receive operation is in progress, the error rate drops significantly, but not completely at all supported baud rates.

For UART0 receive without any simultaneous USB serial output:

At 230400 baud the error rate is 0%

At 460800 baud the error rate is around 0%

At 921600 baud the error rate is 32%

For some reason these errors are only seen on the sender when it is receiving its response from the receiver. I have not seen these errors on the receiver, which is using the same code to receive data and receiving the same amount.

The only issue I have seen on the receiver is Issue 1, the phantom byte at that start. Strangely this does not seem to occur on the sender when it receives its first response from the receiver. The difference is that it sends data out on UART0 before before it checks if data has been received, I will need to make some modifications to investigate that aspect further.

Notes:

The above tests were conducted with the FIFO disabled as in the uart_advanced example.

With the FIFO enabled, issue 1 still occurs at all baud rates.

With the FIFO enabled, the error rate for issue 2 is zero for all of the above scenarios and baud rates, this solves the issue but is unexpected and should not be requirement?

Having the FIO disabled can be desirable or essential for certain use cases and there is nothing in the documentation that mentions any limits on the supported baud rates with the FIFO disabled?

Issue 2 Scope traces:

Here is a scope trace for Issue 2 at 460800 baud:
The yellow trace is the Sender's TX line, Purple is the sender's RX line, Blue is a debug low pulse from the sender triggered for the duration of the on_uart_rx() IRQ.
460800_baud_missing_irq
As can be seen, on the right hand side there is missing blue pulse indicating a missing IRQ.

Another trace for Issue 2:
460800_baud_missing_irq_2
As can be seen, near the start one of the blue pulses is shifted to the right and about 2/3 of the way along, there is a missing pulse.

Trace for Issue 2 with FIFO enabled:
It can be seen here that then IRQ is firing every 4 bytes instead of after every bye in the above traces, suggesting that 4 bytes is either the FIFO size or maybe just how full it is before the IRQ fires.

921600 baud FIFO enabled
I don't know why the first IRQ takes much longer than the rest, the only parts of the code which could cause this are
uart_is_readable(UART_ID) or uart_getc(UART_ID)
this also happens with the FIFO disabled on some occasions I have seen.

Issue 1 Scope traces:

The yellow trace is the Receiver's RX line, Purple is the Receiver's TX line, Blue is a debug low pulse from the Receiver triggered for the duration of the on_uart_rx() IRQ.
The trace starts from shortly before the debug pins are configured during startup and before the UART is configured. The phantom IRQ can be seen here just after 4ms from DEBUG_PIN2 being configured as output High during startup.
phantom start byte 2
It can be seen that there is no data on the RX or TX lines and the IRQ was still fired, its also strange that it is fired around 3.6ms after UART0 is configured

Further Notes:
If I disconnect the Receiver's RX line the issue still occurs.
If I tie the RX line to ground via a 10k resistor the issue still occurs, However if I tie the RX line to 3.3v via the 10k resistor the issue goes away, I don't see the phantom IRQ.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions