Main Menu
Plant Numbering
Evaluation Board
Test Program
Test Program EXE
VB Source Code

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 multicore CPU.


USB-Serial Converters

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:

  • Although the data sheet claims that the devices support Break detection, this support is so limited that it is useless in practice. The receiver FIFO is only 8 bit wide and every time a special event occurs, this is reported in the first byte of a USB transfer. Unfortunately, "Break" is not an "event character" so in case of more telegrams immediately after each other, it is impossible to separate the various telegrams and even if it were, the short telegrams of Max-i would course so many USB transfers that the maximum speed would be rather limited.

  • When used together with SerialPort of Microsoft .Net, more break events are sometimes reported than actually transmitted, and the state of CTS is not reported correct except just after initialization of the driver.

  • Although the data sheet claims that there is automatic flow control, this is only partly true. When CTS goes low, the devices may continue to transmit up to 3 bytes more, which is too much for the Max-i controller to handle. The controller only has a 3-byte FIFO where one byte is the UART shift register. In practice, all telegrams course overflow except for a poll of a value with a short identifier! Note that most microprocessors with build-in UART have an even shorter FIFO than Max-i - usually only a single register, so the FTDI devices are as useless for communication with these kind of devices as they are for communication with Max-i.

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!

  • The driver seems to be a standard Microsoft driver, which does not support any of the advanced settings in the circuits. For example, it is only possible to set the FIFO sizes up to 16 bytes corresponding to a standard 16C550 UART and it is not possible to select the wide mode.

  • The driver does not fire the .Net SerialPort PinChanged event for Break characters, which makes it useless for Max-i unless the circuit is put into Wide mode. The PinChanged event works all right for DSR and CTS.

  • The driver or the circuit generates numerous Break's (00 bytes) when the driver settings such as port name (COMx) or flow control is changed.

  • There is no way to set the properties of the USB part like the number of 64-byte blocks for each transfer (for Max-i, this number should be 1). You can only hope that the default settings are what you want.

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:

  • Use for example a 16C950 UART from PLX Technology (previous Oxford Semiconductor) and write a driver that uses 16-bit buffers and preserves the synchronization between bytes and flags.

  • Use the EXAR XR21V141x or XR21B1411 family of USB-UART's in Wide mode as shown in the test program.

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