de-vri-es / serial2-rs

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

How to get a new instance of the Settings struct? #9

Closed kinire98 closed 1 year ago

kinire98 commented 1 year ago

I'm trying to open a port with Settings but there isn't seem to be any static method of the struch which returns the struct itself. Am I missing something or is there a way to initialize it?

kinire98 commented 1 year ago

I can make a simple PR with the changes...

kinire98 commented 1 year ago

Ok, nvm. This happens for not reading the docs enough. jeje. The answer is to open the port with:

let port = SerialPort::open("COM1", 9600);

and then get the configuration with:

let settings = port.get_configuration();

Leaving this here if it helps someone. Sorry for bothering

de-vri-es commented 1 year ago

Yeah, to clarify why there is no Settings::new(): you should always preserve settings you don't care/know about. So instead of mmaking a "clean" settings struct and applying it, you always have to get one from the device, modify it, and set it again.

brainstorm commented 1 year ago

I also found this builder very confusing... in fact I'm still a bit confused on how to i.e set the flow control back to the port when the result type is unit ()?:

Screenshot 2023-08-03 at 9 34 41 pm

Can you provide some illustrative examples on how you are using it, @de-vri-es? Right now I'm observing on my oscilloscope that some packets are not being sent out to my (cheap, most probably counterfeit) FTDI clone and I'd like to pin down what is it through tweaking settings (and in the future set/unset RTS at will, if possible).... but I find this non-new() builder pattern a bit unfamiliar TBH :_S

de-vri-es commented 1 year ago

settings.set_flow_control(...) simply modifies the existing settings object.

let mut port = SerialPort::open("/dev/ttyUSB0", 115200)?;
let mut settings = port.get_configuration();
settings.set_flow_control(serial2::FlowControl::RtsCts)?;
port.set_configuration(&settings)?;
brainstorm commented 1 year ago

Thanks! I changed it as advised (don't know why I got stuck on that simple issue, doh):

    dbg!("Serial port setup...");
    // Serial port
    let mut port = SerialPort::open(PORT, BAUD)?;
    let mut settings = port.get_configuration()?;

    settings.set_flow_control(serial2::FlowControl::RtsCts);
    port.set_configuration(&settings)?;

But now I'm getting the following error:

[src/main.rs:53] "Serial port setup..." = "Serial port setup..."
Error: Custom { kind: Other, error: "failed to apply some or all settings" }

I will now check the serial2 code and see what's the underlying issue, perhaps the dongle's (OSX) driver not allowing that?. That setting/change works fine in CoolTerm.

brainstorm commented 1 year ago

Interesting:

    dbg!("Serial port setup...");
    // Serial port
    let mut port = SerialPort::open(PORT, BAUD)?;
    let mut settings = port.get_configuration()?;
    dbg!(&settings);
    settings.set_flow_control(serial2::FlowControl::RtsCts);
    dbg!(&settings);
    port.set_configuration(&settings)?;

Yields the following, which applies the other available flow control setting instead of the one I specified in my code 🤔 :

[src/main.rs:53] "Serial port setup..." = "Serial port setup..."
[src/main.rs:57] &settings = Settings {
    baud_rate: Ok(
        9600,
    ),
    char_size: Ok(
        Bits8,
    ),
    stop_bits: Ok(
        One,
    ),
    parity: Ok(
        None,
    ),
    flow_control: Ok(
        None,
    ),
}
[src/main.rs:59] &settings = Settings {
    baud_rate: Ok(
        9600,
    ),
    char_size: Ok(
        Bits8,
    ),
    stop_bits: Ok(
        One,
    ),
    parity: Ok(
        None,
    ),
    flow_control: Ok(
        XonXoff,
    ),
}
Error: Custom { kind: Other, error: "failed to apply some or all settings" }

... and funnily the reverse happens as well:

    let mut settings = port.get_configuration()?;
    dbg!(&settings);
    settings.set_flow_control(serial2::FlowControl::XonXoff);
    dbg!(&settings);

Yields:

[src/main.rs:53] "Serial port setup..." = "Serial port setup..."
[src/main.rs:57] &settings = Settings {
    baud_rate: Ok(
        9600,
    ),
    char_size: Ok(
        Bits8,
    ),
    stop_bits: Ok(
        One,
    ),
    parity: Ok(
        None,
    ),
    flow_control: Ok(
        None,
    ),
}
[src/main.rs:59] &settings = Settings {
    baud_rate: Ok(
        9600,
    ),
    char_size: Ok(
        Bits8,
    ),
    stop_bits: Ok(
        One,
    ),
    parity: Ok(
        None,
    ),
    flow_control: Ok(
        RtsCts,
    ),
}
Error: Custom { kind: Other, error: "failed to apply some or all settings" }

Perhaps due to some flipped values on a flowcontrol enum?

de-vri-es commented 1 year ago

Yeah, not all devices support flow control. It's probably a limitation of the device.

brainstorm commented 1 year ago

Ok, interesting, I'd expect the altered settings to be None on that field instead of another (opposite?) value :-S

Is there a way to list the capabilities of a device? Where are those settings really stored?

de-vri-es commented 1 year ago

Yields the following, which applies the other available flow control setting instead of the one I specified in my code thinking :

Ah, this is certainly a bug, although I thought I fixed that recently.

I'm not aware of any way to list device capabilities. But in order to see if the settings are accepted by the device you have to call set_configuration(), and if you want to be sure what is set afterwards you have to call get_configuration() again.

de-vri-es commented 1 year ago

Ah, this is certainly a bug, although I thought I fixed that recently.

Released version 0.2.2 with a fix for this. Thanks for reporting it!