4
votes

I'm working on a Communications Device Class (CDC) driver for an embedded device, a Full Speed implementation of USB 2.0. The COM port settings are 115200, 8-bit, no parity, 1 stop bit, no flow control. Our PC application (32-bit, Windows 7, .NET 2.0) communicates with the target device through a virtual COM port, which on the target device can connect to either a FTDI (USB-to-SCI bridge) chip or the integrated USB peripheral in the microcontroller, depending on which port is selected by the application.

Both virtual COM ports work without any problems using Realterm. However, while our desktop application works using the virtual COM port connected via the FTDI chip, it hangs when attempting to use the virtual COM connected via the microcontroller's integrated USB peripheral.

When connected via the virtual COM port using the integrated USB, the application consistently hangs on the second call to SerialPort.Write(...). Using Serial Monitor from HHD Software I can see that the data is transmitted on the first call to SerialPort.Write(...). However, that data is never received by the target device.

It's odd because the only time I have seen similar problems on previous projects was when the flow control settings on each side of the bus were mismatched.

Additional info...


Here is the data captured from various port monitoring tools while running our PC application connected to the target device via its integrated USB peripheral. Any insight would be appreciated.

For those that are interested, I am using CodeWarrior 10.2 with the MCF51JM128 from Freescale.


Any ideas or suggestions would be appreciated. Thanks.

1
Do you tried to track the actions of Realterm? There must be differences which should show the solution.jeb
@jeb How would I do that? Is it one of Realterm's features? I'll admit that I'm familiar with only a small subset of its capabilities.Jim Fell
No, but tools like portmon from sysinternals/microsoft can show all actions of a port, open/close and also read/write and that for an other program like Realterms and your ownjeb
What uC is this? Meaning the one in "integrated USB peripheral in the microcontroller". Most Virtual COM stuff I have seen seemed not very suited/optimized. I suspect the uC is at fault here. You have to remember, you are adding a lot of overhead handing it off to the uC.leppie
I worked on a very similar product with a COM port / USB cable using the FTDI chipset... not sure if I can suggest anything you haven't already tried, but two quick (probably dumb) questions: have you tried setting the WriteTimeout to some big number (e.g., 60 seconds)? Also, are you trying to close/reopen the COM port between writes? The latter is something I found works extremely poorly (because of the asynchronous nature of the request to close the port and its actual closing).Gojira

1 Answers

3
votes

It is clear from the logs that you are making the classic mistake of not taking care of the hardware handshaking signals. That only ever works by accident, a terminal emulator like Realterm will never make that mistake.

You must set the DtrEnable property to true. That turns on the Data Terminal Ready signal. It is important because RS-232 is an unterminated bus so is subject to electrical noise when the cable is disconnected or the power turned off. DTR convinces the device that it is in fact connected to a powered device. This is emulated of course in your case but the driver or firmware will still typically implement the RS-232 behavior.

And the RtsEnable property is important, used to handshake with the device and prevent the receive buffer from overflowing when the app isn't emptying the buffer in a timely matter. You really should set the Handshake property to Handshake.RequestToSend, the most common way a device implements it. Which then also takes care of turning RTS on. If you have to use Handshake.None for some reason then you have to turn it on yourself by setting RtsEnable to true.

This ought to take of the problem. If you still have trouble then use PortMon to spy on the way Realterm initializes the driver. Compare the commands you see against the commands that the SerialPort class sends. Make sure they are the same. In value, not in sequence.