mik3y / usb-serial-for-android

Android USB host serial driver library for CDC, FTDI, Arduino and other devices.
MIT License
4.95k stars 1.6k forks source link

Missing/Corrupt data with high baud rates. #599

Open GeorgePapageorgakis opened 1 month ago

GeorgePapageorgakis commented 1 month ago

Hello,

I have a serial device that sends data with the following configuration using an FTDI FT230XQ-R chip:

baud rate = 921600
databits = 8
stopbit = 1
parity = none
dtr = true
rts = true
Flow control = false

The device functions correctly on other serial interfaces with identical configurations, indicating the data is transmitted accurately. However, when connected to Android devices, we observe corrupted data particularly at the higher baud rate of 921600. At this rate, the last 62 bytes of each data chunk consistently register as zeros. Lowering the baud rate to 112500 decreases the frequency of these errors, though they still persist on occasion.

This problem has also been replicated in the Simple USB Terminal and Serial USB Terminal apps on Android. Unfortunately, enabling flow control is not feasible due to our current firmware constraints.

Could the USB converter, specifically the TpLink USB-C to USB 3.0 adapter UC400(UN) 1.0, be contributing to this issue? We would greatly appreciate any insights or suggestions you might have to help resolve this data corruption.

Could this be the solution? https://github.com/mik3y/usb-serial-for-android/wiki/FAQ#when-reading-a-message-why-dont-all-bytes-arrive-at-the-same-time

So for 512 bytes a 1-10ms pause could work? The size of the whole packet could reach up to 1-2MB.

Thank you for your assistance.

GeorgePapageorgakis commented 1 month ago

Just tested by adding 1 to 10ms every 1KB. The problem persists, still getting the last 62 bytes as zeros of every chunk. For example, with default 4096 as buffer in SerialInputOutputManager data is split in chunks, say: 3968 bytes x8 chunks and in every chunk the last 62 bytes are zeroes.

Thus, the larger and more chunked the initial packet the more corrupt the data.

kai-morich commented 1 month ago

you could try to tweak thread priority as mentioned here but preventing data loss is hardly possible without flow control.

Each FTDI request begins with a 2 byte header so it only has 62 byte of actual content. If the 62 bytes are fully used is up to the FTDI device.

You might try FT2232 or FT4232 as these have larger buffers.

GeorgePapageorgakis commented 1 month ago

@kai-morich Ok so Flow Control is mandatory for these high baud rates.

A workaround that seems to work is to send chunks of max size with a pause. Now it seems to work with 1KB-3KB chunk and 50ms delay. However, this is also non deterministic approach. It improved reliability but now if we have larger packets, say 100-150KB data, only 64KB seem to pass through, rest are lost/corrupted. Needs more testing/debugging to understand what is going on now.

chaniotisalex commented 1 month ago

Thanks @GeorgePapageorgakis . Chunking solved the issue in my case too.

GeorgePapageorgakis commented 1 month ago

I would recommend to add an additional overloaded constructor in UsbInputOutputManager with buffer size parameter. The default of 4KB seems problematic and increasing it to 16KB or more, improved the performance and chunking issues.

kai-morich commented 1 month ago

you can already configure the buffer sizes with setReadBufferSize and setWriteBufferSize in SerialInputOutputManager class