1
Discussion - Software / Re: VNC2: UART to FT232 bridge at 230400 baud no flow control
« on: June 23, 2022, 11:21:24 AM »
Dear Community,
much too many hours later I resolved the issus. As written above I had an existing hardware design and no control of the USB peer device. I've learned a whole lot and will share some experience hoping it helps to learn faster than I did. Experts, you're welcome to correct my statements.
My system:
- The VNC2 is a data relay inbetween a USB peer device and an embedded system connected via UART.
- The communication follows a strict request/response pattern, where the embedded system is the master.
- USB peer is preconfigured with 230400 baud, 8N1, no flow control. Data packets are up to 4k byte (upstream).
- UART peer now is configured with 500k baud, 8N1, flow control in the logic layer; explanation below (downstream).
In bullets:
- 230400 baud is possible under very special circumstances.
- The whole FW for the VNC2 is more complex than it appears. Devil is in the detail.
- I checked 11 examples. I was able to learn from them, but they are not 'industry ready' code. Happy path worked most of the time. But edge cases usually were not considered.
- There is a patch "Vinculum II Installer V2.0.2-SP3.exe" that fixes some parts in the UART lib. BUT! You need to request it via email from the support -> thanks for the quick replies.
- The main problem I experienced is in the USB part of the chip. FT232 splits a continuous UART data stream in chucks of 62 bytes and obviously the RTOS then takes care of other stuff in between. These "pauses" in the data stream cause a buffer overflow at same input/output baud rates. See the attached scope plot, where red is the incoming data stream (continuous) and blue is the outgoing data stream (split).
- As said, the output data stream is split into chunks of 62 bytes. If, at the end, the last chuck is not 62 bytes, there is a delay from 10msec to 80msec!!! before the VNC2 sends it. See the scope plot with the blue peak at the end. I've sent 63 bytes. I read about a config paramter for that timeout, but was not able to apply it.
- Hardware flow control is not possible by design. I tried SW flow control between the VNC2 and the embedded system. I did not work. I was not able to identify the reason.
The solution:
- Part one of the solution was to increase the UART baud rate from VNC2 to the embedded system to 500k baud to compensate for the pauses in the upstream.
- Part two of the solution was to slow down the downstream from the embedded system to the USB peer on the logic layer. I.e. I split the downstream into chunks of 62 bytes and allow a pause of 1.3msec between (heuristic value).
- Part three of the solution was a carefully balanced timing in the VNC2 firmware.
- I have three threads: downstream, upstream, and connection events. All threads have the same priority. Otherwise the thread with less priority is never executed.
- The downstream sleeps for one msec when no data is avialable. Othewise the scheduler would jump back and forth every time and the pauses in the upstream are too long.
- The upstream does never sleep. This reduces the 'effective" downstream, but I compensate that with the delays in the logic layer of the embedded system.
I would love to learn that there is this magic configuration that resolves my problems, and all the custom design patterns applied here are not necessary.
FTDI: please, please, please, put the code of your examples to github! Then, we - the community - can help fix, improve, extend, collaborate.
much too many hours later I resolved the issus. As written above I had an existing hardware design and no control of the USB peer device. I've learned a whole lot and will share some experience hoping it helps to learn faster than I did. Experts, you're welcome to correct my statements.
My system:
- The VNC2 is a data relay inbetween a USB peer device and an embedded system connected via UART.
- The communication follows a strict request/response pattern, where the embedded system is the master.
- USB peer is preconfigured with 230400 baud, 8N1, no flow control. Data packets are up to 4k byte (upstream).
- UART peer now is configured with 500k baud, 8N1, flow control in the logic layer; explanation below (downstream).
In bullets:
- 230400 baud is possible under very special circumstances.
- The whole FW for the VNC2 is more complex than it appears. Devil is in the detail.
- I checked 11 examples. I was able to learn from them, but they are not 'industry ready' code. Happy path worked most of the time. But edge cases usually were not considered.
- There is a patch "Vinculum II Installer V2.0.2-SP3.exe" that fixes some parts in the UART lib. BUT! You need to request it via email from the support -> thanks for the quick replies.
- The main problem I experienced is in the USB part of the chip. FT232 splits a continuous UART data stream in chucks of 62 bytes and obviously the RTOS then takes care of other stuff in between. These "pauses" in the data stream cause a buffer overflow at same input/output baud rates. See the attached scope plot, where red is the incoming data stream (continuous) and blue is the outgoing data stream (split).
- As said, the output data stream is split into chunks of 62 bytes. If, at the end, the last chuck is not 62 bytes, there is a delay from 10msec to 80msec!!! before the VNC2 sends it. See the scope plot with the blue peak at the end. I've sent 63 bytes. I read about a config paramter for that timeout, but was not able to apply it.
- Hardware flow control is not possible by design. I tried SW flow control between the VNC2 and the embedded system. I did not work. I was not able to identify the reason.
The solution:
- Part one of the solution was to increase the UART baud rate from VNC2 to the embedded system to 500k baud to compensate for the pauses in the upstream.
- Part two of the solution was to slow down the downstream from the embedded system to the USB peer on the logic layer. I.e. I split the downstream into chunks of 62 bytes and allow a pause of 1.3msec between (heuristic value).
- Part three of the solution was a carefully balanced timing in the VNC2 firmware.
- I have three threads: downstream, upstream, and connection events. All threads have the same priority. Otherwise the thread with less priority is never executed.
- The downstream sleeps for one msec when no data is avialable. Othewise the scheduler would jump back and forth every time and the pauses in the upstream are too long.
- The upstream does never sleep. This reduces the 'effective" downstream, but I compensate that with the delays in the logic layer of the embedded system.
I would love to learn that there is this magic configuration that resolves my problems, and all the custom design patterns applied here are not necessary.
FTDI: please, please, please, put the code of your examples to github! Then, we - the community - can help fix, improve, extend, collaborate.