Max-i uses "Break" to separate the various telegrams and uses automatic flow control as these solutions by far are the most efficient ways for synchronous binary communication where all byte values from 0 to 255 may be used. Unfortunately, such "modern" ways are not supported in the PC world where the serial port implementation is still "stone age" - both regarding hardware and software.
First of all, the transmitter FIFO in the standard UART 16550 of the PC world has always been full of errors and flaws. In the first version, the FIFO didn't work at all although the circuit was brought to market! In the next version (16550AFN), the FIFO almost worked, but a byte written while the last byte was transmitted, was not always recognized so that you could loose bytes. In the following versions, this bug was fixed, but the designers still did not realize that a transmitter FIFO without automatic flow control is useless in practice, and unfortunately, all later copies of 16550 in various chip sets are just copies of this buggy design. Only Texas Instruments has added the last AND-gate necessary to make the transmitter FIFO useful.
The receiver FIFO in 16550 is more clever as it is 11 bit wide to enable 100% synchronization between the received bytes and the three error and status flags - Break, Framing Error and Parity error, but with a little help from Microsoft that feature is efficiently destroyed! Microsoft takes 11 bits from the FIFO, use the three status bits to fire some events, which may be executed more task switchings later, and then throws the bits away, before the result is stored in a 16-bit stream, which could easily have contained all 11 bits. This makes it impossible to use any of the modern communication methods like 9th bit communication and telegram separation by means of Break because the vital synchronization between bytes and flags are lost and cannot be regained. This also means that in case of an error, all received bytes in the receiver FIFO and any following buffers must be thrown away because it is impossible to tell to which telegram an error belongs!
To make it complete, Microsoft does not fire an event when the transmitter serial register becomes empty so that it is virtually impossible to
control the modem control signals without listening for ones own communication, and they pass all modem signal commands through at least one level
of task switching so that it for example is impossible to generate Break conditions below 11-16 mS depending on whether the PC has a single core or
Today, it is very common to use USB-serial converters, but some precautions are necessary depending on the manufacturer:
Devices from Future Technology Devices International Ltd. (FTDI) like the FT232(x) series:
Devices from EXAR like the XR21V141x, XR21B1411 USB-UART family:
The EXAR family has a 384 x 11-bit receiver FIFO and a 128 x 9-bit transmitter FIFO. They also have a Wide-mode i hardware. In this mode, the devices transfer two bytes for every byte received - one with data and one with status. In this way, it is possible to work around the Microsoft limitation and use advanced communication methods. The devices are also able to force a USB transfer if a period corresponding to 3 bytes has elapsed without any reception, and it can generate a timed (in mS) Break so everything seems perfect - except for the driver!
It is easy to utilize the advanced Exar features by means of native C++ programming, but nowadays most Windows programmers use .Net and managed
code and "of course" there is no direct way to communicate with the driver that way. SerialPort of .Net has no method to return the handle
of an opened port and many types are private. The only way is by means of a reflection hack, which gets the handle from the generated code. By means of
this handle and a little unmanaged code it is then possible to put the EXAR circuits in wide mode and utilize the timed Break generation. It is not very
pretty, but it works.
Solution and Test program
There are at least two good solutions:
Our test program is written in Microsoft VB.NET for framework 2.0, which is the only .Net version, where you can live with the bugs. It throws an unhanded exception if you remove the USB plug, but othervise it works. All newer versions up to at least 3.5 SP1 are completely useless! You can download the entier source code or just the executeable (EXE). The test program will be updated from time to time as new features are added.
The test program is default in UART mode for use with everything else than an Exar USB-UART. In this mode, a transfer is triggered when the Break event fires. Because Microsoft don't preserve the synchronization between data and flags, our test program cannot always recognize telegram boundaries in this mode. At low telegram rates it works very well, but at higher rates, it is not able to separate the various telegrams. Note that if you try to use the program in this mode together with an Exar USB-UART, you will not receive anything as the Exar circuits do not fire the PinChanged event when a Break occurs.
If you have an Exar USB-UART, you can put the program in EXAR mode (remember to choose the right type). In this mode, the Wide-mode is utilized and all telegrams are separated correct - at least for XR21B1411. For the moment, the program is not tested for XR21V141x, which uses different register addresses than XR21B1411.
Note that when you start the test program, you must select the UART type at first, then select the port and then usually CTS handshake except for a few 16C950 UART drivers, where the handshake must be set to None in the program and to CTS handshake in the driver by means of Windows device manager (program setting not transferred to driver).
This page is updated July 24th 2013