ethercat_controller/
ethercat_patch.rs

1// function not available in the ethercat-rs crate
2
3use ethercat::{Master, SlavePos, SmInfo};
4use std::io;
5
6use std::os::fd::AsRawFd;
7use std::{convert::TryFrom, ffi::CStr, fs::OpenOptions};
8
9use ethercat_sys as ec;
10
11/// ioctl macro to call the ioctl function
12///
13/// Copied from the ethercat-rs crate
14macro_rules! ioctl {
15    ($m:expr, $f:expr) => { ioctl!($m, $f,) };
16    ($m:expr, $f:expr, $($arg:tt)*) => {{
17        let file = OpenOptions::new()
18            .read(true)
19            .write(false)
20            .open(&"/dev/EtherCAT0")?;
21        let res = unsafe { $f(file.as_raw_fd(), $($arg)*) };
22        if res < 0 { Err(ethercat::Error::Io(io::Error::last_os_error())) } else { Ok(res) }
23    }}
24}
25
26/// Function that configures the sync manager of the master
27/// It is missing from the ethercat-rs crate
28///
29/// # Arguments
30///
31/// * `master` - A mutable reference to the master
32/// * `slave_pos` - The slave position
33/// * `sm` - The sync manager information
34///
35/// # Returns
36///
37/// * `Result<(), ethercat::Error>` - The result of the operation
38///
39pub fn master_configure_sync(
40    master: &mut Master,
41    slave_pos: SlavePos,
42    sm: SmInfo,
43) -> Result<(), ethercat::Error> {
44    let mut sync = ec::ec_ioctl_slave_sync_t::default();
45    sync.slave_position = u16::from(slave_pos);
46    sync.sync_index = u8::from(sm.idx) as u32;
47    sync.physical_start_address = sm.start_addr;
48    sync.control_register = sm.control_register;
49    sync.enable = if sm.enable { 1 } else { 0 };
50    sync.pdo_count = sm.pdo_count;
51    sync.default_size = sm.default_size;
52    ioctl!(master, ec::ioctl::SLAVE_SYNC, &mut sync).map(|_| ())
53}