LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

PSA: Using VISA with SILabs CP2102 USB to Serial devices has some non-obvious timing issues

Solved!
Go to solution

This is one of those things that I "knew" in the back of my head, but bonked into it yesterday in an edge case that caused me to lose a few hours.

 

TL;DR: When writing data using VISA Write to an SI Labs CP2102 chip, you must wait until the data is physically transmitted before using VISA Close.

 

Long version: Normally one uses a termchar to end a write, but some protocols do not use a termchar or flow control. I was writing to an instrument that used a binary protocol, and the write was about 4500 bytes long. The device does not provide a response to this command (I have no control over that).

 

So, my code was very simple: VISA Configure (no termchar, baud rate, etc), VISA Write, VISA Close. When I tested this, the device reported only receiving ~4000 bytes, and the number would vary a bit run to run. This was consistent across multiple computers and multiple USB to Serial devices. Switching to an FTDI chip would solve the problem. VISA Write was set to Synchronous mode. "Return count" showed that I'd written the right amount of data with VISA Write. Even a software-level serial port snooper showed I was writing all of my data- it's just that a hardware-level snooper showed I was not, in fact, writing all of my data.

 

The fix ended up being to simply add a Wait between VISA Write and VISA Close. It's common knowledge that the VISA Write function returns when it transfers data to the driver, not to the hardware. The driver itself decides when to actually write the data out to the physical device. (More reading: https://www.ni.com/en/support/documentation/supplemental/18/choosing-between-synchronous-and-asynchr...)

 

The thing that got me here was that in 99.9% of cases, I do a write, then a read. In this case, there was nothing to read, so I just closed the reference to the port since I was done with it.

 

Apparently, when you call VISA Close with the SI Labs driver, it will stop any transfer in-progress wherever it happens to be in the write. AFAIK there is no way to query the driver for how many bytes have actually been written on a physical level. Thus, anytime you do a Write with a CP210x chip, you need to have something happen before closing. A Read will do it, or you can use a Stall Data Flow or something to give it a little delay there.

 

I tried it with (I think it was) an FTDI based chip and did not see this behavior- all of the data was physically written, even when calling VISA Close early. I didn't test the limits to see if I put, say, 45,000 bytes on the port then immediately closed it if it would abort the write as well.

Message 1 of 10
(1,696 Views)
Solution
Accepted by topic author BertMcMahan

Replying to mark as "Solved" for future Googler's with a similar issue.

0 Kudos
Message 2 of 10
(1,693 Views)

Have you tried flushing I/O buffer with mask 0x20 (discard contents of the transmit buffer by writing all the buffered data to the device)?

Lucian
CLA
0 Kudos
Message 3 of 10
(1,632 Views)

I didn't try messing with Flush Buffers since I can tell the data was written to the driver already, as I could see it being written in my software-level port sniffer. I could also see the data had begun coming out of the port itself using my hardware-level sniffer, so I know the data had been written to the driver. In other words, it was already out of the VISA buffer.

0 Kudos
Message 4 of 10
(1,578 Views)

It may even have been (partially) out of the OS driver. Those chips all have a hardware FIFO buffer for both directions. Although at least the FTDI ones don’t use several kB large FIFOs.

Rolf Kalbermatter
My Blog
0 Kudos
Message 5 of 10
(1,490 Views)

@BertMcMahan wrote:

TL;DR: When writing data using VISA Write to an SI Labs CP2102 chip, you must wait until the data is physically transmitted before using VISA Close.


I have ran into this with other serial ports as well, including some built into the mother board.  I have no clue what the manufacturers were as I didn't really care at the time.  It is just a generally good idea to let the data get out before closing your port.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
0 Kudos
Message 6 of 10
(1,385 Views)

@crossrulz wrote:

@BertMcMahan wrote:

TL;DR: When writing data using VISA Write to an SI Labs CP2102 chip, you must wait until the data is physically transmitted before using VISA Close.


I have ran into this with other serial ports as well, including some built into the mother board.  I have no clue what the manufacturers were as I didn't really care at the time.  It is just a generally good idea to let the data get out before closing your port.


Certainly true. I just wish there was a way to know it was actually, physically sent out other than just waiting a little bit.

0 Kudos
Message 7 of 10
(1,252 Views)

Aside that RS-232 doesn’t really have any such signaling (aside from relying on a response to a command), hoping to get this (unreliable) information from the device driver through at least 4 driver layers is hopeless.

So your most promising approach is probably to do a status query of the device itself with a reasonable timeout before close (even as part of your close function). Not perfect but the most reliable option.

Rolf Kalbermatter
My Blog
0 Kudos
Message 8 of 10
(1,245 Views)

Yeah I know there's no signaling, I'm just wishing 🙂 I do wonder if there might be a way to handle it with manufacturer-specific DLL calls rather than using normal abstraction layers but that's way more trouble than it's worth.

 

Normally I do wait for a response... but this one particular device, with this one particular command, doesn't provide a response. The short version is that it's a final "reset" command after a series of configuration commands (which do provide replies), but this one doesn't. Apparently it triggers the reboot nearly instantly and doesn't have time to send the reply (or so I'm told...) That's why I ran into this issue for the first time in about a decade of dealing with serial devices. I'd simply never done a configure/write/close before. I'd initially assumed that, once transferred to the driver, that it would actually send out the data written to it, but I can understand the argument for the "abort all actions once the handle is released". The fact that it seems manufacturer specific is a little annoying though (FTDI didn't seem to do this but I didn't test super thoroughly).

0 Kudos
Message 9 of 10
(1,233 Views)

It may be simply a question of FIFO size. The FTDI232H has an internal FIFO buffer of 1kB per direction. The CP2102 has 640 bytes. Not a huge difference but still. Together with some different strategy in the low level USB device driver, this may make all the difference.

 

Also the FTDI232H supports High-Speed (480Mb/s) data transfer if the USB port can handle that (all USB ports in a PC nowadays are at least High-Speed). The CP2102 only supports Full-Speed (12Mb/s). So the FTDI driver certainly could push a few kB much much faster into the device buffer than the CP2102 driver could and that might be all the difference there is. Once the data is in the chip FIFO, the only way to prevent it to be sent out would be actually a reset.

Rolf Kalbermatter
My Blog
Message 10 of 10
(1,199 Views)