de-vri-es / serial2-rs

Cross platform serial ports for Rust
Other
48 stars 11 forks source link

Windows USB VCOM port problem. #14

Closed perlindgren closed 10 months ago

perlindgren commented 1 year ago

Hi Folks

My setup is as follows.

Win10 as host system. ATSAME70Q21 Xplained Ultra as target system.

Using a terminal program like CoolTerm, I can send and recieve data between the systems over usb-serial (it appears as COM3 on Win10).

Trying to send/receive data using Serial2 does not work, it seems that outgoing data is not flushed properly.

    let r = port.write_all(out_buf);
    println!("{:?}", r);
    let r = port.flush();
    println!("{:?}", r);

There is no errors, but nothing happens on the target side (no data).

The Rust application waits in an infinite loop just to prevent that the link from being torn down. But even after long while nothing happens.

If I quit the Rust application, and then connects to COM3, the first thing that happens is that the written buffer is flushed (so at that point the target receives the data written earlier by the Rust application).

So the CoolTerm program seems to trigger a lower-level flush.

I tried setting the write timout

port.set_write_timeout(Duration::from_millis(10));

No errors but no change of behaviour.

The same code (even without the flushing, set_timeout etc.) works like a charm under Linux, so this is something related the Windows handling of com ports).

I haven't been fiddling with the flow control, am I right in understanding that all types of flow control is disabled by default by Serial2?

As a reference, these are the settings that CoolTerm uses:

image

Any tips what to try?


I haven't tested with FTDI devices, just the VCOM port provided by the Xplained Ultra dev kit.

de-vri-es commented 1 year ago

Hey! It could be the state of the DTR and/or RTS lines. Could you try setting those high after opening the device?

let port = SerialPort::open("COM3", 9600)?;
port.set_dtr(true)?;
port.set_rts(true)?;
perlindgren commented 1 year ago

Just tested setting the dtr/rts, as suggested, and now the data transfer is not stalled.

I needed to add some time-out values, to get the application working. (That was not needed under Linux.) So it could be that under the hood Linux/Windows has a slightly different behavior per default.

I don't know the exact defaults under Linux (regarding dts/rts/timeouts), but if there is such a default, maybe these should be applied by Serial2 on SerialPort::open, to make application more portable.

What do you (de-vri-es, and others) think?

de-vri-es commented 1 year ago

I think that might be wise. Although I'm a bit hesitant to set DTS and RTS high by default. People sometimes use them as GPIO, and then who knows what will happen when they go high. So I want to allow full flexibility to the user for those signals.

Setting a default timeout could be good. Which timeouts did you have to use?

de-vri-es commented 12 months ago

There are now consistent default timeouts on Windows and Unix of 3 seconds by default.

de-vri-es commented 10 months ago

Considering this completed for now. Please comment if you think I missed something and I will re-open the issue.

Thanks for reporting your experience!