Skip to content

Add posibility to enable rs485 functionality for port under Linux #226

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
slyshykO opened this issue Oct 31, 2024 · 2 comments
Open

Add posibility to enable rs485 functionality for port under Linux #226

slyshykO opened this issue Oct 31, 2024 · 2 comments

Comments

@slyshykO
Copy link

There is rs485 that provides this functionality.
But it has not been updated for 7 years.
And it is convenient to have such functionality right in place.

@sirhcel
Copy link
Contributor

sirhcel commented Nov 24, 2024

Thank you for this suggestion! Yes, it would be convenient to support this functionality directly from the serialport crate.

My gut instinct tells me that verifying this functionality will become the hardest part. Do you know of some commodity hardware which we could use for testing? Especially the more exotic stuff like activating a termination resistor?

@olback
Copy link

olback commented Feb 11, 2025

Thank you for this suggestion! Yes, it would be convenient to support this functionality directly from the serialport crate.

My gut instinct tells me that verifying this functionality will become the hardest part. Do you know of some commodity hardware which we could use for testing? Especially the more exotic stuff like activating a termination resistor?

We're using Moxa devices in a lot of our products, specifically, the UPort 1450I, and they work great. They have DIP-switches internally to control the termination resistors. Everything in this reply below will be about said device, for context.

Image
(Moxa UPort Manual)

Here's what I'm currently working with:

$ lsusb
[..]
Bus 001 Device 005: ID 110a:1450 Moxa Technologies Co., Ltd. UPort 1450 4-Port RS-232/422/485
[..]

I first tried to use the rs485-crate like OP mentioned, but the mxuport-driver does not support that IOCTL call. Instead, you change the port value in the serial_port struct.

// See `serial_struct` in the Linux kernel source: https://github.com/torvalds/linux/blob/master/include/uapi/linux/serial.h
#[repr(C)]
#[derive(Debug, Clone)]
struct LinuxSerialStruct { .. }

let mut sp = serialport::new(port, baud)
    .open_native()
    .expect("Failed to open serial port");

// Read the serial struct
let mut ss_old = LinuxSerialStruct::default();
if unsafe { libc::ioctl(sp.as_raw_fd(), libc::TIOCGSERIAL, &mut ss_old) } < 0 {
    eprintln!("Failed to GET serial struct");
    return;
}
println!("Old serial struct: {:#?}", ss_old);

// Set the serial struct with modified port
let mut ss_new = ss_old.clone();
// RS232 = 0, RS485 2W = 1, RS422 = 2, RS485 4W = 3 as per the MOXA UPort Manual
ss_new.port = 1; // RS485 2W

if unsafe { libc::ioctl(sp.as_raw_fd(), libc::TIOCSSERIAL, &mut ss_new) } < 0 {
    eprintln!("Failed to SET serial struct");
    return;
}

let dyn_sp = &mut sp as &mut dyn serialport::SerialPort;

// Use dyn_sp like normal, but make sure to not TX/RX at the same time!

All this to say that all serial port devices are unique in handling configuration. Moxa uses TIOCSSERIAL and the rs485-crate uses TIOCSRS485.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants