├── .gitignore ├── examples ├── info.rs ├── foe-read.rs ├── foe-write.rs ├── sdo.rs ├── list_slaves.rs └── cyclic-data.rs ├── src ├── lib.rs ├── convert.rs ├── types.rs └── master.rs ├── ethercat-sys ├── src │ ├── lib.rs │ ├── ioctls-v1.6.1.rs │ ├── ioctls-v1.5.2-sncn-11.rs │ ├── bindings-v1.5.2-sncn-11.rs │ └── bindings-v1.6.1.rs ├── Cargo.toml └── build.rs ├── LICENSE-MIT ├── .github └── workflows │ └── build.yml ├── Cargo.toml ├── README.md ├── CHANGELOG.md └── LICENSE-APACHE /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk 3 | Cargo.lock 4 | -------------------------------------------------------------------------------- /examples/info.rs: -------------------------------------------------------------------------------- 1 | use ethercat::{Master, MasterAccess}; 2 | 3 | pub fn main() -> Result<(), std::io::Error> { 4 | let master = Master::open(0, MasterAccess::ReadWrite)?; 5 | let info = master.get_info(); 6 | println!("EtherCAT Master: {:#?}", info); 7 | Ok(()) 8 | } 9 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | // Part of ethercat-rs. Copyright 2018-2022 by the authors. 2 | // This work is dual-licensed under Apache 2.0 and MIT terms. 3 | 4 | use ethercat_sys as ec; 5 | 6 | mod convert; 7 | mod master; 8 | mod types; 9 | 10 | pub use self::{ 11 | master::{Domain, Master, MasterAccess, SlaveConfig}, 12 | types::*, 13 | }; 14 | -------------------------------------------------------------------------------- /examples/foe-read.rs: -------------------------------------------------------------------------------- 1 | use ethercat::{Master, MasterAccess}; 2 | 3 | fn main() -> Result<(), std::io::Error> { 4 | let mut master = Master::open(0, MasterAccess::ReadWrite)?; 5 | 6 | let args: Vec = std::env::args().collect(); 7 | if args.len() < 3 { 8 | eprintln!("Usage: foe-read "); 9 | return Err(std::io::Error::new( 10 | std::io::ErrorKind::Other, 11 | "Not enough arguments", 12 | )); 13 | } 14 | let slave_idx: ethercat::SlavePos = args[1] 15 | .parse::() 16 | .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))? 17 | .into(); 18 | let foe_name = &args[2]; 19 | let res = master.foe_read(slave_idx, foe_name)?; 20 | println!("FoE data: {:x?}, {} bytes", res, res.len()); 21 | Ok(()) 22 | } 23 | -------------------------------------------------------------------------------- /examples/foe-write.rs: -------------------------------------------------------------------------------- 1 | use ethercat::{Master, MasterAccess}; 2 | 3 | fn main() -> Result<(), std::io::Error> { 4 | let mut master = Master::open(0, MasterAccess::ReadWrite)?; 5 | 6 | let args: Vec = std::env::args().collect(); 7 | if args.len() < 4 { 8 | eprintln!("Usage: foe-read "); 9 | return Err(std::io::Error::new( 10 | std::io::ErrorKind::Other, 11 | "Not enough arguments", 12 | )); 13 | } 14 | let slave_idx = args[1] 15 | .parse::() 16 | .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))? 17 | .into(); 18 | let foe_name = &args[2]; 19 | let file = &args[3]; 20 | let buf = std::fs::read(file)?; 21 | 22 | master.foe_write(slave_idx, foe_name, &buf)?; 23 | Ok(()) 24 | } 25 | -------------------------------------------------------------------------------- /examples/sdo.rs: -------------------------------------------------------------------------------- 1 | use ethercat::{AlState, Master, MasterAccess, SdoEntryAddr, SdoIdx, SdoPos, SlavePos, SubIdx}; 2 | 3 | pub fn main() -> Result<(), std::io::Error> { 4 | let slave_pos = SlavePos::from(0); 5 | let mut master = Master::open(0, MasterAccess::ReadWrite)?; 6 | master.request_state(slave_pos, AlState::PreOp)?; 7 | #[cfg(feature = "sncn")] 8 | master.dict_upload(slave_pos)?; 9 | let sdo_count = master.get_slave_info(slave_pos)?.sdo_count; 10 | if sdo_count == 0 { 11 | println!("Could not find any SDOs"); 12 | return Ok(()); 13 | } 14 | for i in 0..sdo_count { 15 | let sdo_info = master.get_sdo(slave_pos, SdoPos::from(i))?; 16 | for j in 0..=u8::from(sdo_info.max_sub_idx) { 17 | let addr = SdoEntryAddr::ByIdx(SdoIdx { 18 | idx: sdo_info.idx, 19 | sub_idx: SubIdx::from(j), 20 | }); 21 | let entry = master.get_sdo_entry(slave_pos, addr)?; 22 | println!("0x{:X}/{} = {:#?}", u16::from(sdo_info.idx), j, entry); 23 | } 24 | } 25 | Ok(()) 26 | } 27 | -------------------------------------------------------------------------------- /ethercat-sys/src/lib.rs: -------------------------------------------------------------------------------- 1 | // Part of ethercat-rs. Copyright 2018-2022 by the authors. 2 | // This work is dual-licensed under Apache 2.0 and MIT terms. 3 | 4 | #![allow(non_upper_case_globals)] 5 | #![allow(non_camel_case_types)] 6 | #![allow(non_snake_case)] 7 | #![allow(clippy::useless_transmute)] 8 | 9 | #[cfg(not(feature = "pregenerated-bindings"))] 10 | include!(concat!(env!("OUT_DIR"), "/bindings.rs")); 11 | 12 | #[cfg(all(not(feature = "sncn"), feature = "pregenerated-bindings"))] 13 | include!("bindings-v1.6.1.rs"); 14 | 15 | #[cfg(all(feature = "sncn", feature = "pregenerated-bindings"))] 16 | include!("bindings-v1.5.2-sncn-11.rs"); 17 | 18 | use ioctl_sys::{io, ioc, ioctl, ior, iorw, iow}; 19 | 20 | pub mod ioctl { 21 | use super::EC_IOCTL_TYPE as EC; 22 | use super::*; 23 | 24 | #[cfg(not(feature = "pregenerated-bindings"))] 25 | include!(concat!(env!("OUT_DIR"), "/ioctls.rs")); 26 | 27 | #[cfg(all(not(feature = "sncn"), feature = "pregenerated-bindings"))] 28 | include!("ioctls-v1.6.1.rs"); 29 | 30 | #[cfg(all(feature = "sncn", feature = "pregenerated-bindings"))] 31 | include!("ioctls-v1.5.2-sncn-11.rs"); 32 | } 33 | -------------------------------------------------------------------------------- /ethercat-sys/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "ethercat-sys" 3 | description = "Binding to the Etherlab open-source EtherCAT master" 4 | keywords = ["ethercat", "master", "etherlab", "binding"] 5 | version = "0.3.1" 6 | authors = ["Georg Brandl ", "slowtec GmbH "] 7 | repository = "https://github.com/ethercat-rs/ethercat" 8 | license = "MIT/Apache-2.0" 9 | edition = "2018" 10 | 11 | [dependencies] 12 | ioctl-sys = "0.5.2" 13 | 14 | [build-dependencies] 15 | bindgen = "0.69.0" 16 | regex = "=1.9.6" 17 | # for 1.63 compatibility 18 | home = "=0.5.5" 19 | 20 | [features] 21 | default = [] 22 | 23 | # Enable this feature to use it with the 24 | # synapticon branch `release/v1.5.2-sncn-11` 25 | # at https://github.com/synapticon/Etherlab_EtherCAT_Master 26 | sncn = [] 27 | 28 | # Enable this feature to use pregenerated bindings. 29 | # CAUTION: If your kernel module was not built 30 | # with the corresponding version, it might break your application. 31 | pregenerated-bindings = [] 32 | 33 | [package.metadata.docs.rs] 34 | features = [ "pregenerated-bindings" ] 35 | 36 | [badges] 37 | maintenance = { status = "actively-developed" } 38 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018-2022 The Ethercat-rs Developers 2 | 3 | Permission is hereby granted, free of charge, to any 4 | person obtaining a copy of this software and associated 5 | documentation files (the "Software"), to deal in the 6 | Software without restriction, including without 7 | limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software 10 | is furnished to do so, subject to the following 11 | conditions: 12 | 13 | The above copyright notice and this permission notice 14 | shall be included in all copies or substantial portions 15 | of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /examples/list_slaves.rs: -------------------------------------------------------------------------------- 1 | //! EtherCAT master example: List slaves 2 | //! 3 | //! Opens master 0 (read-only), queries slave info for positions 0..31 and 4 | //! prints discovered slaves. 5 | use ethercat::{Master, SlavePos}; 6 | use std::io; 7 | 8 | pub fn main() -> Result<(), io::Error> { 9 | env_logger::init(); 10 | 11 | // Open /dev/EtherCAT0 (the first EtherCAT master) in read-only mode 12 | // Prerequisites: You must configure the Etherlab EtherCAT master using `/etc/ethercat.conf`, 13 | // and have the master running (e.g. via `sudo systemctl start ethercat`). 14 | let master = Master::open(0, ethercat::MasterAccess::ReadOnly)?; 15 | 16 | log::info!("Master 0 opened. Attempting to list slaves (positions 0..31)..."); 17 | 18 | let mut found = 0u32; 19 | for i in 0u16..=31 { 20 | let pos = SlavePos::from(i); 21 | match master.get_slave_info(pos) { 22 | Ok(info) => { 23 | println!("Slave pos {i}: {info:?}"); 24 | found += 1; 25 | } 26 | Err(_) => { 27 | println!("Slave pos {i}: "); 28 | } 29 | } 30 | } 31 | 32 | println!("Discovered {found} slaves (checked positions 0..31)"); 33 | 34 | Ok(()) 35 | } 36 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | pull_request: 7 | 8 | env: 9 | CARGO_TERM_COLOR: always 10 | 11 | jobs: 12 | fmt: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v4 16 | - uses: actions-rust-lang/setup-rust-toolchain@v1 17 | with: 18 | toolchain: stable 19 | components: rustfmt 20 | - run: cargo fmt --all -- --check 21 | 22 | build: 23 | runs-on: ubuntu-latest 24 | strategy: 25 | matrix: 26 | toolchain: 27 | - 1.63.0 28 | - stable 29 | - nightly 30 | env: 31 | ETHERCAT_PATH: ../ethercat-git 32 | steps: 33 | - uses: actions/checkout@v4 34 | - uses: actions-rust-lang/setup-rust-toolchain@v1 35 | with: 36 | toolchain: ${{ matrix.toolchain }} 37 | components: clippy 38 | 39 | - name: Set up IgH repo 40 | run: | 41 | git clone https://gitlab.com/etherlab.org/ethercat ethercat-git 42 | cd ethercat-git 43 | git checkout stable-1.6 44 | ./bootstrap 45 | ./configure --disable-8139too 46 | 47 | - run: cargo clippy --all-targets 48 | - run: cargo build --all-targets 49 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | 3 | [package] 4 | name = "ethercat" 5 | version = "0.3.1" 6 | description = "Binding to the IgH/Etherlab open-source EtherCAT master" 7 | keywords = ["ethercat", "master", "etherlab", "fieldbus", "automation"] 8 | authors = ["Georg Brandl ", "slowtec GmbH "] 9 | repository = "https://github.com/ethercat-rs/ethercat" 10 | readme = "README.md" 11 | license = "MIT/Apache-2.0" 12 | edition = "2018" 13 | 14 | [dependencies] 15 | derive-new = "0.5" 16 | ethercat-sys = { path = "ethercat-sys", version = "0.3" } 17 | ethercat-types = "0.3.1" 18 | libc = "0.2" 19 | log = "0.4" 20 | memmap = "0.7" 21 | num-traits = "0.2" 22 | thiserror = "1.0" 23 | 24 | [dev-dependencies] 25 | ethercat-esi = "0.2" 26 | env_logger = "0.8" 27 | 28 | [features] 29 | default = [] 30 | 31 | # Enable this feature to use it with the 32 | # synapticon branch `release/v1.5.2-sncn-11` 33 | # at https://github.com/synapticon/Etherlab_EtherCAT_Master 34 | sncn = ["ethercat-sys/sncn"] 35 | 36 | # Enable this feature to use pregenerated bindings. 37 | # CAUTION: If your kernel module was not built 38 | # with the corresponding version, it might break your application. 39 | pregenerated-bindings = ["ethercat-sys/pregenerated-bindings"] 40 | 41 | [package.metadata.docs.rs] 42 | features = [ "pregenerated-bindings" ] 43 | 44 | [badges] 45 | maintenance = { status = "actively-developed" } 46 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # The `ethercat` crate 2 | 3 | [![Apache 2.0 licensed](https://img.shields.io/badge/license-Apache2.0-blue.svg)](./LICENSE-APACHE) 4 | [![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE-MIT) 5 | [![crates.io](https://img.shields.io/crates/v/ethercat.svg)](https://crates.io/crates/ethercat) 6 | [![docs](https://docs.rs/ethercat/badge.svg)](https://docs.rs/ethercat) 7 | 8 | [Documentation](https://docs.rs/crate/ethercat/) 9 | 10 | # About 11 | 12 | The `ethercat` crate provides a Rust wrapper for the IgH/Etherlab 13 | [EtherCAT Master for Linux](https://etherlab.org/en/ethercat/). 14 | 15 | EtherCAT is an Ethernet-based fieldbus system, originally invented by Beckhoff 16 | GmbH but now used by numerous providers of automation related hardware. 17 | The IgH master lets you provide an EtherCAT master on a Linux machine without 18 | specialized hardware. 19 | 20 | # Building 21 | 22 | In order to build the raw wrapper crate `ethercat-sys`, you need to set the 23 | environment variable `ETHERCAT_PATH` to the location of a checkout of the IgH 24 | Etherlab repository, *after running `configure` there*. 25 | 26 | The IgH repository is located at . 27 | Please switch to the ``stable-1.6`` branch in the checkout. 28 | 29 | Bindings have been pregenerated for the tag `1.6.1` - if you activate the 30 | feature `pregenerated-bindings`, you don't need the master code to build, but 31 | the kernel modules must match that revision. 32 | 33 | The minimum tested Rust version is 1.63.0. 34 | 35 | # Licensing 36 | 37 | The Etherlab master provides Linux kernel modules under GPLv2 with an ioctl 38 | based interface, and a userspace library under LGPLv2.1. This crate does 39 | not use the userspace library (which is mostly a simple wrapper around the 40 | ioctls anyway) but rather communicates with the kernel modules through the 41 | raw ioctls. 42 | 43 | Therefore, we believe that the crate does not need to be GPLv2-licensed, and 44 | are using the dual MIT/Apache-2 license commonly used for Rust crates. 45 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## Unreleased 4 | 5 | - Update to stable-1.6 branch of master code (#48) 6 | - Update `pregenerated-bindings` to tag 1.6.1 of the master code 7 | 8 | ## v0.3.1 (2023-10-14) 9 | 10 | - Bump MSRV to 1.63.0 11 | - Add `Master::sync_reference_clock_to` (PR #46) 12 | 13 | ## v0.3.0 (2023-04-05) 14 | 15 | - Bump MSRV to 1.58.1 and bindgen to 0.63 (PR #42) 16 | - Update `pregenerated-bindings` to commit c022ddbc of the master code 17 | 18 | ## v0.2.4 (2023-02-24) 19 | 20 | - Fix compilation on ARM (PR #40) 21 | 22 | ## v0.2.3 (2022-12-03) 23 | 24 | - Add `Master::foe_read` and `Master::foe_write` methods (PR #35) 25 | 26 | ## v0.2.2 (2021-03-27) 27 | 28 | - Implement `SdoData` for floating point types 29 | - Add bindings to distributed-clock related APIs on `Master` 30 | 31 | ## v0.2.1 (2020-11-21) 32 | 33 | - Use `AlState` from `ethercat-types` 34 | 35 | ## v0.2.0 (2020-11-02) 36 | 37 | - Move to [ethercat-rs](https://github.com/ethercat-rs) GitHub organization 38 | - Move `ethercat-plc` into [separate repository](https://github.com/ethercat-rs/ethercat-plc) 39 | - Move some common data structures into separate crate [`ethercat-types`](https://github.com/ethercat-rs/ethercat-types) 40 | - BREAKING: `Master::reserve` does not open an instance anymore, use `Master::open` instead 41 | - BREAKING: Rename a lot of fields and types from `index` to `idx` 42 | - BREAKING: Rename `PdoInfo` to `PdoCfg` 43 | - BREAKING: Split some fields from `SyncInfo` into `SyncCfg` 44 | - BREAKING: Refactor & change `Master::config_pdos` to `Master::config_sm_pdos` 45 | - BREAKING: Use specital `Error` enum instead of `io::Error` 46 | - BRAKING: `Master::sdo_download` has now a `complet_access` parameter 47 | - Add `Master::master_count` 48 | - Add `Master::get_sdo` & `Master::get_sdo_entry` 49 | - Add `Master::get_pdo` & `Master::get_pdo_entry` 50 | - Add `Master::get_sync` 51 | - Add `Master::request_state` 52 | - Add `Master::dict_upload` 53 | - Add some basic log messages 54 | - Add `info`, `sdo`, `cyclic-data` examples 55 | - Add `pregenerated-bindings` feature to compile the crate with pregenerated bindings (CAUTION: this might lead to problems) 56 | - Add `sncn` feature to compile with synapticon `v1.5.2-sncn-11` fork 57 | - Auto generate ioctl numbers from master header 58 | - Derive some more implementations like `Clone`, `Copy`, etc. for some datastructures 59 | - Refactoring & dependency updates 60 | 61 | ## v0.1.3 (2019-10-12) 62 | 63 | - Relicense under MIT/Apache 2.0 64 | - Add definition for Beckhoff EL1502 65 | - Update dependencies 66 | 67 | ## v0.1.1 (2019-04-03) 68 | 69 | - Fix ioctls for 32 Bit systems 70 | - Add motor controller (EL7047) demo 71 | - Minor fixes & dependency updates 72 | 73 | ## v0.1.0 (2019-03-01) 74 | 75 | - Initial release 76 | -------------------------------------------------------------------------------- /src/convert.rs: -------------------------------------------------------------------------------- 1 | // Part of ethercat-rs. Copyright 2018-2022 by the authors. 2 | // This work is dual-licensed under Apache 2.0 and MIT terms. 3 | 4 | use crate::types::{Error, Result}; 5 | use std::ffi::CStr; 6 | use std::io; 7 | use std::os::raw::c_char; 8 | 9 | pub(crate) fn string_to_foe_name(input: &str) -> Result<[c_char; 32]> { 10 | if input.len() > 32 { 11 | let e = io::Error::new( 12 | io::ErrorKind::InvalidInput, 13 | format!( 14 | "FoE name can have a maximum length of 32, '{}' has {}", 15 | input, 16 | input.len() 17 | ), 18 | ); 19 | return Err(Error::Io(e)); 20 | } 21 | let mut foe_name: [std::os::raw::c_char; 32] = [0; 32]; 22 | input 23 | .as_bytes() 24 | .iter() 25 | .zip(&mut foe_name) 26 | .for_each(|(i, r)| *r = *i as _); 27 | Ok(foe_name) 28 | } 29 | 30 | #[test] 31 | fn test_string_to_foe_name() { 32 | let cmp = |s: String, chars: [i8; 32]| { 33 | let arr: Vec = s.as_bytes().iter().map(|c| *c as i8).collect(); 34 | assert_eq!(chars.len(), 32); 35 | assert_eq!(chars[0..arr.len()], arr); 36 | assert_eq!(chars[arr.len()..], vec![0; 32 - s.len()]); 37 | }; 38 | 39 | let name = String::from("some Name of a FoE file"); 40 | let chars = string_to_foe_name(&name).expect("Name is ok"); 41 | cmp(name, chars); 42 | 43 | let name = String::from("short"); 44 | let chars = string_to_foe_name(&name).expect("Name is ok"); 45 | cmp(name, chars); 46 | 47 | let name = String::from("\u{2665}\u{1F494};"); 48 | let chars = string_to_foe_name(&name).expect("Name is ok"); 49 | cmp(name, chars); 50 | 51 | let name = String::from("a name that is just too long so we'll see what happens"); 52 | let e = string_to_foe_name(&name).unwrap_err(); 53 | assert_eq!( 54 | e.to_string(), 55 | format!( 56 | "FoE name can have a maximum length of 32, '{}' has {}", 57 | name, 58 | name.len() 59 | ) 60 | ); 61 | } 62 | 63 | pub(crate) fn c_array_to_string(data: *const i8) -> String { 64 | unsafe { 65 | CStr::from_ptr(data as *const c_char) 66 | .to_string_lossy() 67 | .into_owned() 68 | } 69 | } 70 | 71 | #[test] 72 | fn test_c_array_to_string() { 73 | let arr: [i8; 64] = [0_i8; 64]; 74 | assert_eq!(c_array_to_string(arr.as_ptr()), ""); 75 | 76 | let mut arr: [i8; 64] = [0_i8; 64]; 77 | [80_i8, 114, 111, 100, 117, 99, 116, 32, 99, 111, 100, 101] 78 | .iter() 79 | .enumerate() 80 | .for_each(|(idx, v)| { 81 | arr[idx] = *v; 82 | }); 83 | assert_eq!(c_array_to_string(arr.as_ptr()), "Product code"); 84 | } 85 | -------------------------------------------------------------------------------- /ethercat-sys/build.rs: -------------------------------------------------------------------------------- 1 | // Part of ethercat-rs. Copyright 2018-2022 by the authors. 2 | // This work is dual-licensed under Apache 2.0 and MIT terms. 3 | 4 | use std::{env, fmt::Write, fs, path::PathBuf}; 5 | 6 | fn main() { 7 | if env::var("CARGO_FEATURE_PREGENERATED_BINDINGS").is_err() { 8 | let path = env::var("ETHERCAT_PATH").expect( 9 | "Please set the ETHERCAT_PATH env var to the location of \ 10 | a checkout of the Ethercat master after running configure", 11 | ); 12 | 13 | let bindings = bindgen::Builder::default() 14 | .header(format!("{}/lib/ioctl.h", path)) 15 | .clang_arg(format!("-I{}", path)) 16 | .derive_default(true) 17 | .derive_debug(false) 18 | .prepend_enum_name(false) 19 | .ignore_functions() 20 | .allowlist_type("ec_ioctl_.*") 21 | .allowlist_type("ec_master_state_t") 22 | .allowlist_var("EC_IOCTL_.*") 23 | .allowlist_var("EC_MAX_.*") 24 | .layout_tests(false) 25 | .generate() 26 | .expect("Unable to generate bindings"); 27 | 28 | let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); 29 | bindings 30 | .write_to_file(out_path.join("bindings.rs")) 31 | .expect("Couldn't write bindings!"); 32 | 33 | // Generate the EC_IOCTL_ ioctl numbers -- bindgen can't handle them. 34 | let code = fs::read_to_string(format!("{}/master/ioctl.h", path)) 35 | .expect("master/ioctl.h not found"); 36 | let mut new = String::new(); 37 | for line in code.split('\n') { 38 | let parts = line.split_whitespace().collect::>(); 39 | if parts.len() >= 3 40 | && parts[0] == "#define" 41 | && parts[1].starts_with("EC_IOCTL_") 42 | && parts[2].starts_with("EC_IO") 43 | { 44 | let name = &parts[1]["EC_IOCTL_".len()..]; 45 | 46 | // FIXME: 47 | // There are constant names that start with a number 48 | // so they would be invalid rust code. 49 | // The problem exists e.g. if you try to 50 | // compile the v1.5.2-sncn-11 branch of the synapticon 51 | // fork: https://github.com/synapticon/Etherlab_EtherCAT_Master 52 | // So as a first dirty workaround we just ignore them 53 | // to be able to compile. 54 | if name.starts_with("64_REF_CLK") { 55 | continue; 56 | } 57 | 58 | let mut numparts = parts[2].split('('); 59 | let access = match numparts.next().unwrap() { 60 | "EC_IO" => match name { 61 | "SEND" | "SEND_EXT" => "arg", 62 | x if x.starts_with("DOMAIN_") => "arg", 63 | _ => "none", 64 | }, 65 | "EC_IOR" => "read", 66 | "EC_IOW" => "write", 67 | "EC_IOWR" => "readwrite", 68 | _ => unreachable!("invalid IO macro found"), 69 | }; 70 | let number = numparts.next().unwrap().trim_matches(&[')', ','][..]); 71 | let argtype = parts.get(3).map(|p| match p.trim_matches(')') { 72 | "uint32_t" => "u32", 73 | "uint64_t" => "u64", 74 | "size_t" => "usize", 75 | x => x, 76 | }); 77 | writeln!( 78 | &mut new, 79 | "ioctl!({:10} {:20} with EC, {}{}{});", 80 | access, 81 | name, 82 | number, 83 | if argtype.is_some() { "; " } else { "" }, 84 | argtype.unwrap_or("") 85 | ) 86 | .unwrap(); 87 | } 88 | } 89 | fs::write(out_path.join("ioctls.rs"), new.as_bytes()) 90 | .expect("failed to write ioctls.rs bindings"); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /examples/cyclic-data.rs: -------------------------------------------------------------------------------- 1 | use ethercat::{ 2 | AlState, DomainIdx as DomainIndex, Master, MasterAccess, Offset, PdoCfg, PdoEntryIdx, 3 | PdoEntryInfo, PdoEntryPos, SlaveAddr, SlaveId, SlavePos, SmCfg, 4 | }; 5 | use ethercat_esi::EtherCatInfo; 6 | use std::{ 7 | collections::HashMap, 8 | env, 9 | fs::File, 10 | io::{self, prelude::*}, 11 | thread, 12 | time::Duration, 13 | }; 14 | 15 | type BitLen = u8; 16 | 17 | pub fn main() -> Result<(), io::Error> { 18 | env_logger::init(); 19 | let args: Vec<_> = env::args().collect(); 20 | let file_name = match args.len() { 21 | 2 => &args[1], 22 | _ => { 23 | println!("usage: {} ESI-FILE", env!("CARGO_PKG_NAME")); 24 | return Ok(()); 25 | } 26 | }; 27 | 28 | log::debug!("Parse XML file {}", file_name); 29 | let mut esi_file = File::open(file_name)?; 30 | let mut esi_xml_string = String::new(); 31 | esi_file.read_to_string(&mut esi_xml_string)?; 32 | let esi = EtherCatInfo::from_xml_str(&esi_xml_string)?; 33 | let (mut master, domain_idx, offsets) = init_master(&esi, 0_u32)?; 34 | for (s, o) in &offsets { 35 | log::info!("PDO offsets of Slave {}:", u16::from(*s)); 36 | for (pdo, (bit_len, offset)) in o { 37 | log::info!( 38 | " - {:X}:{:X} - {:?}, bit length: {}", 39 | u16::from(pdo.idx), 40 | u8::from(pdo.sub_idx), 41 | offset, 42 | bit_len 43 | ); 44 | } 45 | } 46 | let cycle_time = Duration::from_micros(50_000); 47 | master.activate()?; 48 | 49 | loop { 50 | master.receive()?; 51 | master.domain(domain_idx).process()?; 52 | master.domain(domain_idx).queue()?; 53 | master.send()?; 54 | let m_state = master.state()?; 55 | let d_state = master.domain(domain_idx).state(); 56 | log::debug!("Master state: {:?}", m_state); 57 | log::debug!("Domain state: {:?}", d_state); 58 | if m_state.link_up && m_state.al_states == 8 { 59 | let raw_data = master.domain_data(domain_idx); 60 | log::debug!("{:?}", raw_data); 61 | } 62 | thread::sleep(cycle_time); 63 | } 64 | } 65 | 66 | type SlaveMap = HashMap>; 67 | 68 | pub fn init_master( 69 | esi: &EtherCatInfo, 70 | idx: u32, 71 | ) -> Result<(Master, DomainIndex, SlaveMap), io::Error> { 72 | let mut master = Master::open(idx, MasterAccess::ReadWrite)?; 73 | log::debug!("Reserve master"); 74 | master.reserve()?; 75 | log::debug!("Create domain"); 76 | let domain_idx = master.create_domain()?; 77 | let mut offsets: HashMap> = HashMap::new(); 78 | 79 | for (dev_nr, dev) in esi.description.devices.iter().enumerate() { 80 | let slave_pos = SlavePos::from(dev_nr as u16); 81 | log::debug!("Request PreOp state for {:?}", slave_pos); 82 | master.request_state(slave_pos, AlState::PreOp)?; 83 | let slave_info = master.get_slave_info(slave_pos)?; 84 | log::info!("Found device {}:{:?}", dev.name, slave_info); 85 | let slave_addr = SlaveAddr::ByPos(dev_nr as u16); 86 | let slave_id = SlaveId { 87 | vendor_id: esi.vendor.id, 88 | product_code: dev.product_code, 89 | }; 90 | let mut config = master.configure_slave(slave_addr, slave_id)?; 91 | let mut entry_offsets: HashMap = HashMap::new(); 92 | 93 | let rx_pdos: Vec = dev 94 | .rx_pdo 95 | .iter() 96 | .map(|pdo| PdoCfg { 97 | idx: pdo.idx, 98 | entries: pdo 99 | .entries 100 | .iter() 101 | .enumerate() 102 | .map(|(i, e)| PdoEntryInfo { 103 | entry_idx: e.entry_idx, 104 | bit_len: e.bit_len as u8, 105 | name: e.name.clone().unwrap_or_default(), 106 | pos: PdoEntryPos::from(i as u8), 107 | }) 108 | .collect(), 109 | }) 110 | .collect(); 111 | 112 | let tx_pdos: Vec = dev 113 | .tx_pdo 114 | .iter() 115 | .map(|pdo| PdoCfg { 116 | idx: pdo.idx, 117 | entries: pdo 118 | .entries 119 | .iter() 120 | .enumerate() 121 | .map(|(i, e)| PdoEntryInfo { 122 | entry_idx: e.entry_idx, 123 | bit_len: e.bit_len as u8, 124 | name: e.name.clone().unwrap_or_default(), 125 | pos: PdoEntryPos::from(i as u8), 126 | }) 127 | .collect(), 128 | }) 129 | .collect(); 130 | 131 | let output = SmCfg::output(2.into()); 132 | let input = SmCfg::input(3.into()); 133 | 134 | config.config_sm_pdos(output, &rx_pdos)?; 135 | config.config_sm_pdos(input, &tx_pdos)?; 136 | 137 | for pdo in &rx_pdos { 138 | // Positions of RX PDO 139 | log::debug!("Positions of RX PDO 0x{:X}:", u16::from(pdo.idx)); 140 | for entry in &pdo.entries { 141 | let offset = config.register_pdo_entry(entry.entry_idx, domain_idx)?; 142 | entry_offsets.insert(entry.entry_idx, (entry.bit_len, offset)); 143 | } 144 | } 145 | for pdo in &tx_pdos { 146 | // Positions of TX PDO 147 | log::debug!("Positions of TX PDO 0x{:X}:", u16::from(pdo.idx)); 148 | for entry in &pdo.entries { 149 | let offset = config.register_pdo_entry(entry.entry_idx, domain_idx)?; 150 | entry_offsets.insert(entry.entry_idx, (entry.bit_len, offset)); 151 | } 152 | } 153 | 154 | let cfg_index = config.index(); 155 | let cfg_info = master.get_config_info(cfg_index)?; 156 | log::info!("Config info: {:#?}", cfg_info); 157 | if cfg_info.slave_position.is_none() { 158 | return Err(io::Error::new( 159 | io::ErrorKind::Other, 160 | "Unable to configure slave", 161 | )); 162 | } 163 | offsets.insert(slave_pos, entry_offsets); 164 | } 165 | Ok((master, domain_idx, offsets)) 166 | } 167 | -------------------------------------------------------------------------------- /ethercat-sys/src/ioctls-v1.6.1.rs: -------------------------------------------------------------------------------- 1 | ioctl!(read MODULE with EC, 0x00; ec_ioctl_module_t); 2 | ioctl!(read MASTER with EC, 0x01; ec_ioctl_master_t); 3 | ioctl!(readwrite SLAVE with EC, 0x02; ec_ioctl_slave_t); 4 | ioctl!(readwrite SLAVE_SYNC with EC, 0x03; ec_ioctl_slave_sync_t); 5 | ioctl!(readwrite SLAVE_SYNC_PDO with EC, 0x04; ec_ioctl_slave_sync_pdo_t); 6 | ioctl!(readwrite SLAVE_SYNC_PDO_ENTRY with EC, 0x05; ec_ioctl_slave_sync_pdo_entry_t); 7 | ioctl!(readwrite DOMAIN with EC, 0x06; ec_ioctl_domain_t); 8 | ioctl!(readwrite DOMAIN_FMMU with EC, 0x07; ec_ioctl_domain_fmmu_t); 9 | ioctl!(readwrite DOMAIN_DATA with EC, 0x08; ec_ioctl_domain_data_t); 10 | ioctl!(none MASTER_DEBUG with EC, 0x09); 11 | ioctl!(none MASTER_RESCAN with EC, 0x0a); 12 | ioctl!(write SLAVE_STATE with EC, 0x0b; ec_ioctl_slave_state_t); 13 | ioctl!(readwrite SLAVE_SDO with EC, 0x0c; ec_ioctl_slave_sdo_t); 14 | ioctl!(readwrite SLAVE_SDO_ENTRY with EC, 0x0d; ec_ioctl_slave_sdo_entry_t); 15 | ioctl!(readwrite SLAVE_SDO_UPLOAD with EC, 0x0e; ec_ioctl_slave_sdo_upload_t); 16 | ioctl!(readwrite SLAVE_SDO_DOWNLOAD with EC, 0x0f; ec_ioctl_slave_sdo_download_t); 17 | ioctl!(readwrite SLAVE_SII_READ with EC, 0x10; ec_ioctl_slave_sii_t); 18 | ioctl!(write SLAVE_SII_WRITE with EC, 0x11; ec_ioctl_slave_sii_t); 19 | ioctl!(readwrite SLAVE_REG_READ with EC, 0x12; ec_ioctl_slave_reg_t); 20 | ioctl!(write SLAVE_REG_WRITE with EC, 0x13; ec_ioctl_slave_reg_t); 21 | ioctl!(readwrite SLAVE_FOE_READ with EC, 0x14; ec_ioctl_slave_foe_t); 22 | ioctl!(write SLAVE_FOE_WRITE with EC, 0x15; ec_ioctl_slave_foe_t); 23 | ioctl!(readwrite SLAVE_SOE_READ with EC, 0x16; ec_ioctl_slave_soe_read_t); 24 | ioctl!(readwrite SLAVE_SOE_WRITE with EC, 0x17; ec_ioctl_slave_soe_write_t); 25 | ioctl!(write SLAVE_EOE_IP_PARAM with EC, 0x18; ec_ioctl_eoe_ip_t); 26 | ioctl!(readwrite CONFIG with EC, 0x19; ec_ioctl_config_t); 27 | ioctl!(readwrite CONFIG_PDO with EC, 0x1a; ec_ioctl_config_pdo_t); 28 | ioctl!(readwrite CONFIG_PDO_ENTRY with EC, 0x1b; ec_ioctl_config_pdo_entry_t); 29 | ioctl!(readwrite CONFIG_SDO with EC, 0x1c; ec_ioctl_config_sdo_t); 30 | ioctl!(readwrite CONFIG_IDN with EC, 0x1d; ec_ioctl_config_idn_t); 31 | ioctl!(readwrite CONFIG_FLAG with EC, 0x1e; ec_ioctl_config_flag_t); 32 | ioctl!(readwrite CONFIG_EOE_IP_PARAM with EC, 0x1f; ec_ioctl_eoe_ip_t); 33 | ioctl!(readwrite EOE_HANDLER with EC, 0x20; ec_ioctl_eoe_handler_t); 34 | ioctl!(none REQUEST with EC, 0x21); 35 | ioctl!(none CREATE_DOMAIN with EC, 0x22); 36 | ioctl!(readwrite CREATE_SLAVE_CONFIG with EC, 0x23; ec_ioctl_config_t); 37 | ioctl!(write SELECT_REF_CLOCK with EC, 0x24; u32); 38 | ioctl!(read ACTIVATE with EC, 0x25; ec_ioctl_master_activate_t); 39 | ioctl!(none DEACTIVATE with EC, 0x26); 40 | ioctl!(arg SEND with EC, 0x27); 41 | ioctl!(none RECEIVE with EC, 0x28); 42 | ioctl!(read MASTER_STATE with EC, 0x29; ec_master_state_t); 43 | ioctl!(readwrite MASTER_LINK_STATE with EC, 0x2a; ec_ioctl_link_state_t); 44 | ioctl!(write APP_TIME with EC, 0x2b; u64); 45 | ioctl!(none SYNC_REF with EC, 0x2c); 46 | ioctl!(write SYNC_REF_TO with EC, 0x2d; u64); 47 | ioctl!(none SYNC_SLAVES with EC, 0x2e); 48 | ioctl!(read REF_CLOCK_TIME with EC, 0x2f; u32); 49 | ioctl!(none SYNC_MON_QUEUE with EC, 0x30); 50 | ioctl!(read SYNC_MON_PROCESS with EC, 0x31; u32); 51 | ioctl!(none RESET with EC, 0x32); 52 | ioctl!(write SC_SYNC with EC, 0x33; ec_ioctl_config_t); 53 | ioctl!(write SC_WATCHDOG with EC, 0x34; ec_ioctl_config_t); 54 | ioctl!(write SC_ADD_PDO with EC, 0x35; ec_ioctl_config_pdo_t); 55 | ioctl!(write SC_CLEAR_PDOS with EC, 0x36; ec_ioctl_config_pdo_t); 56 | ioctl!(write SC_ADD_ENTRY with EC, 0x37; ec_ioctl_add_pdo_entry_t); 57 | ioctl!(write SC_CLEAR_ENTRIES with EC, 0x38; ec_ioctl_config_pdo_t); 58 | ioctl!(readwrite SC_REG_PDO_ENTRY with EC, 0x39; ec_ioctl_reg_pdo_entry_t); 59 | ioctl!(readwrite SC_REG_PDO_POS with EC, 0x3a; ec_ioctl_reg_pdo_pos_t); 60 | ioctl!(write SC_DC with EC, 0x3b; ec_ioctl_config_t); 61 | ioctl!(write SC_SDO with EC, 0x3c; ec_ioctl_sc_sdo_t); 62 | ioctl!(write SC_EMERG_SIZE with EC, 0x3d; ec_ioctl_sc_emerg_t); 63 | ioctl!(readwrite SC_EMERG_POP with EC, 0x3e; ec_ioctl_sc_emerg_t); 64 | ioctl!(write SC_EMERG_CLEAR with EC, 0x3f; ec_ioctl_sc_emerg_t); 65 | ioctl!(readwrite SC_EMERG_OVERRUNS with EC, 0x40; ec_ioctl_sc_emerg_t); 66 | ioctl!(readwrite SC_SDO_REQUEST with EC, 0x41; ec_ioctl_sdo_request_t); 67 | ioctl!(readwrite SC_SOE_REQUEST with EC, 0x42; ec_ioctl_soe_request_t); 68 | ioctl!(readwrite SC_REG_REQUEST with EC, 0x43; ec_ioctl_reg_request_t); 69 | ioctl!(readwrite SC_VOE with EC, 0x44; ec_ioctl_voe_t); 70 | ioctl!(readwrite SC_STATE with EC, 0x45; ec_ioctl_sc_state_t); 71 | ioctl!(write SC_IDN with EC, 0x46; ec_ioctl_sc_idn_t); 72 | ioctl!(write SC_FLAG with EC, 0x47; ec_ioctl_sc_flag_t); 73 | ioctl!(write SC_EOE_IP_PARAM with EC, 0x48; ec_ioctl_eoe_ip_t); 74 | ioctl!(write SC_STATE_TIMEOUT with EC, 0x49; ec_ioctl_sc_state_timeout_t); 75 | ioctl!(arg DOMAIN_SIZE with EC, 0x4a); 76 | ioctl!(arg DOMAIN_OFFSET with EC, 0x4b); 77 | ioctl!(arg DOMAIN_PROCESS with EC, 0x4c); 78 | ioctl!(arg DOMAIN_QUEUE with EC, 0x4d); 79 | ioctl!(readwrite DOMAIN_STATE with EC, 0x4e; ec_ioctl_domain_state_t); 80 | ioctl!(readwrite SDO_REQUEST_INDEX with EC, 0x4f; ec_ioctl_sdo_request_t); 81 | ioctl!(readwrite SDO_REQUEST_TIMEOUT with EC, 0x50; ec_ioctl_sdo_request_t); 82 | ioctl!(readwrite SDO_REQUEST_STATE with EC, 0x51; ec_ioctl_sdo_request_t); 83 | ioctl!(readwrite SDO_REQUEST_READ with EC, 0x52; ec_ioctl_sdo_request_t); 84 | ioctl!(readwrite SDO_REQUEST_WRITE with EC, 0x53; ec_ioctl_sdo_request_t); 85 | ioctl!(readwrite SDO_REQUEST_DATA with EC, 0x54; ec_ioctl_sdo_request_t); 86 | ioctl!(readwrite SOE_REQUEST_IDN with EC, 0x55; ec_ioctl_soe_request_t); 87 | ioctl!(readwrite SOE_REQUEST_TIMEOUT with EC, 0x56; ec_ioctl_soe_request_t); 88 | ioctl!(readwrite SOE_REQUEST_STATE with EC, 0x57; ec_ioctl_soe_request_t); 89 | ioctl!(readwrite SOE_REQUEST_READ with EC, 0x58; ec_ioctl_soe_request_t); 90 | ioctl!(readwrite SOE_REQUEST_WRITE with EC, 0x59; ec_ioctl_soe_request_t); 91 | ioctl!(readwrite SOE_REQUEST_DATA with EC, 0x5a; ec_ioctl_soe_request_t); 92 | ioctl!(readwrite REG_REQUEST_DATA with EC, 0x5b; ec_ioctl_reg_request_t); 93 | ioctl!(readwrite REG_REQUEST_STATE with EC, 0x5c; ec_ioctl_reg_request_t); 94 | ioctl!(readwrite REG_REQUEST_WRITE with EC, 0x5d; ec_ioctl_reg_request_t); 95 | ioctl!(readwrite REG_REQUEST_READ with EC, 0x5e; ec_ioctl_reg_request_t); 96 | ioctl!(write VOE_SEND_HEADER with EC, 0x5f; ec_ioctl_voe_t); 97 | ioctl!(readwrite VOE_REC_HEADER with EC, 0x60; ec_ioctl_voe_t); 98 | ioctl!(write VOE_READ with EC, 0x61; ec_ioctl_voe_t); 99 | ioctl!(write VOE_READ_NOSYNC with EC, 0x62; ec_ioctl_voe_t); 100 | ioctl!(readwrite VOE_WRITE with EC, 0x63; ec_ioctl_voe_t); 101 | ioctl!(readwrite VOE_EXEC with EC, 0x64; ec_ioctl_voe_t); 102 | ioctl!(readwrite VOE_DATA with EC, 0x65; ec_ioctl_voe_t); 103 | ioctl!(write SET_SEND_INTERVAL with EC, 0x66; usize); 104 | -------------------------------------------------------------------------------- /src/types.rs: -------------------------------------------------------------------------------- 1 | // Part of ethercat-rs. Copyright 2018-2022 by the authors. 2 | // This work is dual-licensed under Apache 2.0 and MIT terms. 3 | 4 | use crate::ec; 5 | use derive_new::new; 6 | use std::io; 7 | use thiserror::Error; 8 | 9 | #[derive(Debug, Error)] 10 | pub enum Error { 11 | #[error("No devices available")] 12 | NoDevices, 13 | #[error("Sync manager index is too large")] 14 | SmIdxTooLarge, 15 | #[error("Invalid domain index {0}")] 16 | DomainIdx(usize), 17 | #[error("Kernel module version mismatch: expected {0}, found {1}")] 18 | KernelModule(u32, u32), 19 | #[error("Domain is not available")] 20 | NoDomain, 21 | #[error("Master is not activated")] 22 | NotActivated, 23 | #[error("Invalid AL state 0x{0:X}")] 24 | InvalidAlState(u8), 25 | #[error("SDO/VoE/register request failed")] 26 | RequestFailed, 27 | #[error(transparent)] 28 | Io(#[from] io::Error), 29 | } 30 | 31 | impl From for io::Error { 32 | fn from(e: Error) -> Self { 33 | io::Error::new(io::ErrorKind::Other, e) 34 | } 35 | } 36 | 37 | pub use ethercat_types::*; 38 | 39 | pub type Result = std::result::Result; 40 | pub type MasterIdx = u32; 41 | 42 | #[derive(Debug, Clone, Copy)] 43 | pub(crate) struct DomainDataPlacement { 44 | pub offset: usize, 45 | pub size: usize, 46 | } 47 | 48 | pub type SlaveConfigIdx = u32; 49 | 50 | /// An EtherCAT slave identification, consisting of vendor ID and product code. 51 | #[derive(Debug, Clone, Copy, new)] 52 | pub struct SlaveId { 53 | pub vendor_id: u32, 54 | pub product_code: u32, 55 | } 56 | 57 | /// An EtherCAT slave revision identification. 58 | #[derive(Debug, Clone, Copy, new)] 59 | pub struct SlaveRev { 60 | pub revision_number: u32, 61 | pub serial_number: u32, 62 | } 63 | 64 | /// An EtherCAT slave, which is specified either by absolute position in the 65 | /// ring or by offset from a given alias. 66 | #[derive(Debug, Clone, Copy)] 67 | pub enum SlaveAddr { 68 | ByPos(u16), 69 | ByAlias(u16, u16), 70 | } 71 | 72 | impl SlaveAddr { 73 | pub(crate) fn as_pair(self) -> (u16, u16) { 74 | match self { 75 | SlaveAddr::ByPos(x) => (0, x), 76 | SlaveAddr::ByAlias(x, y) => (x, y), 77 | } 78 | } 79 | } 80 | 81 | #[derive(Debug, Clone)] 82 | pub struct MasterInfo { 83 | pub slave_count: u32, 84 | pub link_up: bool, 85 | pub scan_busy: bool, 86 | pub app_time: u64, 87 | } 88 | 89 | #[derive(Debug, Clone)] 90 | pub struct MasterState { 91 | pub slaves_responding: u32, 92 | pub al_states: u8, 93 | pub link_up: bool, 94 | } 95 | 96 | #[derive(Debug, Clone)] 97 | pub struct ConfigInfo { 98 | pub alias: u16, 99 | pub position: u16, 100 | pub id: SlaveId, 101 | pub slave_position: Option, 102 | pub sdo_count: u32, 103 | pub idn_count: u32, 104 | // TODO: more attributes are returned: 105 | // syncs[*], watchdog_*, dc_* 106 | } 107 | 108 | #[derive(Debug, Clone)] 109 | pub struct SlaveInfo { 110 | pub name: String, 111 | pub ring_pos: u16, 112 | pub id: SlaveId, 113 | pub rev: SlaveRev, 114 | pub alias: u16, 115 | pub current_on_ebus: i16, 116 | pub al_state: AlState, 117 | pub error_flag: u8, 118 | pub sync_count: u8, 119 | pub sdo_count: u16, 120 | pub ports: [SlavePortInfo; ec::EC_MAX_PORTS as usize], 121 | } 122 | 123 | #[derive(Debug, Clone, Copy)] 124 | pub enum SlavePortType { 125 | NotImplemented, 126 | NotConfigured, 127 | EBus, 128 | MII, 129 | } 130 | 131 | #[allow(clippy::derivable_impls)] // later we can use the new #[default] attr 132 | impl Default for SlavePortType { 133 | fn default() -> Self { 134 | SlavePortType::NotImplemented 135 | } 136 | } 137 | 138 | #[derive(Debug, Default, Clone, Copy)] 139 | pub struct SlavePortLink { 140 | pub link_up: bool, 141 | pub loop_closed: bool, 142 | pub signal_detected: bool, 143 | } 144 | 145 | #[derive(Debug, Default, Clone, Copy)] 146 | pub struct SlavePortInfo { 147 | pub desc: SlavePortType, 148 | pub link: SlavePortLink, 149 | pub receive_time: u32, 150 | pub next_slave: u16, 151 | pub delay_to_next_dc: u32, 152 | } 153 | 154 | #[derive(Debug, Clone, Copy)] 155 | pub struct SlaveConfigState { 156 | pub online: bool, 157 | pub operational: bool, 158 | pub al_state: AlState, 159 | } 160 | 161 | #[derive(Debug, Clone, Copy)] 162 | pub enum SyncDirection { 163 | Invalid, 164 | Output, 165 | Input, 166 | } 167 | 168 | #[derive(Debug, Clone, Copy)] 169 | pub enum WatchdogMode { 170 | Default, 171 | Enable, 172 | Disable, 173 | } 174 | 175 | /// Sync Manager Info 176 | #[derive(Debug, Copy, Clone)] 177 | pub struct SmInfo { 178 | pub idx: SmIdx, 179 | pub start_addr: u16, 180 | pub default_size: u16, 181 | pub control_register: u8, 182 | pub enable: bool, 183 | pub pdo_count: u8, 184 | } 185 | 186 | /// Sync Manager Config 187 | #[derive(Debug, Clone, Copy)] 188 | pub struct SmCfg { 189 | pub idx: SmIdx, 190 | pub watchdog_mode: WatchdogMode, 191 | pub direction: SyncDirection, 192 | } 193 | 194 | impl SmCfg { 195 | pub const fn input(idx: SmIdx) -> Self { 196 | Self { 197 | idx, 198 | direction: SyncDirection::Input, 199 | watchdog_mode: WatchdogMode::Default, 200 | } 201 | } 202 | pub const fn output(idx: SmIdx) -> Self { 203 | Self { 204 | idx, 205 | direction: SyncDirection::Output, 206 | watchdog_mode: WatchdogMode::Default, 207 | } 208 | } 209 | } 210 | 211 | /// PDO Config 212 | #[derive(Debug, Clone)] 213 | pub struct PdoCfg { 214 | pub idx: PdoIdx, 215 | pub entries: Vec, 216 | } 217 | 218 | impl PdoCfg { 219 | pub const fn new(idx: PdoIdx) -> PdoCfg { 220 | Self { 221 | idx, 222 | entries: vec![], 223 | } 224 | } 225 | } 226 | 227 | pub trait SdoData { 228 | fn data_ptr(&self) -> *const u8 { 229 | self as *const _ as _ 230 | } 231 | fn data_size(&self) -> usize { 232 | std::mem::size_of_val(self) 233 | } 234 | } 235 | 236 | impl SdoData for u8 {} 237 | impl SdoData for u16 {} 238 | impl SdoData for u32 {} 239 | impl SdoData for u64 {} 240 | impl SdoData for i8 {} 241 | impl SdoData for i16 {} 242 | impl SdoData for i32 {} 243 | impl SdoData for i64 {} 244 | impl SdoData for f32 {} 245 | impl SdoData for f64 {} 246 | 247 | impl SdoData for &'_ [u8] { 248 | fn data_ptr(&self) -> *const u8 { 249 | self.as_ptr() 250 | } 251 | fn data_size(&self) -> usize { 252 | self.len() 253 | } 254 | } 255 | 256 | #[derive(Debug, Clone)] 257 | pub struct DomainState { 258 | pub working_counter: u32, 259 | pub wc_state: WcState, 260 | pub redundancy_active: bool, 261 | } 262 | 263 | #[derive(Debug, Clone, Copy)] 264 | pub enum WcState { 265 | Zero = 0, 266 | Incomplete, 267 | Complete, 268 | } 269 | 270 | pub(crate) fn get_sdo_entry_access(read: [u8; 3], write: [u8; 3]) -> SdoEntryAccess { 271 | SdoEntryAccess { 272 | pre_op: access(read[0], write[0]), 273 | safe_op: access(read[1], write[1]), 274 | op: access(read[2], write[2]), 275 | } 276 | } 277 | 278 | fn access(read: u8, write: u8) -> Access { 279 | match (read, write) { 280 | (1, 0) => Access::ReadOnly, 281 | (0, 1) => Access::WriteOnly, 282 | (1, 1) => Access::ReadWrite, 283 | _ => Access::Unknown, 284 | } 285 | } 286 | 287 | impl From for WcState { 288 | fn from(st: u32) -> Self { 289 | match st { 290 | 0 => WcState::Zero, 291 | 1 => WcState::Incomplete, 292 | 2 => WcState::Complete, 293 | x => panic!("invalid state {}", x), 294 | } 295 | } 296 | } 297 | -------------------------------------------------------------------------------- /ethercat-sys/src/ioctls-v1.5.2-sncn-11.rs: -------------------------------------------------------------------------------- 1 | ioctl!(read MODULE with EC, 0x00; ec_ioctl_module_t); 2 | ioctl!(read MASTER with EC, 0x01; ec_ioctl_master_t); 3 | ioctl!(readwrite SLAVE with EC, 0x02; ec_ioctl_slave_t); 4 | ioctl!(readwrite SLAVE_SYNC with EC, 0x03; ec_ioctl_slave_sync_t); 5 | ioctl!(readwrite SLAVE_SYNC_PDO with EC, 0x04; ec_ioctl_slave_sync_pdo_t); 6 | ioctl!(readwrite SLAVE_SYNC_PDO_ENTRY with EC, 0x05; ec_ioctl_slave_sync_pdo_entry_t); 7 | ioctl!(readwrite DOMAIN with EC, 0x06; ec_ioctl_domain_t); 8 | ioctl!(readwrite DOMAIN_FMMU with EC, 0x07; ec_ioctl_domain_fmmu_t); 9 | ioctl!(readwrite DOMAIN_DATA with EC, 0x08; ec_ioctl_domain_data_t); 10 | ioctl!(none MASTER_DEBUG with EC, 0x09); 11 | ioctl!(none MASTER_RESCAN with EC, 0x0a); 12 | ioctl!(write SLAVE_STATE with EC, 0x0b; ec_ioctl_slave_state_t); 13 | ioctl!(readwrite SLAVE_SDO with EC, 0x0c; ec_ioctl_slave_sdo_t); 14 | ioctl!(readwrite SLAVE_SDO_ENTRY with EC, 0x0d; ec_ioctl_slave_sdo_entry_t); 15 | ioctl!(readwrite SLAVE_SDO_UPLOAD with EC, 0x0e; ec_ioctl_slave_sdo_upload_t); 16 | ioctl!(readwrite SLAVE_SDO_DOWNLOAD with EC, 0x0f; ec_ioctl_slave_sdo_download_t); 17 | ioctl!(readwrite SLAVE_SII_READ with EC, 0x10; ec_ioctl_slave_sii_t); 18 | ioctl!(write SLAVE_SII_WRITE with EC, 0x11; ec_ioctl_slave_sii_t); 19 | ioctl!(readwrite SLAVE_REG_READ with EC, 0x12; ec_ioctl_slave_reg_t); 20 | ioctl!(write SLAVE_REG_WRITE with EC, 0x13; ec_ioctl_slave_reg_t); 21 | ioctl!(readwrite SLAVE_FOE_READ with EC, 0x14; ec_ioctl_slave_foe_t); 22 | ioctl!(write SLAVE_FOE_WRITE with EC, 0x15; ec_ioctl_slave_foe_t); 23 | ioctl!(readwrite SLAVE_SOE_READ with EC, 0x16; ec_ioctl_slave_soe_read_t); 24 | ioctl!(readwrite SLAVE_SOE_WRITE with EC, 0x17; ec_ioctl_slave_soe_write_t); 25 | ioctl!(write SLAVE_EOE_IP_PARAM with EC, 0x18; ec_ioctl_slave_eoe_ip_t); 26 | ioctl!(readwrite CONFIG with EC, 0x19; ec_ioctl_config_t); 27 | ioctl!(readwrite CONFIG_PDO with EC, 0x1a; ec_ioctl_config_pdo_t); 28 | ioctl!(readwrite CONFIG_PDO_ENTRY with EC, 0x1b; ec_ioctl_config_pdo_entry_t); 29 | ioctl!(readwrite CONFIG_SDO with EC, 0x1c; ec_ioctl_config_sdo_t); 30 | ioctl!(readwrite CONFIG_IDN with EC, 0x1d; ec_ioctl_config_idn_t); 31 | ioctl!(readwrite EOE_HANDLER with EC, 0x1e; ec_ioctl_eoe_handler_t); 32 | ioctl!(write SLAVE_DICT_UPLOAD with EC, 0x7f; ec_ioctl_slave_dict_upload_t); 33 | ioctl!(none REQUEST with EC, 0x1f); 34 | ioctl!(none CREATE_DOMAIN with EC, 0x20); 35 | ioctl!(readwrite CREATE_SLAVE_CONFIG with EC, 0x21; ec_ioctl_config_t); 36 | ioctl!(write SELECT_REF_CLOCK with EC, 0x22; u32); 37 | ioctl!(read ACTIVATE with EC, 0x23; ec_ioctl_master_activate_t); 38 | ioctl!(none DEACTIVATE with EC, 0x24); 39 | ioctl!(arg SEND with EC, 0x25); 40 | ioctl!(none RECEIVE with EC, 0x26); 41 | ioctl!(read MASTER_STATE with EC, 0x27; ec_master_state_t); 42 | ioctl!(readwrite MASTER_LINK_STATE with EC, 0x28; ec_ioctl_link_state_t); 43 | ioctl!(write APP_TIME with EC, 0x29; u64); 44 | ioctl!(none SYNC_REF with EC, 0x2a); 45 | ioctl!(write SYNC_REF_TO with EC, 0x2b; u64); 46 | ioctl!(none SYNC_SLAVES with EC, 0x2c); 47 | ioctl!(read REF_CLOCK_TIME with EC, 0x2d; u32); 48 | ioctl!(none SYNC_MON_QUEUE with EC, 0x2e); 49 | ioctl!(read SYNC_MON_PROCESS with EC, 0x2f; u32); 50 | ioctl!(none RESET with EC, 0x30); 51 | ioctl!(write SC_SYNC with EC, 0x31; ec_ioctl_config_t); 52 | ioctl!(write SC_WATCHDOG with EC, 0x32; ec_ioctl_config_t); 53 | ioctl!(write SC_ADD_PDO with EC, 0x33; ec_ioctl_config_pdo_t); 54 | ioctl!(write SC_CLEAR_PDOS with EC, 0x34; ec_ioctl_config_pdo_t); 55 | ioctl!(write SC_ADD_ENTRY with EC, 0x35; ec_ioctl_add_pdo_entry_t); 56 | ioctl!(write SC_CLEAR_ENTRIES with EC, 0x36; ec_ioctl_config_pdo_t); 57 | ioctl!(readwrite SC_REG_PDO_ENTRY with EC, 0x37; ec_ioctl_reg_pdo_entry_t); 58 | ioctl!(readwrite SC_REG_PDO_POS with EC, 0x38; ec_ioctl_reg_pdo_pos_t); 59 | ioctl!(write SC_DC with EC, 0x39; ec_ioctl_config_t); 60 | ioctl!(write SC_SDO with EC, 0x3a; ec_ioctl_sc_sdo_t); 61 | ioctl!(write SC_EMERG_SIZE with EC, 0x3b; ec_ioctl_sc_emerg_t); 62 | ioctl!(readwrite SC_EMERG_POP with EC, 0x3c; ec_ioctl_sc_emerg_t); 63 | ioctl!(write SC_EMERG_CLEAR with EC, 0x3d; ec_ioctl_sc_emerg_t); 64 | ioctl!(readwrite SC_EMERG_OVERRUNS with EC, 0x3e; ec_ioctl_sc_emerg_t); 65 | ioctl!(readwrite SC_SDO_REQUEST with EC, 0x3f; ec_ioctl_sdo_request_t); 66 | ioctl!(readwrite SC_REG_REQUEST with EC, 0x40; ec_ioctl_reg_request_t); 67 | ioctl!(readwrite SC_VOE with EC, 0x41; ec_ioctl_voe_t); 68 | ioctl!(readwrite SC_STATE with EC, 0x42; ec_ioctl_sc_state_t); 69 | ioctl!(write SC_IDN with EC, 0x43; ec_ioctl_sc_idn_t); 70 | ioctl!(arg DOMAIN_SIZE with EC, 0x44); 71 | ioctl!(arg DOMAIN_OFFSET with EC, 0x45); 72 | ioctl!(arg DOMAIN_PROCESS with EC, 0x46); 73 | ioctl!(arg DOMAIN_QUEUE with EC, 0x47); 74 | ioctl!(readwrite DOMAIN_STATE with EC, 0x48; ec_ioctl_domain_state_t); 75 | ioctl!(readwrite SDO_REQUEST_INDEX with EC, 0x49; ec_ioctl_sdo_request_t); 76 | ioctl!(readwrite SDO_REQUEST_TIMEOUT with EC, 0x4a; ec_ioctl_sdo_request_t); 77 | ioctl!(readwrite SDO_REQUEST_STATE with EC, 0x4b; ec_ioctl_sdo_request_t); 78 | ioctl!(readwrite SDO_REQUEST_READ with EC, 0x4c; ec_ioctl_sdo_request_t); 79 | ioctl!(readwrite SDO_REQUEST_WRITE with EC, 0x4d; ec_ioctl_sdo_request_t); 80 | ioctl!(readwrite SDO_REQUEST_DATA with EC, 0x4e; ec_ioctl_sdo_request_t); 81 | ioctl!(readwrite REG_REQUEST_DATA with EC, 0x4f; ec_ioctl_reg_request_t); 82 | ioctl!(readwrite REG_REQUEST_STATE with EC, 0x50; ec_ioctl_reg_request_t); 83 | ioctl!(readwrite REG_REQUEST_WRITE with EC, 0x51; ec_ioctl_reg_request_t); 84 | ioctl!(readwrite REG_REQUEST_READ with EC, 0x52; ec_ioctl_reg_request_t); 85 | ioctl!(write VOE_SEND_HEADER with EC, 0x53; ec_ioctl_voe_t); 86 | ioctl!(readwrite VOE_REC_HEADER with EC, 0x54; ec_ioctl_voe_t); 87 | ioctl!(write VOE_READ with EC, 0x55; ec_ioctl_voe_t); 88 | ioctl!(write VOE_READ_NOSYNC with EC, 0x56; ec_ioctl_voe_t); 89 | ioctl!(readwrite VOE_WRITE with EC, 0x57; ec_ioctl_voe_t); 90 | ioctl!(readwrite VOE_EXEC with EC, 0x58; ec_ioctl_voe_t); 91 | ioctl!(readwrite VOE_DATA with EC, 0x59; ec_ioctl_voe_t); 92 | ioctl!(write SET_SEND_INTERVAL with EC, 0x5a; usize); 93 | ioctl!(write SC_OVERLAPPING_IO with EC, 0x5b; ec_ioctl_config_t); 94 | ioctl!(write SLAVE_REBOOT with EC, 0x5c; ec_ioctl_slave_reboot_t); 95 | ioctl!(readwrite SLAVE_REG_READWRITE with EC, 0x5d; ec_ioctl_slave_reg_t); 96 | ioctl!(readwrite REG_REQUEST_READWRITE with EC, 0x5e; ec_ioctl_reg_request_t); 97 | ioctl!(read SETUP_DOMAIN_MEMORY with EC, 0x60; ec_ioctl_master_activate_t); 98 | ioctl!(none DEACTIVATE_SLAVES with EC, 0x61); 99 | ioctl!(readwrite SC_FOE_REQUEST with EC, 0x64; ec_ioctl_foe_request_t); 100 | ioctl!(readwrite FOE_REQUEST_FILE with EC, 0x65; ec_ioctl_foe_request_t); 101 | ioctl!(readwrite FOE_REQUEST_TIMEOUT with EC, 0x66; ec_ioctl_foe_request_t); 102 | ioctl!(readwrite FOE_REQUEST_STATE with EC, 0x67; ec_ioctl_foe_request_t); 103 | ioctl!(readwrite FOE_REQUEST_READ with EC, 0x68; ec_ioctl_foe_request_t); 104 | ioctl!(readwrite FOE_REQUEST_WRITE with EC, 0x69; ec_ioctl_foe_request_t); 105 | ioctl!(readwrite FOE_REQUEST_DATA with EC, 0x6a; ec_ioctl_foe_request_t); 106 | ioctl!(write RT_SLAVE_REQUESTS with EC, 0x6b; u32); 107 | ioctl!(none EXEC_SLAVE_REQUESTS with EC, 0x6c); 108 | ioctl!(none EOE_IS_OPEN with EC, 0x6d); 109 | ioctl!(none EOE_PROCESS with EC, 0x6e); 110 | ioctl!(arg SEND_EXT with EC, 0x6f); 111 | ioctl!(readwrite EOE_ADDIF with EC, 0x70; ec_ioctl_eoe_if_t); 112 | ioctl!(readwrite EOE_DELIF with EC, 0x71; ec_ioctl_eoe_if_t); 113 | ioctl!(readwrite PCAP_DATA with EC, 0x72; ec_ioctl_pcap_data_t); 114 | ioctl!(readwrite MBOX_GATEWAY with EC, 0x73; ec_ioctl_mbox_gateway_t); 115 | -------------------------------------------------------------------------------- /LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /src/master.rs: -------------------------------------------------------------------------------- 1 | // Part of ethercat-rs. Copyright 2018-2022 by the authors. 2 | // This work is dual-licensed under Apache 2.0 and MIT terms. 3 | 4 | #![allow(clippy::field_reassign_with_default)] 5 | 6 | use crate::{convert, ec, types::*}; 7 | use num_traits::cast::FromPrimitive; 8 | use std::{ 9 | collections::HashMap, 10 | convert::TryFrom, 11 | ffi::CStr, 12 | fs::{File, OpenOptions}, 13 | io, 14 | os::{raw::c_ulong, unix::io::AsRawFd}, 15 | }; 16 | 17 | macro_rules! ioctl { 18 | ($m:expr, $f:expr) => { ioctl!($m, $f,) }; 19 | ($m:expr, $f:expr, $($arg:tt)*) => {{ 20 | let res = unsafe { $f($m.file.as_raw_fd(), $($arg)*) }; 21 | if res < 0 { Err(Error::Io(io::Error::last_os_error())) } else { Ok(res) } 22 | }} 23 | } 24 | 25 | /// An EtherCAT master. 26 | pub struct Master { 27 | file: File, 28 | map: Option, 29 | domains: HashMap, 30 | } 31 | 32 | pub struct Domain<'m> { 33 | master: &'m Master, 34 | idx: DomainIdx, 35 | } 36 | 37 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] 38 | pub enum MasterAccess { 39 | ReadOnly, 40 | ReadWrite, 41 | } 42 | 43 | impl Master { 44 | pub fn open(idx: MasterIdx, access: MasterAccess) -> Result { 45 | let devpath = format!("/dev/EtherCAT{}", idx); 46 | log::debug!("Open EtherCAT Master {}", devpath); 47 | let file = OpenOptions::new() 48 | .read(true) 49 | .write(access == MasterAccess::ReadWrite) 50 | .open(&devpath)?; 51 | let mut module_info = ec::ec_ioctl_module_t::default(); 52 | let master = Master { 53 | file, 54 | map: None, 55 | domains: HashMap::new(), 56 | }; 57 | ioctl!(master, ec::ioctl::MODULE, &mut module_info)?; 58 | if module_info.ioctl_version_magic != ec::EC_IOCTL_VERSION_MAGIC { 59 | return Err(Error::KernelModule( 60 | ec::EC_IOCTL_VERSION_MAGIC, 61 | module_info.ioctl_version_magic, 62 | )); 63 | } 64 | Ok(master) 65 | } 66 | 67 | pub fn master_count() -> Result { 68 | let master = Self::open(0, MasterAccess::ReadOnly)?; 69 | let mut module_info = ec::ec_ioctl_module_t::default(); 70 | ioctl!(master, ec::ioctl::MODULE, &mut module_info)?; 71 | Ok(module_info.master_count as usize) 72 | } 73 | 74 | pub fn reserve(&self) -> Result<()> { 75 | log::debug!("Reserve EtherCAT Master"); 76 | ioctl!(self, ec::ioctl::REQUEST)?; 77 | Ok(()) 78 | } 79 | 80 | pub fn create_domain(&self) -> Result { 81 | Ok((ioctl!(self, ec::ioctl::CREATE_DOMAIN)? as usize).into()) 82 | } 83 | 84 | pub const fn domain(&self, idx: DomainIdx) -> Domain { 85 | Domain::new(idx, self) 86 | } 87 | 88 | pub fn domain_data(&mut self, idx: DomainIdx) -> Result<&mut [u8]> { 89 | let p = self 90 | .domain_data_placement(idx) 91 | .map_err(|_| Error::NoDomain)?; 92 | let data = self.map.as_mut().ok_or(Error::NotActivated)?; 93 | Ok(&mut data[p.offset..p.offset + p.size]) 94 | } 95 | 96 | fn domain_data_placement(&mut self, idx: DomainIdx) -> Result { 97 | Ok(match self.domains.get(&idx) { 98 | None => { 99 | let d_idx = 100 | c_ulong::try_from(idx).map_err(|_| Error::DomainIdx(usize::from(idx)))?; 101 | let offset = ioctl!(self, ec::ioctl::DOMAIN_OFFSET, d_idx)? as usize; 102 | let size = ioctl!(self, ec::ioctl::DOMAIN_SIZE, d_idx)? as usize; 103 | let meta_data = DomainDataPlacement { offset, size }; 104 | self.domains.insert(idx, meta_data); 105 | meta_data 106 | } 107 | Some(d) => *d, 108 | }) 109 | } 110 | 111 | pub fn activate(&mut self) -> Result<()> { 112 | log::debug!("Activate EtherCAT Master"); 113 | let mut data = ec::ec_ioctl_master_activate_t::default(); 114 | ioctl!(self, ec::ioctl::ACTIVATE, &mut data)?; 115 | 116 | self.map = unsafe { 117 | memmap::MmapOptions::new() 118 | .len(data.process_data_size) 119 | .map_mut(&self.file) 120 | .map(Some)? 121 | }; 122 | self.map.as_mut().ok_or(Error::NotActivated)?[0] = 0; 123 | Ok(()) 124 | } 125 | 126 | pub fn deactivate(&mut self) -> Result<()> { 127 | log::debug!("Deactivate EtherCAT Master"); 128 | ioctl!(self, ec::ioctl::DEACTIVATE)?; 129 | self.domains.clear(); 130 | self.map = None; 131 | Ok(()) 132 | } 133 | 134 | pub fn set_send_interval(&mut self, interval_us: usize) -> Result<()> { 135 | ioctl!(self, ec::ioctl::SET_SEND_INTERVAL, &interval_us).map(|_| ()) 136 | } 137 | 138 | pub fn send(&mut self) -> Result { 139 | let mut sent = 0; 140 | ioctl!(self, ec::ioctl::SEND, &mut sent as *mut _ as c_ulong)?; 141 | Ok(sent) 142 | } 143 | 144 | pub fn receive(&mut self) -> Result<()> { 145 | ioctl!(self, ec::ioctl::RECEIVE).map(|_| ()) 146 | } 147 | 148 | pub fn reset(&mut self) -> Result<()> { 149 | ioctl!(self, ec::ioctl::RESET).map(|_| ()) 150 | } 151 | 152 | pub fn state(&self) -> Result { 153 | let mut data = ec::ec_master_state_t::default(); 154 | ioctl!(self, ec::ioctl::MASTER_STATE, &mut data)?; 155 | Ok(MasterState { 156 | slaves_responding: data.slaves_responding, 157 | al_states: data.al_states() as u8, 158 | link_up: data.link_up() != 0, 159 | }) 160 | } 161 | 162 | pub fn link_state(&self, dev_idx: u32) -> Result { 163 | let mut state = ec::ec_master_link_state_t::default(); 164 | let mut data = ec::ec_ioctl_link_state_t { 165 | dev_idx, 166 | state: &mut state, 167 | }; 168 | ioctl!(self, ec::ioctl::MASTER_LINK_STATE, &mut data)?; 169 | Ok(MasterState { 170 | slaves_responding: state.slaves_responding, 171 | al_states: state.al_states() as u8, 172 | link_up: state.link_up() != 0, 173 | }) 174 | } 175 | 176 | pub fn get_info(&self) -> Result { 177 | let mut data = ec::ec_ioctl_master_t::default(); 178 | ioctl!(self, ec::ioctl::MASTER, &mut data)?; 179 | let ec::ec_ioctl_master_t { 180 | slave_count, 181 | devices, 182 | scan_busy, 183 | app_time, 184 | .. 185 | } = data; 186 | let first_device = devices.first().ok_or(Error::NoDevices)?; 187 | let link_up = first_device.link_state != 0; 188 | let scan_busy = scan_busy != 0; 189 | Ok(MasterInfo { 190 | slave_count, 191 | link_up, 192 | scan_busy, 193 | app_time, 194 | }) 195 | } 196 | 197 | pub fn get_slave_info(&self, position: SlavePos) -> Result { 198 | let mut data = ec::ec_ioctl_slave_t::default(); 199 | data.position = u16::from(position); 200 | ioctl!(self, ec::ioctl::SLAVE, &mut data)?; 201 | let mut ports = [SlavePortInfo::default(); ec::EC_MAX_PORTS as usize]; 202 | for (i, port) in ports.iter_mut().enumerate().take(ec::EC_MAX_PORTS as usize) { 203 | port.desc = match data.ports[i].desc { 204 | ec::EC_PORT_NOT_IMPLEMENTED => SlavePortType::NotImplemented, 205 | ec::EC_PORT_NOT_CONFIGURED => SlavePortType::NotConfigured, 206 | ec::EC_PORT_EBUS => SlavePortType::EBus, 207 | ec::EC_PORT_MII => SlavePortType::MII, 208 | x => panic!("invalid port type {}", x), 209 | }; 210 | port.link = SlavePortLink { 211 | link_up: data.ports[i].link.link_up != 0, 212 | loop_closed: data.ports[i].link.loop_closed != 0, 213 | signal_detected: data.ports[i].link.signal_detected != 0, 214 | }; 215 | port.receive_time = data.ports[i].receive_time; 216 | port.next_slave = data.ports[i].next_slave; 217 | port.delay_to_next_dc = data.ports[i].delay_to_next_dc; 218 | } 219 | Ok(SlaveInfo { 220 | name: unsafe { 221 | CStr::from_ptr(data.name.as_ptr()) 222 | .to_string_lossy() 223 | .into_owned() 224 | }, 225 | ring_pos: data.position, 226 | id: SlaveId { 227 | vendor_id: data.vendor_id, 228 | product_code: data.product_code, 229 | }, 230 | rev: SlaveRev { 231 | revision_number: data.revision_number, 232 | serial_number: data.serial_number, 233 | }, 234 | alias: data.alias, 235 | current_on_ebus: data.current_on_ebus, 236 | al_state: AlState::try_from(data.al_state) 237 | .map_err(|_| Error::InvalidAlState(data.al_state))?, 238 | error_flag: data.error_flag, 239 | sync_count: data.sync_count, 240 | sdo_count: data.sdo_count, 241 | ports, 242 | }) 243 | } 244 | 245 | pub fn get_config_info(&self, idx: SlaveConfigIdx) -> Result { 246 | let mut data = ec::ec_ioctl_config_t::default(); 247 | data.config_index = idx; 248 | ioctl!(self, ec::ioctl::CONFIG, &mut data)?; 249 | let id = SlaveId { 250 | vendor_id: data.vendor_id, 251 | product_code: data.product_code, 252 | }; 253 | let slave_position = if data.slave_position == -1 { 254 | None 255 | } else { 256 | Some(SlavePos::from(data.slave_position as u16)) 257 | }; 258 | Ok(ConfigInfo { 259 | alias: data.alias, 260 | position: data.position, 261 | id, 262 | slave_position, 263 | sdo_count: data.sdo_count, 264 | idn_count: data.idn_count, 265 | }) 266 | } 267 | 268 | pub fn configure_slave(&mut self, addr: SlaveAddr, expected: SlaveId) -> Result { 269 | log::debug!("Configure slave {:?}", addr); 270 | let mut data = ec::ec_ioctl_config_t::default(); 271 | let (alias, pos) = addr.as_pair(); 272 | data.alias = alias; 273 | data.position = pos; 274 | data.vendor_id = expected.vendor_id; 275 | data.product_code = expected.product_code; 276 | ioctl!(self, ec::ioctl::CREATE_SLAVE_CONFIG, &mut data)?; 277 | Ok(SlaveConfig { 278 | master: self, 279 | idx: data.config_index, 280 | }) 281 | } 282 | 283 | pub fn get_sdo(&mut self, slave_pos: SlavePos, sdo_pos: SdoPos) -> Result { 284 | let mut sdo = ec::ec_ioctl_slave_sdo_t::default(); 285 | sdo.slave_position = u16::from(slave_pos); 286 | sdo.sdo_position = u16::from(sdo_pos); 287 | ioctl!(self, ec::ioctl::SLAVE_SDO, &mut sdo)?; 288 | #[cfg(feature = "sncn")] 289 | { 290 | Ok(SdoInfo { 291 | pos: SdoPos::from(sdo.sdo_position), 292 | idx: Idx::from(sdo.sdo_index), 293 | max_sub_idx: SubIdx::from(sdo.max_subindex), 294 | object_code: Some(sdo.object_code), 295 | name: c_array_to_string(sdo.name.as_ptr()), 296 | }) 297 | } 298 | #[cfg(not(feature = "sncn"))] 299 | { 300 | Ok(SdoInfo { 301 | pos: SdoPos::from(sdo.sdo_position), 302 | idx: Idx::from(sdo.sdo_index), 303 | max_sub_idx: SubIdx::from(sdo.max_subindex), 304 | object_code: None, 305 | name: convert::c_array_to_string(sdo.name.as_ptr()), 306 | }) 307 | } 308 | } 309 | 310 | pub fn get_sdo_entry( 311 | &mut self, 312 | slave_pos: SlavePos, 313 | addr: SdoEntryAddr, 314 | ) -> Result { 315 | let mut entry = ec::ec_ioctl_slave_sdo_entry_t::default(); 316 | entry.slave_position = u16::from(slave_pos); 317 | let (spec, sub) = match addr { 318 | SdoEntryAddr::ByPos(pos, sub) => (-(u16::from(pos) as i32), sub), 319 | SdoEntryAddr::ByIdx(idx) => (u16::from(idx.idx) as i32, idx.sub_idx), 320 | }; 321 | entry.sdo_spec = spec; 322 | entry.sdo_entry_subindex = u8::from(sub); 323 | ioctl!(self, ec::ioctl::SLAVE_SDO_ENTRY, &mut entry)?; 324 | Ok(SdoEntryInfo { 325 | data_type: DataType::from_u16(entry.data_type).unwrap_or_else(|| { 326 | let fallback = DataType::Raw; 327 | log::warn!( 328 | "Slave {} / SDO {}: Unknown data type (type value: {:X}): use '{:?}' as fallback", 329 | u16::from(slave_pos), 330 | match addr { 331 | SdoEntryAddr::ByPos(pos, sub) => format!("{:?} {:?} ", pos, sub), 332 | SdoEntryAddr::ByIdx(idx) => 333 | format!("{:X}:{}", u16::from(idx.idx), u8::from(idx.sub_idx)), 334 | }, 335 | entry.data_type, 336 | fallback 337 | ); 338 | fallback 339 | }), 340 | bit_len: entry.bit_length, 341 | access: get_sdo_entry_access(entry.read_access, entry.write_access), 342 | description: convert::c_array_to_string(entry.description.as_ptr()), 343 | }) 344 | } 345 | 346 | pub fn sdo_download( 347 | &mut self, 348 | position: SlavePos, 349 | sdo_idx: SdoIdx, 350 | complete_access: bool, 351 | data: &T, 352 | ) -> Result<()> 353 | where 354 | T: SdoData + ?Sized, 355 | { 356 | #[cfg(feature = "sncn")] 357 | let data_ptr = data.data_ptr(); 358 | 359 | #[cfg(not(feature = "sncn"))] 360 | let data_ptr = data.data_ptr() as *mut u8; 361 | 362 | let mut data = ec::ec_ioctl_slave_sdo_download_t { 363 | slave_position: u16::from(position), 364 | sdo_index: u16::from(sdo_idx.idx), 365 | sdo_entry_subindex: u8::from(sdo_idx.sub_idx), 366 | complete_access: if complete_access { 1 } else { 0 }, 367 | data_size: data.data_size(), 368 | data: data_ptr, 369 | abort_code: 0, 370 | }; 371 | ioctl!(self, ec::ioctl::SLAVE_SDO_DOWNLOAD, &mut data).map(|_| ()) 372 | } 373 | 374 | pub fn sdo_upload<'t>( 375 | &self, 376 | position: SlavePos, 377 | sdo_idx: SdoIdx, 378 | #[allow(unused_variables)] complete_access: bool, 379 | target: &'t mut [u8], 380 | ) -> Result<&'t mut [u8]> { 381 | let slave_position = u16::from(position); 382 | let sdo_index = u16::from(sdo_idx.idx); 383 | let sdo_entry_subindex = u8::from(sdo_idx.sub_idx); 384 | let target_size = target.len(); 385 | let data_size = 0; 386 | let abort_code = 0; 387 | 388 | #[cfg(not(feature = "sncn"))] 389 | let mut data = ec::ec_ioctl_slave_sdo_upload_t { 390 | slave_position, 391 | sdo_index, 392 | sdo_entry_subindex, 393 | target_size, 394 | target: target.as_mut_ptr(), 395 | data_size, 396 | abort_code, 397 | }; 398 | 399 | #[cfg(feature = "sncn")] 400 | let mut data = ec::ec_ioctl_slave_sdo_upload_t { 401 | slave_position, 402 | sdo_index, 403 | sdo_entry_subindex, 404 | target_size, 405 | target: target.as_mut_ptr(), 406 | data_size, 407 | abort_code, 408 | complete_access: if complete_access { 1 } else { 0 }, 409 | }; 410 | 411 | ioctl!(self, ec::ioctl::SLAVE_SDO_UPLOAD, &mut data)?; 412 | Ok(&mut target[..data.data_size]) 413 | } 414 | 415 | pub fn get_pdo( 416 | &mut self, 417 | slave_pos: SlavePos, 418 | sync_index: SmIdx, 419 | pdo_position: PdoPos, 420 | ) -> Result { 421 | let mut pdo = ec::ec_ioctl_slave_sync_pdo_t::default(); 422 | pdo.slave_position = u16::from(slave_pos); 423 | pdo.sync_index = u8::from(sync_index) as u32; 424 | pdo.pdo_pos = u8::from(pdo_position) as u32; 425 | ioctl!(self, ec::ioctl::SLAVE_SYNC_PDO, &mut pdo)?; 426 | Ok(PdoInfo { 427 | sm: SmIdx::from(pdo.sync_index as u8), 428 | pos: PdoPos::from(pdo.pdo_pos as u8), 429 | idx: Idx::from(pdo.index), 430 | entry_count: pdo.entry_count, 431 | name: convert::c_array_to_string(pdo.name.as_ptr()), 432 | }) 433 | } 434 | 435 | pub fn get_pdo_entry( 436 | &mut self, 437 | slave_pos: SlavePos, 438 | sync_index: SmIdx, 439 | pdo_pos: PdoPos, 440 | entry_pos: PdoEntryPos, 441 | ) -> Result { 442 | let mut entry = ec::ec_ioctl_slave_sync_pdo_entry_t::default(); 443 | entry.slave_position = u16::from(slave_pos); 444 | entry.sync_index = u8::from(sync_index) as u32; 445 | entry.pdo_pos = u8::from(pdo_pos) as u32; 446 | entry.entry_pos = u8::from(entry_pos) as u32; 447 | ioctl!(self, ec::ioctl::SLAVE_SYNC_PDO_ENTRY, &mut entry)?; 448 | Ok(PdoEntryInfo { 449 | pos: PdoEntryPos::from(entry.pdo_pos as u8), 450 | entry_idx: PdoEntryIdx { 451 | idx: Idx::from(entry.index), 452 | sub_idx: SubIdx::from(entry.subindex), 453 | }, 454 | bit_len: entry.bit_length, 455 | name: convert::c_array_to_string(entry.name.as_ptr()), 456 | }) 457 | } 458 | 459 | pub fn get_sync(&mut self, slave_pos: SlavePos, sm: SmIdx) -> Result { 460 | let mut sync = ec::ec_ioctl_slave_sync_t::default(); 461 | sync.slave_position = u16::from(slave_pos); 462 | sync.sync_index = u8::from(sm) as u32; 463 | ioctl!(self, ec::ioctl::SLAVE_SYNC, &mut sync)?; 464 | Ok(SmInfo { 465 | idx: SmIdx::from(sync.sync_index as u8), 466 | start_addr: sync.physical_start_address, 467 | default_size: sync.default_size, 468 | control_register: sync.control_register, 469 | enable: sync.enable == 1, 470 | pdo_count: sync.pdo_count, 471 | }) 472 | } 473 | 474 | pub fn request_state(&mut self, slave_pos: SlavePos, state: AlState) -> Result<()> { 475 | let mut data = ec::ec_ioctl_slave_state_t::default(); 476 | data.slave_position = u16::from(slave_pos); 477 | data.al_state = state as u8; 478 | ioctl!(self, ec::ioctl::SLAVE_STATE, &data)?; 479 | Ok(()) 480 | } 481 | 482 | #[cfg(feature = "sncn")] 483 | pub fn dict_upload(&mut self, slave_pos: SlavePos) -> Result<()> { 484 | let mut data = ec::ec_ioctl_slave_dict_upload_t::default(); 485 | data.slave_position = u16::from(slave_pos); 486 | ioctl!(self, ec::ioctl::SLAVE_DICT_UPLOAD, &mut data)?; 487 | Ok(()) 488 | } 489 | 490 | pub fn set_application_time(&mut self, app_time: u64) -> Result<()> { 491 | ioctl!(self, ec::ioctl::APP_TIME, &app_time)?; 492 | Ok(()) 493 | } 494 | 495 | pub fn sync_reference_clock(&mut self) -> Result<()> { 496 | ioctl!(self, ec::ioctl::SYNC_REF)?; 497 | Ok(()) 498 | } 499 | 500 | pub fn sync_slave_clocks(&mut self) -> Result<()> { 501 | ioctl!(self, ec::ioctl::SYNC_SLAVES)?; 502 | Ok(()) 503 | } 504 | 505 | pub fn sync_reference_clock_to(&mut self, sync_time: u64) -> Result<()> { 506 | ioctl!(self, ec::ioctl::SYNC_REF_TO, &sync_time)?; 507 | Ok(()) 508 | } 509 | 510 | pub fn sync_monitor_queue(&mut self) -> Result<()> { 511 | ioctl!(self, ec::ioctl::SYNC_MON_QUEUE)?; 512 | Ok(()) 513 | } 514 | 515 | pub fn sync_monitor_process(&mut self) -> Result { 516 | let mut time = 0; 517 | ioctl!(self, ec::ioctl::SYNC_MON_PROCESS, &mut time)?; 518 | Ok(time) 519 | } 520 | 521 | pub fn get_reference_clock_time(&mut self) -> Result { 522 | let mut time = 0; 523 | ioctl!(self, ec::ioctl::REF_CLOCK_TIME, &mut time)?; 524 | Ok(time) 525 | } 526 | 527 | pub fn foe_read(&mut self, idx: SlavePos, name: &str) -> Result> { 528 | let file_name = convert::string_to_foe_name(name)?; 529 | // FIXME: this is the same as in the c-implementation. Should read in chunks instead of a 530 | // fixed size buffer. The ioctl-call in the master pre-allocates a 10000 byte buffer, so we 531 | // do the same here. 532 | const FOE_SIZE: usize = 10_000; 533 | let mut buf: Vec = vec![0; FOE_SIZE]; 534 | let mut data = ec::ec_ioctl_slave_foe_t { 535 | slave_position: idx.into(), 536 | offset: 0, 537 | buffer_size: FOE_SIZE, 538 | buffer: buf.as_mut_ptr(), 539 | file_name, 540 | ..Default::default() 541 | }; 542 | ioctl!(self, ec::ioctl::SLAVE_FOE_READ, &mut data)?; 543 | 544 | assert!(data.data_size <= FOE_SIZE); 545 | buf.truncate(data.data_size); 546 | Ok(buf) 547 | } 548 | 549 | pub fn foe_write(&mut self, idx: SlavePos, name: &str, data: &[u8]) -> Result<()> { 550 | let file_name = convert::string_to_foe_name(name)?; 551 | 552 | let buffer = data.as_ptr() as *mut _; 553 | let data = ec::ec_ioctl_slave_foe_t { 554 | slave_position: idx.into(), 555 | offset: 0, 556 | buffer_size: data.len(), 557 | buffer, 558 | file_name, 559 | ..Default::default() 560 | }; 561 | ioctl!(self, ec::ioctl::SLAVE_FOE_WRITE, &data)?; 562 | 563 | Ok(()) 564 | } 565 | 566 | // XXX missing: write_idn, read_idn 567 | } 568 | 569 | pub struct SlaveConfig<'m> { 570 | master: &'m Master, 571 | idx: SlaveConfigIdx, 572 | } 573 | 574 | impl<'m> SlaveConfig<'m> { 575 | pub const fn index(&self) -> SlaveConfigIdx { 576 | self.idx 577 | } 578 | 579 | pub fn state(&self) -> Result { 580 | let mut state = ec::ec_slave_config_state_t::default(); 581 | let mut data = ec::ec_ioctl_sc_state_t { 582 | config_index: self.idx, 583 | state: &mut state, 584 | }; 585 | ioctl!(self.master, ec::ioctl::SC_STATE, &mut data)?; 586 | let al_state_u8 = state.al_state() as u8; 587 | Ok(SlaveConfigState { 588 | online: state.online() != 0, 589 | operational: state.operational() != 0, 590 | al_state: AlState::try_from(al_state_u8) 591 | .map_err(|_| Error::InvalidAlState(al_state_u8))?, 592 | }) 593 | } 594 | 595 | /// Configure PDOs of a specifc Sync Manager 596 | pub fn config_sm_pdos(&mut self, sm_cfg: SmCfg, pdo_cfgs: &[PdoCfg]) -> Result<()> { 597 | self.config_sync_manager(&sm_cfg)?; 598 | self.clear_pdo_assignments(sm_cfg.idx)?; 599 | for pdo_cfg in pdo_cfgs { 600 | self.add_pdo_assignment(sm_cfg.idx, pdo_cfg.idx)?; 601 | if !pdo_cfg.entries.is_empty() { 602 | self.clear_pdo_mapping(pdo_cfg.idx)?; 603 | for entry in &pdo_cfg.entries { 604 | self.add_pdo_mapping(pdo_cfg.idx, entry)?; 605 | } 606 | } 607 | } 608 | Ok(()) 609 | } 610 | 611 | pub fn config_watchdog(&mut self, divider: u16, intervals: u16) -> Result<()> { 612 | let mut data = ec::ec_ioctl_config_t::default(); 613 | data.config_index = self.idx; 614 | data.watchdog_divider = divider; 615 | data.watchdog_intervals = intervals; 616 | ioctl!(self.master, ec::ioctl::SC_WATCHDOG, &data).map(|_| ()) 617 | } 618 | 619 | #[cfg(feature = "sncn")] 620 | pub fn config_overlapping_pdos(&mut self, allow: bool) -> Result<()> { 621 | let mut data = ec::ec_ioctl_config_t::default(); 622 | data.config_index = self.idx; 623 | data.allow_overlapping_pdos = allow as u8; 624 | ioctl!(self.master, ec::ioctl::SC_OVERLAPPING_IO, &data).map(|_| ()) 625 | } 626 | 627 | pub fn config_sync_manager(&mut self, cfg: &SmCfg) -> Result<()> { 628 | log::debug!("Configure Sync Manager: {:?}", cfg); 629 | if u8::from(cfg.idx) >= ec::EC_MAX_SYNC_MANAGERS as u8 { 630 | return Err(Error::SmIdxTooLarge); 631 | } 632 | let mut data = ec::ec_ioctl_config_t::default(); 633 | data.config_index = self.idx; 634 | let ix = u8::from(cfg.idx) as usize; 635 | data.syncs[ix].dir = cfg.direction as u32; 636 | data.syncs[ix].watchdog_mode = cfg.watchdog_mode as u32; 637 | data.syncs[ix].config_this = 1; 638 | ioctl!(self.master, ec::ioctl::SC_SYNC, &data).map(|_| ()) 639 | } 640 | 641 | pub fn clear_pdo_assignments(&mut self, sync_idx: SmIdx) -> Result<()> { 642 | let mut data = ec::ec_ioctl_config_pdo_t::default(); 643 | data.config_index = self.idx; 644 | data.sync_index = u8::from(sync_idx); 645 | ioctl!(self.master, ec::ioctl::SC_CLEAR_PDOS, &data).map(|_| ()) 646 | } 647 | 648 | pub fn add_pdo_assignment(&mut self, sync_idx: SmIdx, pdo_idx: PdoIdx) -> Result<()> { 649 | let mut data = ec::ec_ioctl_config_pdo_t::default(); 650 | data.config_index = self.idx; 651 | data.sync_index = u8::from(sync_idx); 652 | data.index = u16::from(pdo_idx); 653 | ioctl!(self.master, ec::ioctl::SC_ADD_PDO, &data).map(|_| ()) 654 | } 655 | 656 | pub fn clear_pdo_mapping(&mut self, pdo_idx: PdoIdx) -> Result<()> { 657 | let mut data = ec::ec_ioctl_config_pdo_t::default(); 658 | data.config_index = self.idx; 659 | data.index = u16::from(pdo_idx); 660 | ioctl!(self.master, ec::ioctl::SC_CLEAR_ENTRIES, &data).map(|_| ()) 661 | } 662 | 663 | pub fn add_pdo_mapping(&mut self, pdo_index: PdoIdx, entry: &PdoEntryInfo) -> Result<()> { 664 | let data = ec::ec_ioctl_add_pdo_entry_t { 665 | config_index: self.idx, 666 | pdo_index: u16::from(pdo_index), 667 | entry_index: u16::from(entry.entry_idx.idx), 668 | entry_subindex: u8::from(entry.entry_idx.sub_idx), 669 | entry_bit_length: entry.bit_len, 670 | }; 671 | ioctl!(self.master, ec::ioctl::SC_ADD_ENTRY, &data).map(|_| ()) 672 | } 673 | 674 | pub fn register_pdo_entry(&mut self, index: PdoEntryIdx, domain: DomainIdx) -> Result { 675 | let mut data = ec::ec_ioctl_reg_pdo_entry_t { 676 | config_index: self.idx, 677 | entry_index: u16::from(index.idx), 678 | entry_subindex: u8::from(index.sub_idx), 679 | domain_index: u32::try_from(domain) 680 | .map_err(|_| Error::DomainIdx(usize::from(domain)))?, 681 | bit_position: 0, 682 | }; 683 | let byte = ioctl!(self.master, ec::ioctl::SC_REG_PDO_ENTRY, &mut data)?; 684 | Ok(Offset { 685 | byte: byte as usize, 686 | bit: data.bit_position, 687 | }) 688 | } 689 | 690 | pub fn register_pdo_entry_by_position( 691 | &mut self, 692 | sync_index: SmIdx, 693 | pdo_pos: u32, 694 | entry_pos: u32, 695 | domain: DomainIdx, 696 | ) -> Result { 697 | let mut data = ec::ec_ioctl_reg_pdo_pos_t { 698 | config_index: self.idx, 699 | sync_index: u8::from(sync_index) as u32, 700 | pdo_pos, 701 | entry_pos, 702 | domain_index: u32::try_from(domain) 703 | .map_err(|_| Error::DomainIdx(usize::from(domain)))?, 704 | bit_position: 0, 705 | }; 706 | let byte = ioctl!(self.master, ec::ioctl::SC_REG_PDO_POS, &mut data)?; 707 | Ok(Offset { 708 | byte: byte as usize, 709 | bit: data.bit_position, 710 | }) 711 | } 712 | 713 | pub fn config_dc( 714 | &mut self, 715 | assign_activate: u16, 716 | sync0_cycle_time: u32, 717 | sync0_shift_time: i32, 718 | sync1_cycle_time: u32, 719 | sync1_shift_time: i32, 720 | ) -> Result<()> { 721 | let mut data = ec::ec_ioctl_config_t::default(); 722 | data.config_index = self.idx; 723 | data.dc_assign_activate = assign_activate; 724 | data.dc_sync[0].cycle_time = sync0_cycle_time; 725 | data.dc_sync[0].shift_time = sync0_shift_time; 726 | data.dc_sync[1].cycle_time = sync1_cycle_time; 727 | data.dc_sync[1].shift_time = sync1_shift_time; 728 | ioctl!(self.master, ec::ioctl::SC_DC, &data).map(|_| ()) 729 | } 730 | 731 | pub fn add_sdo(&mut self, index: SdoIdx, data: &T) -> Result<()> 732 | where 733 | T: SdoData + ?Sized, 734 | { 735 | let data = ec::ec_ioctl_sc_sdo_t { 736 | config_index: self.idx, 737 | index: u16::from(index.idx), 738 | subindex: u8::from(index.sub_idx), 739 | data: data.data_ptr(), 740 | size: data.data_size(), 741 | complete_access: 0, 742 | }; 743 | ioctl!(self.master, ec::ioctl::SC_SDO, &data).map(|_| ()) 744 | } 745 | 746 | pub fn add_complete_sdo(&mut self, index: SdoIdx, data: &[u8]) -> Result<()> { 747 | let data = ec::ec_ioctl_sc_sdo_t { 748 | config_index: self.idx, 749 | index: u16::from(index.idx), 750 | subindex: u8::from(index.sub_idx), 751 | data: data.as_ptr(), 752 | size: data.len(), 753 | complete_access: 1, 754 | }; 755 | ioctl!(self.master, ec::ioctl::SC_SDO, &data).map(|_| ()) 756 | } 757 | 758 | pub fn config_idn( 759 | &mut self, 760 | drive_no: u8, 761 | idn: u16, 762 | al_state: AlState, 763 | data: &[u8], 764 | ) -> Result<()> { 765 | let data = ec::ec_ioctl_sc_idn_t { 766 | config_index: self.idx, 767 | drive_no, 768 | idn, 769 | al_state: al_state as u32, 770 | data: data.as_ptr(), 771 | size: data.len(), 772 | }; 773 | ioctl!(self.master, ec::ioctl::SC_IDN, &data).map(|_| ()) 774 | } 775 | 776 | pub fn set_emerg_size(&mut self, elements: u64) -> Result<()> { 777 | let mut data = ec::ec_ioctl_sc_emerg_t::default(); 778 | data.config_index = self.idx; 779 | data.size = elements as usize; 780 | ioctl!(self.master, ec::ioctl::SC_EMERG_SIZE, &data).map(|_| ()) 781 | } 782 | 783 | pub fn pop_emerg(&mut self, target: &mut [u8]) -> Result<()> { 784 | let mut data = ec::ec_ioctl_sc_emerg_t::default(); 785 | data.config_index = self.idx; 786 | data.target = target.as_mut_ptr(); 787 | ioctl!(self.master, ec::ioctl::SC_EMERG_POP, &mut data).map(|_| ()) 788 | } 789 | 790 | pub fn clear_emerg(&mut self) -> Result<()> { 791 | let mut data = ec::ec_ioctl_sc_emerg_t::default(); 792 | data.config_index = self.idx; 793 | ioctl!(self.master, ec::ioctl::SC_EMERG_CLEAR, &data).map(|_| ()) 794 | } 795 | 796 | pub fn emerg_overruns(&mut self) -> Result { 797 | let mut data = ec::ec_ioctl_sc_emerg_t::default(); 798 | data.config_index = self.idx; 799 | ioctl!(self.master, ec::ioctl::SC_EMERG_OVERRUNS, &mut data)?; 800 | Ok(data.overruns) 801 | } 802 | 803 | // XXX missing: create_sdo_request, create_reg_request, create_voe_handler 804 | } 805 | 806 | impl<'m> Domain<'m> { 807 | pub const fn new(idx: DomainIdx, master: &'m Master) -> Self { 808 | Self { idx, master } 809 | } 810 | 811 | pub fn size(&self) -> Result { 812 | ioctl!( 813 | self.master, 814 | ec::ioctl::DOMAIN_SIZE, 815 | c_ulong::try_from(self.idx).map_err(|_| Error::DomainIdx(usize::from(self.idx)))? 816 | ) 817 | .map(|v| v as usize) 818 | } 819 | 820 | pub fn state(&self) -> Result { 821 | let mut state = ec::ec_domain_state_t::default(); 822 | let mut data = ec::ec_ioctl_domain_state_t { 823 | domain_index: u32::try_from(self.idx) 824 | .map_err(|_| Error::DomainIdx(usize::from(self.idx)))?, 825 | state: &mut state, 826 | }; 827 | ioctl!(self.master, ec::ioctl::DOMAIN_STATE, &mut data)?; 828 | Ok(DomainState { 829 | working_counter: state.working_counter, 830 | redundancy_active: state.redundancy_active != 0, 831 | wc_state: WcState::from(state.wc_state), 832 | }) 833 | } 834 | 835 | pub fn process(&mut self) -> Result<()> { 836 | ioctl!( 837 | self.master, 838 | ec::ioctl::DOMAIN_PROCESS, 839 | usize::from(self.idx) as c_ulong 840 | ) 841 | .map(|_| ()) 842 | } 843 | 844 | pub fn queue(&mut self) -> Result<()> { 845 | ioctl!( 846 | self.master, 847 | ec::ioctl::DOMAIN_QUEUE, 848 | c_ulong::try_from(self.idx).map_err(|_| Error::DomainIdx(usize::from(self.idx)))? 849 | ) 850 | .map(|_| ()) 851 | } 852 | } 853 | -------------------------------------------------------------------------------- /ethercat-sys/src/bindings-v1.5.2-sncn-11.rs: -------------------------------------------------------------------------------- 1 | /* automatically generated by rust-bindgen 0.55.1 */ 2 | 3 | #[repr(C)] 4 | #[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] 5 | pub struct __BindgenBitfieldUnit { 6 | storage: Storage, 7 | align: [Align; 0], 8 | } 9 | impl __BindgenBitfieldUnit { 10 | #[inline] 11 | pub const fn new(storage: Storage) -> Self { 12 | Self { storage, align: [] } 13 | } 14 | } 15 | impl __BindgenBitfieldUnit 16 | where 17 | Storage: AsRef<[u8]> + AsMut<[u8]>, 18 | { 19 | #[inline] 20 | pub fn get_bit(&self, index: usize) -> bool { 21 | debug_assert!(index / 8 < self.storage.as_ref().len()); 22 | let byte_index = index / 8; 23 | let byte = self.storage.as_ref()[byte_index]; 24 | let bit_index = if cfg!(target_endian = "big") { 25 | 7 - (index % 8) 26 | } else { 27 | index % 8 28 | }; 29 | let mask = 1 << bit_index; 30 | byte & mask == mask 31 | } 32 | #[inline] 33 | pub fn set_bit(&mut self, index: usize, val: bool) { 34 | debug_assert!(index / 8 < self.storage.as_ref().len()); 35 | let byte_index = index / 8; 36 | let byte = &mut self.storage.as_mut()[byte_index]; 37 | let bit_index = if cfg!(target_endian = "big") { 38 | 7 - (index % 8) 39 | } else { 40 | index % 8 41 | }; 42 | let mask = 1 << bit_index; 43 | if val { 44 | *byte |= mask; 45 | } else { 46 | *byte &= !mask; 47 | } 48 | } 49 | #[inline] 50 | pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { 51 | debug_assert!(bit_width <= 64); 52 | debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); 53 | debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); 54 | let mut val = 0; 55 | for i in 0..(bit_width as usize) { 56 | if self.get_bit(i + bit_offset) { 57 | let index = if cfg!(target_endian = "big") { 58 | bit_width as usize - 1 - i 59 | } else { 60 | i 61 | }; 62 | val |= 1 << index; 63 | } 64 | } 65 | val 66 | } 67 | #[inline] 68 | pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { 69 | debug_assert!(bit_width <= 64); 70 | debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); 71 | debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); 72 | for i in 0..(bit_width as usize) { 73 | let mask = 1 << i; 74 | let val_bit_is_set = val & mask == mask; 75 | let index = if cfg!(target_endian = "big") { 76 | bit_width as usize - 1 - i 77 | } else { 78 | i 79 | }; 80 | self.set_bit(index + bit_offset, val_bit_is_set); 81 | } 82 | } 83 | } 84 | pub const EC_MAX_NUM_DEVICES: u32 = 1; 85 | pub const EC_MAX_SYNC_MANAGERS: u32 = 16; 86 | pub const EC_MAX_STRING_LENGTH: u32 = 64; 87 | pub const EC_MAX_PORTS: u32 = 4; 88 | pub const EC_MAX_SII_SIZE: u32 = 4096; 89 | pub const EC_MAX_FMMUS: u32 = 16; 90 | pub const EC_MAX_HOSTNAME_SIZE: u32 = 32; 91 | pub const EC_IOCTL_TYPE: u32 = 164; 92 | pub const EC_IOCTL_VERSION_MAGIC: u32 = 36; 93 | pub const EC_IOCTL_STRING_SIZE: u32 = 64; 94 | pub const EC_MAX_SDO_DATA_SIZE: u32 = 1024; 95 | pub const EC_MAX_IDN_DATA_SIZE: u32 = 1024; 96 | pub type size_t = ::std::os::raw::c_ulong; 97 | pub type __int8_t = ::std::os::raw::c_schar; 98 | pub type __uint8_t = ::std::os::raw::c_uchar; 99 | pub type __int16_t = ::std::os::raw::c_short; 100 | pub type __uint16_t = ::std::os::raw::c_ushort; 101 | pub type __int32_t = ::std::os::raw::c_int; 102 | pub type __uint32_t = ::std::os::raw::c_uint; 103 | pub type __uint64_t = ::std::os::raw::c_ulong; 104 | #[doc = " Master state."] 105 | #[doc = ""] 106 | #[doc = " This is used for the output parameter of ecrt_master_state()."] 107 | #[doc = ""] 108 | #[doc = " \\see ecrt_master_state()."] 109 | #[repr(C)] 110 | #[derive(Default, Copy, Clone)] 111 | pub struct ec_master_state_t { 112 | #[doc = "< Sum of responding slaves on all"] 113 | #[doc = "Ethernet devices."] 114 | pub slaves_responding: ::std::os::raw::c_uint, 115 | pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize], u8>, 116 | pub __bindgen_padding_0: [u8; 3usize], 117 | } 118 | impl ec_master_state_t { 119 | #[inline] 120 | pub fn al_states(&self) -> ::std::os::raw::c_uint { 121 | unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 4u8) as u32) } 122 | } 123 | #[inline] 124 | pub fn set_al_states(&mut self, val: ::std::os::raw::c_uint) { 125 | unsafe { 126 | let val: u32 = ::std::mem::transmute(val); 127 | self._bitfield_1.set(0usize, 4u8, val as u64) 128 | } 129 | } 130 | #[inline] 131 | pub fn link_up(&self) -> ::std::os::raw::c_uint { 132 | unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 1u8) as u32) } 133 | } 134 | #[inline] 135 | pub fn set_link_up(&mut self, val: ::std::os::raw::c_uint) { 136 | unsafe { 137 | let val: u32 = ::std::mem::transmute(val); 138 | self._bitfield_1.set(4usize, 1u8, val as u64) 139 | } 140 | } 141 | #[inline] 142 | pub fn scan_busy(&self) -> ::std::os::raw::c_uint { 143 | unsafe { ::std::mem::transmute(self._bitfield_1.get(5usize, 1u8) as u32) } 144 | } 145 | #[inline] 146 | pub fn set_scan_busy(&mut self, val: ::std::os::raw::c_uint) { 147 | unsafe { 148 | let val: u32 = ::std::mem::transmute(val); 149 | self._bitfield_1.set(5usize, 1u8, val as u64) 150 | } 151 | } 152 | #[inline] 153 | pub fn new_bitfield_1( 154 | al_states: ::std::os::raw::c_uint, 155 | link_up: ::std::os::raw::c_uint, 156 | scan_busy: ::std::os::raw::c_uint, 157 | ) -> __BindgenBitfieldUnit<[u8; 1usize], u8> { 158 | let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize], u8> = 159 | Default::default(); 160 | __bindgen_bitfield_unit.set(0usize, 4u8, { 161 | let al_states: u32 = unsafe { ::std::mem::transmute(al_states) }; 162 | al_states as u64 163 | }); 164 | __bindgen_bitfield_unit.set(4usize, 1u8, { 165 | let link_up: u32 = unsafe { ::std::mem::transmute(link_up) }; 166 | link_up as u64 167 | }); 168 | __bindgen_bitfield_unit.set(5usize, 1u8, { 169 | let scan_busy: u32 = unsafe { ::std::mem::transmute(scan_busy) }; 170 | scan_busy as u64 171 | }); 172 | __bindgen_bitfield_unit 173 | } 174 | } 175 | #[doc = " Redundant link state."] 176 | #[doc = ""] 177 | #[doc = " This is used for the output parameter of ecrt_master_link_state()."] 178 | #[doc = ""] 179 | #[doc = " \\see ecrt_master_link_state()."] 180 | #[repr(C)] 181 | #[derive(Default, Copy, Clone)] 182 | pub struct ec_master_link_state_t { 183 | #[doc = "< Sum of responding slaves on the given"] 184 | #[doc = "link."] 185 | pub slaves_responding: ::std::os::raw::c_uint, 186 | pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize], u8>, 187 | pub __bindgen_padding_0: [u8; 3usize], 188 | } 189 | impl ec_master_link_state_t { 190 | #[inline] 191 | pub fn al_states(&self) -> ::std::os::raw::c_uint { 192 | unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 4u8) as u32) } 193 | } 194 | #[inline] 195 | pub fn set_al_states(&mut self, val: ::std::os::raw::c_uint) { 196 | unsafe { 197 | let val: u32 = ::std::mem::transmute(val); 198 | self._bitfield_1.set(0usize, 4u8, val as u64) 199 | } 200 | } 201 | #[inline] 202 | pub fn link_up(&self) -> ::std::os::raw::c_uint { 203 | unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 1u8) as u32) } 204 | } 205 | #[inline] 206 | pub fn set_link_up(&mut self, val: ::std::os::raw::c_uint) { 207 | unsafe { 208 | let val: u32 = ::std::mem::transmute(val); 209 | self._bitfield_1.set(4usize, 1u8, val as u64) 210 | } 211 | } 212 | #[inline] 213 | pub fn new_bitfield_1( 214 | al_states: ::std::os::raw::c_uint, 215 | link_up: ::std::os::raw::c_uint, 216 | ) -> __BindgenBitfieldUnit<[u8; 1usize], u8> { 217 | let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize], u8> = 218 | Default::default(); 219 | __bindgen_bitfield_unit.set(0usize, 4u8, { 220 | let al_states: u32 = unsafe { ::std::mem::transmute(al_states) }; 221 | al_states as u64 222 | }); 223 | __bindgen_bitfield_unit.set(4usize, 1u8, { 224 | let link_up: u32 = unsafe { ::std::mem::transmute(link_up) }; 225 | link_up as u64 226 | }); 227 | __bindgen_bitfield_unit 228 | } 229 | } 230 | #[doc = " Slave configuration state."] 231 | #[doc = ""] 232 | #[doc = " This is used as an output parameter of ecrt_slave_config_state()."] 233 | #[doc = ""] 234 | #[doc = " \\see ecrt_slave_config_state()."] 235 | #[repr(C)] 236 | #[repr(align(4))] 237 | #[derive(Default, Copy, Clone)] 238 | pub struct ec_slave_config_state_t { 239 | pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize], u8>, 240 | #[doc = "< Offset of the slave in the ring."] 241 | pub position: u16, 242 | } 243 | impl ec_slave_config_state_t { 244 | #[inline] 245 | pub fn online(&self) -> ::std::os::raw::c_uint { 246 | unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } 247 | } 248 | #[inline] 249 | pub fn set_online(&mut self, val: ::std::os::raw::c_uint) { 250 | unsafe { 251 | let val: u32 = ::std::mem::transmute(val); 252 | self._bitfield_1.set(0usize, 1u8, val as u64) 253 | } 254 | } 255 | #[inline] 256 | pub fn operational(&self) -> ::std::os::raw::c_uint { 257 | unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) } 258 | } 259 | #[inline] 260 | pub fn set_operational(&mut self, val: ::std::os::raw::c_uint) { 261 | unsafe { 262 | let val: u32 = ::std::mem::transmute(val); 263 | self._bitfield_1.set(1usize, 1u8, val as u64) 264 | } 265 | } 266 | #[inline] 267 | pub fn al_state(&self) -> ::std::os::raw::c_uint { 268 | unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 4u8) as u32) } 269 | } 270 | #[inline] 271 | pub fn set_al_state(&mut self, val: ::std::os::raw::c_uint) { 272 | unsafe { 273 | let val: u32 = ::std::mem::transmute(val); 274 | self._bitfield_1.set(2usize, 4u8, val as u64) 275 | } 276 | } 277 | #[inline] 278 | pub fn error_flag(&self) -> ::std::os::raw::c_uint { 279 | unsafe { ::std::mem::transmute(self._bitfield_1.get(6usize, 1u8) as u32) } 280 | } 281 | #[inline] 282 | pub fn set_error_flag(&mut self, val: ::std::os::raw::c_uint) { 283 | unsafe { 284 | let val: u32 = ::std::mem::transmute(val); 285 | self._bitfield_1.set(6usize, 1u8, val as u64) 286 | } 287 | } 288 | #[inline] 289 | pub fn ready(&self) -> ::std::os::raw::c_uint { 290 | unsafe { ::std::mem::transmute(self._bitfield_1.get(7usize, 1u8) as u32) } 291 | } 292 | #[inline] 293 | pub fn set_ready(&mut self, val: ::std::os::raw::c_uint) { 294 | unsafe { 295 | let val: u32 = ::std::mem::transmute(val); 296 | self._bitfield_1.set(7usize, 1u8, val as u64) 297 | } 298 | } 299 | #[inline] 300 | pub fn new_bitfield_1( 301 | online: ::std::os::raw::c_uint, 302 | operational: ::std::os::raw::c_uint, 303 | al_state: ::std::os::raw::c_uint, 304 | error_flag: ::std::os::raw::c_uint, 305 | ready: ::std::os::raw::c_uint, 306 | ) -> __BindgenBitfieldUnit<[u8; 1usize], u8> { 307 | let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize], u8> = 308 | Default::default(); 309 | __bindgen_bitfield_unit.set(0usize, 1u8, { 310 | let online: u32 = unsafe { ::std::mem::transmute(online) }; 311 | online as u64 312 | }); 313 | __bindgen_bitfield_unit.set(1usize, 1u8, { 314 | let operational: u32 = unsafe { ::std::mem::transmute(operational) }; 315 | operational as u64 316 | }); 317 | __bindgen_bitfield_unit.set(2usize, 4u8, { 318 | let al_state: u32 = unsafe { ::std::mem::transmute(al_state) }; 319 | al_state as u64 320 | }); 321 | __bindgen_bitfield_unit.set(6usize, 1u8, { 322 | let error_flag: u32 = unsafe { ::std::mem::transmute(error_flag) }; 323 | error_flag as u64 324 | }); 325 | __bindgen_bitfield_unit.set(7usize, 1u8, { 326 | let ready: u32 = unsafe { ::std::mem::transmute(ready) }; 327 | ready as u64 328 | }); 329 | __bindgen_bitfield_unit 330 | } 331 | } 332 | #[doc = "< Port is not implemented."] 333 | pub const EC_PORT_NOT_IMPLEMENTED: ec_slave_port_desc_t = 0; 334 | #[doc = "< Port is not configured."] 335 | pub const EC_PORT_NOT_CONFIGURED: ec_slave_port_desc_t = 1; 336 | #[doc = "< Port is an E-Bus."] 337 | pub const EC_PORT_EBUS: ec_slave_port_desc_t = 2; 338 | #[doc = "< Port is a MII."] 339 | pub const EC_PORT_MII: ec_slave_port_desc_t = 3; 340 | #[doc = " EtherCAT slave port descriptor."] 341 | pub type ec_slave_port_desc_t = ::std::os::raw::c_uint; 342 | #[doc = " EtherCAT slave port information."] 343 | #[repr(C)] 344 | #[derive(Default, Copy, Clone)] 345 | pub struct ec_slave_port_link_t { 346 | #[doc = "< Link detected."] 347 | pub link_up: u8, 348 | #[doc = "< Loop closed."] 349 | pub loop_closed: u8, 350 | #[doc = "< Detected signal on RX port."] 351 | pub signal_detected: u8, 352 | #[doc = "< Packets are bypassing this port (eg. redundancy)"] 353 | pub bypassed: u8, 354 | } 355 | #[doc = "< No registered process data were exchanged."] 356 | pub const EC_WC_ZERO: ec_wc_state_t = 0; 357 | #[doc = "< Some of the registered process data were"] 358 | #[doc = "exchanged."] 359 | pub const EC_WC_INCOMPLETE: ec_wc_state_t = 1; 360 | #[doc = "< All registered process data were exchanged."] 361 | pub const EC_WC_COMPLETE: ec_wc_state_t = 2; 362 | #[doc = " Domain working counter interpretation."] 363 | #[doc = ""] 364 | #[doc = " This is used in ec_domain_state_t."] 365 | pub type ec_wc_state_t = ::std::os::raw::c_uint; 366 | #[doc = " Domain state."] 367 | #[doc = ""] 368 | #[doc = " This is used for the output parameter of ecrt_domain_state()."] 369 | #[repr(C)] 370 | #[derive(Copy, Clone)] 371 | pub struct ec_domain_state_t { 372 | #[doc = "< Value of the last working counter."] 373 | pub working_counter: ::std::os::raw::c_uint, 374 | #[doc = "< Working counter interpretation."] 375 | pub wc_state: ec_wc_state_t, 376 | #[doc = "< Redundant link is in use."] 377 | pub redundancy_active: ::std::os::raw::c_uint, 378 | } 379 | impl Default for ec_domain_state_t { 380 | fn default() -> Self { 381 | unsafe { ::std::mem::zeroed() } 382 | } 383 | } 384 | #[doc = "< Invalid direction. Do not use this value."] 385 | pub const EC_DIR_INVALID: ec_direction_t = 0; 386 | #[doc = "< Values written by the master."] 387 | pub const EC_DIR_OUTPUT: ec_direction_t = 1; 388 | #[doc = "< Values read by the master."] 389 | pub const EC_DIR_INPUT: ec_direction_t = 2; 390 | #[doc = "< Values read and written by the master."] 391 | pub const EC_DIR_BOTH: ec_direction_t = 3; 392 | #[doc = "< Number of directions. For internal use only."] 393 | pub const EC_DIR_COUNT: ec_direction_t = 4; 394 | #[doc = " Direction type for PDO assignment functions."] 395 | pub type ec_direction_t = ::std::os::raw::c_uint; 396 | #[doc = "< Use the default setting of the sync manager."] 397 | pub const EC_WD_DEFAULT: ec_watchdog_mode_t = 0; 398 | #[doc = "< Enable the watchdog."] 399 | pub const EC_WD_ENABLE: ec_watchdog_mode_t = 1; 400 | #[doc = "< Disable the watchdog."] 401 | pub const EC_WD_DISABLE: ec_watchdog_mode_t = 2; 402 | #[doc = " Watchdog mode for sync manager configuration."] 403 | #[doc = ""] 404 | #[doc = " Used to specify, if a sync manager's watchdog is to be enabled."] 405 | pub type ec_watchdog_mode_t = ::std::os::raw::c_uint; 406 | #[doc = "< Not requested."] 407 | pub const EC_REQUEST_UNUSED: ec_request_state_t = 0; 408 | #[doc = "< Request is being processed."] 409 | pub const EC_REQUEST_BUSY: ec_request_state_t = 1; 410 | #[doc = "< Request was processed successfully."] 411 | pub const EC_REQUEST_SUCCESS: ec_request_state_t = 2; 412 | #[doc = "< Request processing failed."] 413 | pub const EC_REQUEST_ERROR: ec_request_state_t = 3; 414 | #[doc = " Request state."] 415 | #[doc = ""] 416 | #[doc = " This is used as return type for ecrt_sdo_request_state() and"] 417 | #[doc = " ecrt_voe_handler_state()."] 418 | pub type ec_request_state_t = ::std::os::raw::c_uint; 419 | #[doc = "< Busy."] 420 | pub const FOE_BUSY: ec_foe_error_t = 0; 421 | #[doc = "< Ready."] 422 | pub const FOE_READY: ec_foe_error_t = 1; 423 | #[doc = "< Idle."] 424 | pub const FOE_IDLE: ec_foe_error_t = 2; 425 | #[doc = "< Working counter error."] 426 | pub const FOE_WC_ERROR: ec_foe_error_t = 3; 427 | #[doc = "< Receive error."] 428 | pub const FOE_RECEIVE_ERROR: ec_foe_error_t = 4; 429 | #[doc = "< Protocol error."] 430 | pub const FOE_PROT_ERROR: ec_foe_error_t = 5; 431 | #[doc = "< No data error."] 432 | pub const FOE_NODATA_ERROR: ec_foe_error_t = 6; 433 | #[doc = "< Packet number error."] 434 | pub const FOE_PACKETNO_ERROR: ec_foe_error_t = 7; 435 | #[doc = "< OpCode error."] 436 | pub const FOE_OPCODE_ERROR: ec_foe_error_t = 8; 437 | #[doc = "< Timeout error."] 438 | pub const FOE_TIMEOUT_ERROR: ec_foe_error_t = 9; 439 | #[doc = "< Error sending received data."] 440 | pub const FOE_SEND_RX_DATA_ERROR: ec_foe_error_t = 10; 441 | #[doc = "< Error acknowledging received data."] 442 | pub const FOE_RX_DATA_ACK_ERROR: ec_foe_error_t = 11; 443 | #[doc = "< Acknowledge error."] 444 | pub const FOE_ACK_ERROR: ec_foe_error_t = 12; 445 | #[doc = "< Error fetching data from mailbox."] 446 | pub const FOE_MBOX_FETCH_ERROR: ec_foe_error_t = 13; 447 | #[doc = "< No data while reading."] 448 | pub const FOE_READ_NODATA_ERROR: ec_foe_error_t = 14; 449 | #[doc = "< Mailbox protocol error."] 450 | pub const FOE_MBOX_PROT_ERROR: ec_foe_error_t = 15; 451 | #[doc = "< Read buffer overflow."] 452 | pub const FOE_READ_OVER_ERROR: ec_foe_error_t = 16; 453 | #[doc = " FoE error enumeration type."] 454 | pub type ec_foe_error_t = ::std::os::raw::c_uint; 455 | #[doc = "< Init."] 456 | pub const EC_AL_STATE_INIT: ec_al_state_t = 1; 457 | #[doc = "< Pre-operational."] 458 | pub const EC_AL_STATE_PREOP: ec_al_state_t = 2; 459 | #[doc = "< Safe-operational."] 460 | pub const EC_AL_STATE_SAFEOP: ec_al_state_t = 4; 461 | #[doc = "< Operational."] 462 | pub const EC_AL_STATE_OP: ec_al_state_t = 8; 463 | #[doc = " Application-layer state."] 464 | pub type ec_al_state_t = ::std::os::raw::c_uint; 465 | #[doc = " Slave information interface CANopen over EtherCAT details flags."] 466 | #[repr(C, packed)] 467 | #[derive(Default, Copy, Clone)] 468 | pub struct ec_sii_coe_details_t { 469 | pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize], u8>, 470 | } 471 | impl ec_sii_coe_details_t { 472 | #[inline] 473 | pub fn enable_sdo(&self) -> u8 { 474 | unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u8) } 475 | } 476 | #[inline] 477 | pub fn set_enable_sdo(&mut self, val: u8) { 478 | unsafe { 479 | let val: u8 = ::std::mem::transmute(val); 480 | self._bitfield_1.set(0usize, 1u8, val as u64) 481 | } 482 | } 483 | #[inline] 484 | pub fn enable_sdo_info(&self) -> u8 { 485 | unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u8) } 486 | } 487 | #[inline] 488 | pub fn set_enable_sdo_info(&mut self, val: u8) { 489 | unsafe { 490 | let val: u8 = ::std::mem::transmute(val); 491 | self._bitfield_1.set(1usize, 1u8, val as u64) 492 | } 493 | } 494 | #[inline] 495 | pub fn enable_pdo_assign(&self) -> u8 { 496 | unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u8) } 497 | } 498 | #[inline] 499 | pub fn set_enable_pdo_assign(&mut self, val: u8) { 500 | unsafe { 501 | let val: u8 = ::std::mem::transmute(val); 502 | self._bitfield_1.set(2usize, 1u8, val as u64) 503 | } 504 | } 505 | #[inline] 506 | pub fn enable_pdo_configuration(&self) -> u8 { 507 | unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 1u8) as u8) } 508 | } 509 | #[inline] 510 | pub fn set_enable_pdo_configuration(&mut self, val: u8) { 511 | unsafe { 512 | let val: u8 = ::std::mem::transmute(val); 513 | self._bitfield_1.set(3usize, 1u8, val as u64) 514 | } 515 | } 516 | #[inline] 517 | pub fn enable_upload_at_startup(&self) -> u8 { 518 | unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 1u8) as u8) } 519 | } 520 | #[inline] 521 | pub fn set_enable_upload_at_startup(&mut self, val: u8) { 522 | unsafe { 523 | let val: u8 = ::std::mem::transmute(val); 524 | self._bitfield_1.set(4usize, 1u8, val as u64) 525 | } 526 | } 527 | #[inline] 528 | pub fn enable_sdo_complete_access(&self) -> u8 { 529 | unsafe { ::std::mem::transmute(self._bitfield_1.get(5usize, 1u8) as u8) } 530 | } 531 | #[inline] 532 | pub fn set_enable_sdo_complete_access(&mut self, val: u8) { 533 | unsafe { 534 | let val: u8 = ::std::mem::transmute(val); 535 | self._bitfield_1.set(5usize, 1u8, val as u64) 536 | } 537 | } 538 | #[inline] 539 | pub fn new_bitfield_1( 540 | enable_sdo: u8, 541 | enable_sdo_info: u8, 542 | enable_pdo_assign: u8, 543 | enable_pdo_configuration: u8, 544 | enable_upload_at_startup: u8, 545 | enable_sdo_complete_access: u8, 546 | ) -> __BindgenBitfieldUnit<[u8; 1usize], u8> { 547 | let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize], u8> = 548 | Default::default(); 549 | __bindgen_bitfield_unit.set(0usize, 1u8, { 550 | let enable_sdo: u8 = unsafe { ::std::mem::transmute(enable_sdo) }; 551 | enable_sdo as u64 552 | }); 553 | __bindgen_bitfield_unit.set(1usize, 1u8, { 554 | let enable_sdo_info: u8 = unsafe { ::std::mem::transmute(enable_sdo_info) }; 555 | enable_sdo_info as u64 556 | }); 557 | __bindgen_bitfield_unit.set(2usize, 1u8, { 558 | let enable_pdo_assign: u8 = unsafe { ::std::mem::transmute(enable_pdo_assign) }; 559 | enable_pdo_assign as u64 560 | }); 561 | __bindgen_bitfield_unit.set(3usize, 1u8, { 562 | let enable_pdo_configuration: u8 = 563 | unsafe { ::std::mem::transmute(enable_pdo_configuration) }; 564 | enable_pdo_configuration as u64 565 | }); 566 | __bindgen_bitfield_unit.set(4usize, 1u8, { 567 | let enable_upload_at_startup: u8 = 568 | unsafe { ::std::mem::transmute(enable_upload_at_startup) }; 569 | enable_upload_at_startup as u64 570 | }); 571 | __bindgen_bitfield_unit.set(5usize, 1u8, { 572 | let enable_sdo_complete_access: u8 = 573 | unsafe { ::std::mem::transmute(enable_sdo_complete_access) }; 574 | enable_sdo_complete_access as u64 575 | }); 576 | __bindgen_bitfield_unit 577 | } 578 | } 579 | #[doc = " Slave information interface general flags."] 580 | #[repr(C, packed)] 581 | #[derive(Default, Copy, Clone)] 582 | pub struct ec_sii_general_flags_t { 583 | pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize], u8>, 584 | } 585 | impl ec_sii_general_flags_t { 586 | #[inline] 587 | pub fn enable_safeop(&self) -> u8 { 588 | unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u8) } 589 | } 590 | #[inline] 591 | pub fn set_enable_safeop(&mut self, val: u8) { 592 | unsafe { 593 | let val: u8 = ::std::mem::transmute(val); 594 | self._bitfield_1.set(0usize, 1u8, val as u64) 595 | } 596 | } 597 | #[inline] 598 | pub fn enable_not_lrw(&self) -> u8 { 599 | unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u8) } 600 | } 601 | #[inline] 602 | pub fn set_enable_not_lrw(&mut self, val: u8) { 603 | unsafe { 604 | let val: u8 = ::std::mem::transmute(val); 605 | self._bitfield_1.set(1usize, 1u8, val as u64) 606 | } 607 | } 608 | #[inline] 609 | pub fn new_bitfield_1( 610 | enable_safeop: u8, 611 | enable_not_lrw: u8, 612 | ) -> __BindgenBitfieldUnit<[u8; 1usize], u8> { 613 | let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize], u8> = 614 | Default::default(); 615 | __bindgen_bitfield_unit.set(0usize, 1u8, { 616 | let enable_safeop: u8 = unsafe { ::std::mem::transmute(enable_safeop) }; 617 | enable_safeop as u64 618 | }); 619 | __bindgen_bitfield_unit.set(1usize, 1u8, { 620 | let enable_not_lrw: u8 = unsafe { ::std::mem::transmute(enable_not_lrw) }; 621 | enable_not_lrw as u64 622 | }); 623 | __bindgen_bitfield_unit 624 | } 625 | } 626 | #[doc = "< 32 bit."] 627 | pub const EC_DC_32: ec_slave_dc_range_t = 0; 628 | pub const EC_DC_64: ec_slave_dc_range_t = 1; 629 | #[doc = " EtherCAT slave distributed clocks range."] 630 | pub type ec_slave_dc_range_t = ::std::os::raw::c_uint; 631 | #[doc = " EtherCAT slave sync signal configuration."] 632 | #[repr(C)] 633 | #[derive(Default, Copy, Clone)] 634 | pub struct ec_sync_signal_t { 635 | #[doc = "< Cycle time [ns]."] 636 | pub cycle_time: u32, 637 | #[doc = "< Shift time [ns]."] 638 | pub shift_time: i32, 639 | } 640 | #[repr(C)] 641 | #[derive(Default, Copy, Clone)] 642 | pub struct ec_ioctl_module_t { 643 | pub ioctl_version_magic: u32, 644 | pub master_count: u32, 645 | } 646 | #[repr(C)] 647 | #[derive(Default, Copy, Clone)] 648 | pub struct ec_ioctl_master_t { 649 | pub slave_count: u32, 650 | pub config_count: u32, 651 | pub domain_count: u32, 652 | pub eoe_handler_count: u32, 653 | pub phase: u8, 654 | pub active: u8, 655 | pub scan_busy: u8, 656 | pub devices: [ec_ioctl_master_t_ec_ioctl_device; 1usize], 657 | pub num_devices: u32, 658 | pub tx_count: u64, 659 | pub rx_count: u64, 660 | pub tx_bytes: u64, 661 | pub rx_bytes: u64, 662 | pub tx_frame_rates: [i32; 3usize], 663 | pub rx_frame_rates: [i32; 3usize], 664 | pub tx_byte_rates: [i32; 3usize], 665 | pub rx_byte_rates: [i32; 3usize], 666 | pub loss_rates: [i32; 3usize], 667 | pub app_time: u64, 668 | pub dc_ref_time: u64, 669 | pub ref_clock: u16, 670 | pub pcap_size: u32, 671 | } 672 | #[repr(C)] 673 | #[derive(Default, Copy, Clone)] 674 | pub struct ec_ioctl_master_t_ec_ioctl_device { 675 | pub address: [u8; 6usize], 676 | pub attached: u8, 677 | pub link_state: u8, 678 | pub tx_count: u64, 679 | pub rx_count: u64, 680 | pub tx_bytes: u64, 681 | pub rx_bytes: u64, 682 | pub tx_errors: u64, 683 | pub tx_frame_rates: [i32; 3usize], 684 | pub rx_frame_rates: [i32; 3usize], 685 | pub tx_byte_rates: [i32; 3usize], 686 | pub rx_byte_rates: [i32; 3usize], 687 | } 688 | #[repr(C)] 689 | #[derive(Copy, Clone)] 690 | pub struct ec_ioctl_slave_t { 691 | pub position: u16, 692 | pub device_index: ::std::os::raw::c_uint, 693 | pub vendor_id: u32, 694 | pub product_code: u32, 695 | pub revision_number: u32, 696 | pub serial_number: u32, 697 | pub alias: u16, 698 | pub boot_rx_mailbox_offset: u16, 699 | pub boot_rx_mailbox_size: u16, 700 | pub boot_tx_mailbox_offset: u16, 701 | pub boot_tx_mailbox_size: u16, 702 | pub std_rx_mailbox_offset: u16, 703 | pub std_rx_mailbox_size: u16, 704 | pub std_tx_mailbox_offset: u16, 705 | pub std_tx_mailbox_size: u16, 706 | pub mailbox_protocols: u16, 707 | pub has_general_category: u8, 708 | pub coe_details: ec_sii_coe_details_t, 709 | pub general_flags: ec_sii_general_flags_t, 710 | pub current_on_ebus: i16, 711 | pub ports: [ec_ioctl_slave_t__bindgen_ty_1; 4usize], 712 | pub upstream_port: u8, 713 | pub fmmu_bit: u8, 714 | pub dc_supported: u8, 715 | pub dc_range: ec_slave_dc_range_t, 716 | pub has_dc_system_time: u8, 717 | pub transmission_delay: u32, 718 | pub al_state: u8, 719 | pub error_flag: u8, 720 | pub scan_required: u8, 721 | pub ready: u8, 722 | pub sync_count: u8, 723 | pub sdo_count: u16, 724 | pub sii_nwords: u32, 725 | pub group: [::std::os::raw::c_char; 64usize], 726 | pub image: [::std::os::raw::c_char; 64usize], 727 | pub order: [::std::os::raw::c_char; 64usize], 728 | pub name: [::std::os::raw::c_char; 64usize], 729 | } 730 | #[repr(C)] 731 | #[derive(Copy, Clone)] 732 | pub struct ec_ioctl_slave_t__bindgen_ty_1 { 733 | pub desc: ec_slave_port_desc_t, 734 | pub link: ec_slave_port_link_t, 735 | pub receive_time: u32, 736 | pub next_slave: u16, 737 | pub delay_to_next_dc: u32, 738 | } 739 | impl Default for ec_ioctl_slave_t__bindgen_ty_1 { 740 | fn default() -> Self { 741 | unsafe { ::std::mem::zeroed() } 742 | } 743 | } 744 | impl Default for ec_ioctl_slave_t { 745 | fn default() -> Self { 746 | unsafe { ::std::mem::zeroed() } 747 | } 748 | } 749 | #[repr(C)] 750 | #[derive(Default, Copy, Clone)] 751 | pub struct ec_ioctl_slave_sync_t { 752 | pub slave_position: u16, 753 | pub sync_index: u32, 754 | pub physical_start_address: u16, 755 | pub default_size: u16, 756 | pub control_register: u8, 757 | pub enable: u8, 758 | pub pdo_count: u8, 759 | } 760 | #[repr(C)] 761 | #[derive(Copy, Clone)] 762 | pub struct ec_ioctl_slave_sync_pdo_t { 763 | pub slave_position: u16, 764 | pub sync_index: u32, 765 | pub pdo_pos: u32, 766 | pub index: u16, 767 | pub entry_count: u8, 768 | pub name: [i8; 64usize], 769 | } 770 | impl Default for ec_ioctl_slave_sync_pdo_t { 771 | fn default() -> Self { 772 | unsafe { ::std::mem::zeroed() } 773 | } 774 | } 775 | #[repr(C)] 776 | #[derive(Copy, Clone)] 777 | pub struct ec_ioctl_slave_sync_pdo_entry_t { 778 | pub slave_position: u16, 779 | pub sync_index: u32, 780 | pub pdo_pos: u32, 781 | pub entry_pos: u32, 782 | pub index: u16, 783 | pub subindex: u8, 784 | pub bit_length: u8, 785 | pub name: [i8; 64usize], 786 | } 787 | impl Default for ec_ioctl_slave_sync_pdo_entry_t { 788 | fn default() -> Self { 789 | unsafe { ::std::mem::zeroed() } 790 | } 791 | } 792 | #[repr(C)] 793 | #[derive(Default, Copy, Clone)] 794 | pub struct ec_ioctl_domain_t { 795 | pub index: u32, 796 | pub data_size: u32, 797 | pub logical_base_address: u32, 798 | pub working_counter: [u16; 1usize], 799 | pub expected_working_counter: u16, 800 | pub fmmu_count: u32, 801 | } 802 | #[repr(C)] 803 | #[derive(Copy, Clone)] 804 | pub struct ec_ioctl_domain_fmmu_t { 805 | pub domain_index: u32, 806 | pub fmmu_index: u32, 807 | pub slave_config_alias: u16, 808 | pub slave_config_position: u16, 809 | pub sync_index: u8, 810 | pub dir: ec_direction_t, 811 | pub logical_address: u32, 812 | pub data_size: u32, 813 | } 814 | impl Default for ec_ioctl_domain_fmmu_t { 815 | fn default() -> Self { 816 | unsafe { ::std::mem::zeroed() } 817 | } 818 | } 819 | #[repr(C)] 820 | #[derive(Copy, Clone)] 821 | pub struct ec_ioctl_domain_data_t { 822 | pub domain_index: u32, 823 | pub data_size: u32, 824 | pub target: *mut u8, 825 | } 826 | impl Default for ec_ioctl_domain_data_t { 827 | fn default() -> Self { 828 | unsafe { ::std::mem::zeroed() } 829 | } 830 | } 831 | #[repr(C)] 832 | #[derive(Copy, Clone)] 833 | pub struct ec_ioctl_pcap_data_t { 834 | pub data_size: u32, 835 | pub reset_data: u8, 836 | pub target: *mut u8, 837 | } 838 | impl Default for ec_ioctl_pcap_data_t { 839 | fn default() -> Self { 840 | unsafe { ::std::mem::zeroed() } 841 | } 842 | } 843 | #[repr(C)] 844 | #[derive(Default, Copy, Clone)] 845 | pub struct ec_ioctl_slave_state_t { 846 | pub slave_position: u16, 847 | pub al_state: u8, 848 | } 849 | #[repr(C)] 850 | #[derive(Copy, Clone)] 851 | pub struct ec_ioctl_slave_sdo_t { 852 | pub slave_position: u16, 853 | pub sdo_position: u16, 854 | pub sdo_index: u16, 855 | pub max_subindex: u8, 856 | pub object_code: u8, 857 | pub name: [i8; 64usize], 858 | } 859 | impl Default for ec_ioctl_slave_sdo_t { 860 | fn default() -> Self { 861 | unsafe { ::std::mem::zeroed() } 862 | } 863 | } 864 | #[repr(C)] 865 | #[derive(Copy, Clone)] 866 | pub struct ec_ioctl_slave_sdo_entry_t { 867 | pub slave_position: u16, 868 | pub sdo_spec: ::std::os::raw::c_int, 869 | pub sdo_entry_subindex: u8, 870 | pub data_type: u16, 871 | pub bit_length: u16, 872 | pub read_access: [u8; 3usize], 873 | pub write_access: [u8; 3usize], 874 | pub description: [i8; 64usize], 875 | } 876 | impl Default for ec_ioctl_slave_sdo_entry_t { 877 | fn default() -> Self { 878 | unsafe { ::std::mem::zeroed() } 879 | } 880 | } 881 | #[repr(C)] 882 | #[derive(Copy, Clone)] 883 | pub struct ec_ioctl_slave_sdo_upload_t { 884 | pub slave_position: u16, 885 | pub sdo_index: u16, 886 | pub sdo_entry_subindex: u8, 887 | pub complete_access: u8, 888 | pub target_size: size_t, 889 | pub target: *mut u8, 890 | pub data_size: size_t, 891 | pub abort_code: u32, 892 | } 893 | impl Default for ec_ioctl_slave_sdo_upload_t { 894 | fn default() -> Self { 895 | unsafe { ::std::mem::zeroed() } 896 | } 897 | } 898 | #[repr(C)] 899 | #[derive(Copy, Clone)] 900 | pub struct ec_ioctl_slave_sdo_download_t { 901 | pub slave_position: u16, 902 | pub sdo_index: u16, 903 | pub sdo_entry_subindex: u8, 904 | pub complete_access: u8, 905 | pub data_size: size_t, 906 | pub data: *const u8, 907 | pub abort_code: u32, 908 | } 909 | impl Default for ec_ioctl_slave_sdo_download_t { 910 | fn default() -> Self { 911 | unsafe { ::std::mem::zeroed() } 912 | } 913 | } 914 | #[repr(C)] 915 | #[derive(Copy, Clone)] 916 | pub struct ec_ioctl_slave_sii_t { 917 | pub slave_position: u16, 918 | pub offset: u16, 919 | pub nwords: u32, 920 | pub words: *mut u16, 921 | } 922 | impl Default for ec_ioctl_slave_sii_t { 923 | fn default() -> Self { 924 | unsafe { ::std::mem::zeroed() } 925 | } 926 | } 927 | #[repr(C)] 928 | #[derive(Copy, Clone)] 929 | pub struct ec_ioctl_slave_reg_t { 930 | pub slave_position: u16, 931 | pub emergency: u8, 932 | pub address: u16, 933 | pub size: size_t, 934 | pub data: *mut u8, 935 | } 936 | impl Default for ec_ioctl_slave_reg_t { 937 | fn default() -> Self { 938 | unsafe { ::std::mem::zeroed() } 939 | } 940 | } 941 | #[repr(C)] 942 | #[derive(Default, Copy, Clone)] 943 | pub struct ec_ioctl_slave_reboot_t { 944 | pub slave_position: u16, 945 | pub broadcast: u8, 946 | } 947 | #[repr(C)] 948 | #[derive(Copy, Clone)] 949 | pub struct ec_ioctl_slave_foe_t { 950 | pub password: u32, 951 | pub slave_position: u16, 952 | pub offset: u16, 953 | pub buffer_size: size_t, 954 | pub buffer: *mut u8, 955 | pub data_size: size_t, 956 | pub result: u32, 957 | pub error_code: u32, 958 | pub file_name: [::std::os::raw::c_char; 255usize], 959 | } 960 | impl Default for ec_ioctl_slave_foe_t { 961 | fn default() -> Self { 962 | unsafe { ::std::mem::zeroed() } 963 | } 964 | } 965 | #[repr(C)] 966 | #[derive(Copy, Clone)] 967 | pub struct ec_ioctl_slave_soe_read_t { 968 | pub slave_position: u16, 969 | pub drive_no: u8, 970 | pub idn: u16, 971 | pub mem_size: size_t, 972 | pub data: *mut u8, 973 | pub data_size: size_t, 974 | pub error_code: u16, 975 | } 976 | impl Default for ec_ioctl_slave_soe_read_t { 977 | fn default() -> Self { 978 | unsafe { ::std::mem::zeroed() } 979 | } 980 | } 981 | #[repr(C)] 982 | #[derive(Copy, Clone)] 983 | pub struct ec_ioctl_slave_soe_write_t { 984 | pub slave_position: u16, 985 | pub drive_no: u8, 986 | pub idn: u16, 987 | pub data_size: size_t, 988 | pub data: *mut u8, 989 | pub error_code: u16, 990 | } 991 | impl Default for ec_ioctl_slave_soe_write_t { 992 | fn default() -> Self { 993 | unsafe { ::std::mem::zeroed() } 994 | } 995 | } 996 | #[repr(C)] 997 | #[derive(Copy, Clone)] 998 | pub struct ec_ioctl_config_t { 999 | pub config_index: u32, 1000 | pub alias: u16, 1001 | pub position: u16, 1002 | pub vendor_id: u32, 1003 | pub product_code: u32, 1004 | pub syncs: [ec_ioctl_config_t__bindgen_ty_1; 16usize], 1005 | pub watchdog_divider: u16, 1006 | pub watchdog_intervals: u16, 1007 | pub sdo_count: u32, 1008 | pub idn_count: u32, 1009 | pub slave_position: i32, 1010 | pub dc_assign_activate: u16, 1011 | pub dc_sync: [ec_sync_signal_t; 2usize], 1012 | pub allow_overlapping_pdos: u8, 1013 | } 1014 | #[repr(C)] 1015 | #[derive(Copy, Clone)] 1016 | pub struct ec_ioctl_config_t__bindgen_ty_1 { 1017 | pub dir: ec_direction_t, 1018 | pub watchdog_mode: ec_watchdog_mode_t, 1019 | pub pdo_count: u32, 1020 | pub config_this: u8, 1021 | } 1022 | impl Default for ec_ioctl_config_t__bindgen_ty_1 { 1023 | fn default() -> Self { 1024 | unsafe { ::std::mem::zeroed() } 1025 | } 1026 | } 1027 | impl Default for ec_ioctl_config_t { 1028 | fn default() -> Self { 1029 | unsafe { ::std::mem::zeroed() } 1030 | } 1031 | } 1032 | #[repr(C)] 1033 | #[derive(Copy, Clone)] 1034 | pub struct ec_ioctl_config_pdo_t { 1035 | pub config_index: u32, 1036 | pub sync_index: u8, 1037 | pub pdo_pos: u16, 1038 | pub index: u16, 1039 | pub entry_count: u8, 1040 | pub name: [i8; 64usize], 1041 | } 1042 | impl Default for ec_ioctl_config_pdo_t { 1043 | fn default() -> Self { 1044 | unsafe { ::std::mem::zeroed() } 1045 | } 1046 | } 1047 | #[repr(C)] 1048 | #[derive(Copy, Clone)] 1049 | pub struct ec_ioctl_config_pdo_entry_t { 1050 | pub config_index: u32, 1051 | pub sync_index: u8, 1052 | pub pdo_pos: u16, 1053 | pub entry_pos: u8, 1054 | pub index: u16, 1055 | pub subindex: u8, 1056 | pub bit_length: u8, 1057 | pub name: [i8; 64usize], 1058 | } 1059 | impl Default for ec_ioctl_config_pdo_entry_t { 1060 | fn default() -> Self { 1061 | unsafe { ::std::mem::zeroed() } 1062 | } 1063 | } 1064 | #[repr(C)] 1065 | #[derive(Copy, Clone)] 1066 | pub struct ec_ioctl_config_sdo_t { 1067 | pub config_index: u32, 1068 | pub sdo_pos: u32, 1069 | pub index: u16, 1070 | pub subindex: u8, 1071 | pub size: size_t, 1072 | pub data: [u8; 1024usize], 1073 | pub complete_access: u8, 1074 | } 1075 | impl Default for ec_ioctl_config_sdo_t { 1076 | fn default() -> Self { 1077 | unsafe { ::std::mem::zeroed() } 1078 | } 1079 | } 1080 | #[repr(C)] 1081 | #[derive(Copy, Clone)] 1082 | pub struct ec_ioctl_config_idn_t { 1083 | pub config_index: u32, 1084 | pub idn_pos: u32, 1085 | pub drive_no: u8, 1086 | pub idn: u16, 1087 | pub state: ec_al_state_t, 1088 | pub size: size_t, 1089 | pub data: [u8; 1024usize], 1090 | } 1091 | impl Default for ec_ioctl_config_idn_t { 1092 | fn default() -> Self { 1093 | unsafe { ::std::mem::zeroed() } 1094 | } 1095 | } 1096 | #[repr(C)] 1097 | #[derive(Default, Copy, Clone)] 1098 | pub struct ec_ioctl_eoe_handler_t { 1099 | pub eoe_index: u16, 1100 | pub name: [::std::os::raw::c_char; 20usize], 1101 | pub slave_position: u16, 1102 | pub open: u8, 1103 | pub rx_bytes: u32, 1104 | pub rx_rate: u32, 1105 | pub tx_bytes: u32, 1106 | pub tx_rate: u32, 1107 | pub tx_queued_frames: u32, 1108 | pub tx_queue_size: u32, 1109 | } 1110 | #[repr(C)] 1111 | #[derive(Default, Copy, Clone)] 1112 | pub struct ec_ioctl_eoe_if_t { 1113 | pub alias: u16, 1114 | pub position: u16, 1115 | } 1116 | #[repr(C)] 1117 | #[derive(Default, Copy, Clone)] 1118 | pub struct ec_ioctl_slave_eoe_ip_t { 1119 | pub slave_position: u16, 1120 | pub mac_address_included: u8, 1121 | pub ip_address_included: u8, 1122 | pub subnet_mask_included: u8, 1123 | pub gateway_included: u8, 1124 | pub dns_included: u8, 1125 | pub name_included: u8, 1126 | pub mac_address: [::std::os::raw::c_uchar; 6usize], 1127 | pub ip_address: u32, 1128 | pub subnet_mask: u32, 1129 | pub gateway: u32, 1130 | pub dns: u32, 1131 | pub name: [::std::os::raw::c_char; 32usize], 1132 | pub result: u16, 1133 | } 1134 | #[repr(C)] 1135 | #[derive(Copy, Clone)] 1136 | pub struct ec_ioctl_master_activate_t { 1137 | pub process_data: *mut ::std::os::raw::c_void, 1138 | pub process_data_size: size_t, 1139 | } 1140 | impl Default for ec_ioctl_master_activate_t { 1141 | fn default() -> Self { 1142 | unsafe { ::std::mem::zeroed() } 1143 | } 1144 | } 1145 | #[repr(C)] 1146 | #[derive(Default, Copy, Clone)] 1147 | pub struct ec_ioctl_add_pdo_entry_t { 1148 | pub config_index: u32, 1149 | pub pdo_index: u16, 1150 | pub entry_index: u16, 1151 | pub entry_subindex: u8, 1152 | pub entry_bit_length: u8, 1153 | } 1154 | #[repr(C)] 1155 | #[derive(Default, Copy, Clone)] 1156 | pub struct ec_ioctl_reg_pdo_entry_t { 1157 | pub config_index: u32, 1158 | pub entry_index: u16, 1159 | pub entry_subindex: u8, 1160 | pub domain_index: u32, 1161 | pub bit_position: ::std::os::raw::c_uint, 1162 | } 1163 | #[repr(C)] 1164 | #[derive(Default, Copy, Clone)] 1165 | pub struct ec_ioctl_reg_pdo_pos_t { 1166 | pub config_index: u32, 1167 | pub sync_index: u32, 1168 | pub pdo_pos: u32, 1169 | pub entry_pos: u32, 1170 | pub domain_index: u32, 1171 | pub bit_position: ::std::os::raw::c_uint, 1172 | } 1173 | #[repr(C)] 1174 | #[derive(Copy, Clone)] 1175 | pub struct ec_ioctl_sc_sdo_t { 1176 | pub config_index: u32, 1177 | pub index: u16, 1178 | pub subindex: u8, 1179 | pub data: *const u8, 1180 | pub size: size_t, 1181 | pub complete_access: u8, 1182 | } 1183 | impl Default for ec_ioctl_sc_sdo_t { 1184 | fn default() -> Self { 1185 | unsafe { ::std::mem::zeroed() } 1186 | } 1187 | } 1188 | #[repr(C)] 1189 | #[derive(Copy, Clone)] 1190 | pub struct ec_ioctl_sc_emerg_t { 1191 | pub config_index: u32, 1192 | pub size: size_t, 1193 | pub target: *mut u8, 1194 | pub overruns: i32, 1195 | } 1196 | impl Default for ec_ioctl_sc_emerg_t { 1197 | fn default() -> Self { 1198 | unsafe { ::std::mem::zeroed() } 1199 | } 1200 | } 1201 | #[repr(C)] 1202 | #[derive(Copy, Clone)] 1203 | pub struct ec_ioctl_sc_state_t { 1204 | pub config_index: u32, 1205 | pub state: *mut ec_slave_config_state_t, 1206 | } 1207 | impl Default for ec_ioctl_sc_state_t { 1208 | fn default() -> Self { 1209 | unsafe { ::std::mem::zeroed() } 1210 | } 1211 | } 1212 | #[repr(C)] 1213 | #[derive(Copy, Clone)] 1214 | pub struct ec_ioctl_sc_idn_t { 1215 | pub config_index: u32, 1216 | pub drive_no: u8, 1217 | pub idn: u16, 1218 | pub al_state: ec_al_state_t, 1219 | pub data: *const u8, 1220 | pub size: size_t, 1221 | } 1222 | impl Default for ec_ioctl_sc_idn_t { 1223 | fn default() -> Self { 1224 | unsafe { ::std::mem::zeroed() } 1225 | } 1226 | } 1227 | #[repr(C)] 1228 | #[derive(Copy, Clone)] 1229 | pub struct ec_ioctl_domain_state_t { 1230 | pub domain_index: u32, 1231 | pub state: *mut ec_domain_state_t, 1232 | } 1233 | impl Default for ec_ioctl_domain_state_t { 1234 | fn default() -> Self { 1235 | unsafe { ::std::mem::zeroed() } 1236 | } 1237 | } 1238 | #[repr(C)] 1239 | #[derive(Copy, Clone)] 1240 | pub struct ec_ioctl_sdo_request_t { 1241 | pub config_index: u32, 1242 | pub request_index: u32, 1243 | pub sdo_index: u16, 1244 | pub sdo_subindex: u8, 1245 | pub complete_access: u8, 1246 | pub size: size_t, 1247 | pub data: *mut u8, 1248 | pub timeout: u32, 1249 | pub state: ec_request_state_t, 1250 | } 1251 | impl Default for ec_ioctl_sdo_request_t { 1252 | fn default() -> Self { 1253 | unsafe { ::std::mem::zeroed() } 1254 | } 1255 | } 1256 | #[repr(C)] 1257 | #[derive(Copy, Clone)] 1258 | pub struct ec_ioctl_foe_request_t { 1259 | pub config_index: u32, 1260 | pub request_index: u32, 1261 | pub password: u32, 1262 | pub size: size_t, 1263 | pub progress: size_t, 1264 | pub data: *mut u8, 1265 | pub timeout: u32, 1266 | pub state: ec_request_state_t, 1267 | pub result: ec_foe_error_t, 1268 | pub error_code: u32, 1269 | pub file_name: [::std::os::raw::c_char; 255usize], 1270 | } 1271 | impl Default for ec_ioctl_foe_request_t { 1272 | fn default() -> Self { 1273 | unsafe { ::std::mem::zeroed() } 1274 | } 1275 | } 1276 | #[repr(C)] 1277 | #[derive(Copy, Clone)] 1278 | pub struct ec_ioctl_reg_request_t { 1279 | pub config_index: u32, 1280 | pub mem_size: size_t, 1281 | pub request_index: u32, 1282 | pub data: *mut u8, 1283 | pub state: ec_request_state_t, 1284 | pub new_data: u8, 1285 | pub address: u16, 1286 | pub transfer_size: size_t, 1287 | } 1288 | impl Default for ec_ioctl_reg_request_t { 1289 | fn default() -> Self { 1290 | unsafe { ::std::mem::zeroed() } 1291 | } 1292 | } 1293 | #[repr(C)] 1294 | #[derive(Copy, Clone)] 1295 | pub struct ec_ioctl_voe_t { 1296 | pub config_index: u32, 1297 | pub voe_index: u32, 1298 | pub vendor_id: *mut u32, 1299 | pub vendor_type: *mut u16, 1300 | pub size: size_t, 1301 | pub data: *mut u8, 1302 | pub state: ec_request_state_t, 1303 | } 1304 | impl Default for ec_ioctl_voe_t { 1305 | fn default() -> Self { 1306 | unsafe { ::std::mem::zeroed() } 1307 | } 1308 | } 1309 | #[repr(C)] 1310 | #[derive(Copy, Clone)] 1311 | pub struct ec_ioctl_link_state_t { 1312 | pub dev_idx: u32, 1313 | pub state: *mut ec_master_link_state_t, 1314 | } 1315 | impl Default for ec_ioctl_link_state_t { 1316 | fn default() -> Self { 1317 | unsafe { ::std::mem::zeroed() } 1318 | } 1319 | } 1320 | #[repr(C)] 1321 | #[derive(Default, Copy, Clone)] 1322 | pub struct ec_ioctl_slave_dict_upload_t { 1323 | pub slave_position: u16, 1324 | } 1325 | #[repr(C)] 1326 | #[derive(Copy, Clone)] 1327 | pub struct ec_ioctl_mbox_gateway_t { 1328 | pub data_size: size_t, 1329 | pub buff_size: size_t, 1330 | pub data: *mut u8, 1331 | } 1332 | impl Default for ec_ioctl_mbox_gateway_t { 1333 | fn default() -> Self { 1334 | unsafe { ::std::mem::zeroed() } 1335 | } 1336 | } 1337 | -------------------------------------------------------------------------------- /ethercat-sys/src/bindings-v1.6.1.rs: -------------------------------------------------------------------------------- 1 | /* automatically generated by rust-bindgen 0.69.4 */ 2 | 3 | #[repr(C)] 4 | #[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] 5 | pub struct __BindgenBitfieldUnit { 6 | storage: Storage, 7 | } 8 | impl __BindgenBitfieldUnit { 9 | #[inline] 10 | pub const fn new(storage: Storage) -> Self { 11 | Self { storage } 12 | } 13 | } 14 | impl __BindgenBitfieldUnit 15 | where 16 | Storage: AsRef<[u8]> + AsMut<[u8]>, 17 | { 18 | #[inline] 19 | pub fn get_bit(&self, index: usize) -> bool { 20 | debug_assert!(index / 8 < self.storage.as_ref().len()); 21 | let byte_index = index / 8; 22 | let byte = self.storage.as_ref()[byte_index]; 23 | let bit_index = if cfg!(target_endian = "big") { 24 | 7 - (index % 8) 25 | } else { 26 | index % 8 27 | }; 28 | let mask = 1 << bit_index; 29 | byte & mask == mask 30 | } 31 | #[inline] 32 | pub fn set_bit(&mut self, index: usize, val: bool) { 33 | debug_assert!(index / 8 < self.storage.as_ref().len()); 34 | let byte_index = index / 8; 35 | let byte = &mut self.storage.as_mut()[byte_index]; 36 | let bit_index = if cfg!(target_endian = "big") { 37 | 7 - (index % 8) 38 | } else { 39 | index % 8 40 | }; 41 | let mask = 1 << bit_index; 42 | if val { 43 | *byte |= mask; 44 | } else { 45 | *byte &= !mask; 46 | } 47 | } 48 | #[inline] 49 | pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { 50 | debug_assert!(bit_width <= 64); 51 | debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); 52 | debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); 53 | let mut val = 0; 54 | for i in 0..(bit_width as usize) { 55 | if self.get_bit(i + bit_offset) { 56 | let index = if cfg!(target_endian = "big") { 57 | bit_width as usize - 1 - i 58 | } else { 59 | i 60 | }; 61 | val |= 1 << index; 62 | } 63 | } 64 | val 65 | } 66 | #[inline] 67 | pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { 68 | debug_assert!(bit_width <= 64); 69 | debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); 70 | debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len()); 71 | for i in 0..(bit_width as usize) { 72 | let mask = 1 << i; 73 | let val_bit_is_set = val & mask == mask; 74 | let index = if cfg!(target_endian = "big") { 75 | bit_width as usize - 1 - i 76 | } else { 77 | i 78 | }; 79 | self.set_bit(index + bit_offset, val_bit_is_set); 80 | } 81 | } 82 | } 83 | pub const EC_MAX_NUM_DEVICES: u32 = 1; 84 | pub const EC_MAX_SYNC_MANAGERS: u32 = 16; 85 | pub const EC_MAX_STRING_LENGTH: u32 = 64; 86 | pub const EC_MAX_PORTS: u32 = 4; 87 | pub const EC_MAX_SII_SIZE: u32 = 4096; 88 | pub const EC_MAX_FMMUS: u32 = 16; 89 | pub const EC_MAX_HOSTNAME_SIZE: u32 = 32; 90 | pub const EC_IOCTL_TYPE: u32 = 164; 91 | pub const EC_IOCTL_VERSION_MAGIC: u32 = 37; 92 | pub const EC_IOCTL_STRING_SIZE: u32 = 64; 93 | pub const EC_MAX_SDO_DATA_SIZE: u32 = 1024; 94 | pub const EC_MAX_IDN_DATA_SIZE: u32 = 1024; 95 | pub const EC_MAX_FLAG_KEY_SIZE: u32 = 128; 96 | pub type in_addr_t = u32; 97 | #[repr(C)] 98 | #[derive(Default, Copy, Clone)] 99 | pub struct in_addr { 100 | pub s_addr: in_addr_t, 101 | } 102 | #[doc = " Master state.\n\n This is used for the output parameter of ecrt_master_state().\n\n \\see ecrt_master_state()."] 103 | #[repr(C)] 104 | #[derive(Default, Copy, Clone)] 105 | pub struct ec_master_state_t { 106 | #[doc = "< Sum of responding slaves on all\nEthernet devices."] 107 | pub slaves_responding: ::std::os::raw::c_uint, 108 | pub _bitfield_align_1: [u8; 0], 109 | pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, 110 | pub __bindgen_padding_0: [u8; 3usize], 111 | } 112 | impl ec_master_state_t { 113 | #[inline] 114 | pub fn al_states(&self) -> ::std::os::raw::c_uint { 115 | unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 4u8) as u32) } 116 | } 117 | #[inline] 118 | pub fn set_al_states(&mut self, val: ::std::os::raw::c_uint) { 119 | unsafe { 120 | let val: u32 = ::std::mem::transmute(val); 121 | self._bitfield_1.set(0usize, 4u8, val as u64) 122 | } 123 | } 124 | #[inline] 125 | pub fn link_up(&self) -> ::std::os::raw::c_uint { 126 | unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 1u8) as u32) } 127 | } 128 | #[inline] 129 | pub fn set_link_up(&mut self, val: ::std::os::raw::c_uint) { 130 | unsafe { 131 | let val: u32 = ::std::mem::transmute(val); 132 | self._bitfield_1.set(4usize, 1u8, val as u64) 133 | } 134 | } 135 | #[inline] 136 | pub fn new_bitfield_1( 137 | al_states: ::std::os::raw::c_uint, 138 | link_up: ::std::os::raw::c_uint, 139 | ) -> __BindgenBitfieldUnit<[u8; 1usize]> { 140 | let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); 141 | __bindgen_bitfield_unit.set(0usize, 4u8, { 142 | let al_states: u32 = unsafe { ::std::mem::transmute(al_states) }; 143 | al_states as u64 144 | }); 145 | __bindgen_bitfield_unit.set(4usize, 1u8, { 146 | let link_up: u32 = unsafe { ::std::mem::transmute(link_up) }; 147 | link_up as u64 148 | }); 149 | __bindgen_bitfield_unit 150 | } 151 | } 152 | #[doc = " Redundant link state.\n\n This is used for the output parameter of ecrt_master_link_state().\n\n \\see ecrt_master_link_state()."] 153 | #[repr(C)] 154 | #[derive(Default, Copy, Clone)] 155 | pub struct ec_master_link_state_t { 156 | #[doc = "< Sum of responding slaves on the given\nlink."] 157 | pub slaves_responding: ::std::os::raw::c_uint, 158 | pub _bitfield_align_1: [u8; 0], 159 | pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, 160 | pub __bindgen_padding_0: [u8; 3usize], 161 | } 162 | impl ec_master_link_state_t { 163 | #[inline] 164 | pub fn al_states(&self) -> ::std::os::raw::c_uint { 165 | unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 4u8) as u32) } 166 | } 167 | #[inline] 168 | pub fn set_al_states(&mut self, val: ::std::os::raw::c_uint) { 169 | unsafe { 170 | let val: u32 = ::std::mem::transmute(val); 171 | self._bitfield_1.set(0usize, 4u8, val as u64) 172 | } 173 | } 174 | #[inline] 175 | pub fn link_up(&self) -> ::std::os::raw::c_uint { 176 | unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 1u8) as u32) } 177 | } 178 | #[inline] 179 | pub fn set_link_up(&mut self, val: ::std::os::raw::c_uint) { 180 | unsafe { 181 | let val: u32 = ::std::mem::transmute(val); 182 | self._bitfield_1.set(4usize, 1u8, val as u64) 183 | } 184 | } 185 | #[inline] 186 | pub fn new_bitfield_1( 187 | al_states: ::std::os::raw::c_uint, 188 | link_up: ::std::os::raw::c_uint, 189 | ) -> __BindgenBitfieldUnit<[u8; 1usize]> { 190 | let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); 191 | __bindgen_bitfield_unit.set(0usize, 4u8, { 192 | let al_states: u32 = unsafe { ::std::mem::transmute(al_states) }; 193 | al_states as u64 194 | }); 195 | __bindgen_bitfield_unit.set(4usize, 1u8, { 196 | let link_up: u32 = unsafe { ::std::mem::transmute(link_up) }; 197 | link_up as u64 198 | }); 199 | __bindgen_bitfield_unit 200 | } 201 | } 202 | #[doc = " Slave configuration state.\n\n This is used as an output parameter of ecrt_slave_config_state().\n\n \\see ecrt_slave_config_state()."] 203 | #[repr(C)] 204 | #[repr(align(4))] 205 | #[derive(Default, Copy, Clone)] 206 | pub struct ec_slave_config_state_t { 207 | pub _bitfield_align_1: [u8; 0], 208 | pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, 209 | pub __bindgen_padding_0: [u8; 3usize], 210 | } 211 | impl ec_slave_config_state_t { 212 | #[inline] 213 | pub fn online(&self) -> ::std::os::raw::c_uint { 214 | unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u32) } 215 | } 216 | #[inline] 217 | pub fn set_online(&mut self, val: ::std::os::raw::c_uint) { 218 | unsafe { 219 | let val: u32 = ::std::mem::transmute(val); 220 | self._bitfield_1.set(0usize, 1u8, val as u64) 221 | } 222 | } 223 | #[inline] 224 | pub fn operational(&self) -> ::std::os::raw::c_uint { 225 | unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) } 226 | } 227 | #[inline] 228 | pub fn set_operational(&mut self, val: ::std::os::raw::c_uint) { 229 | unsafe { 230 | let val: u32 = ::std::mem::transmute(val); 231 | self._bitfield_1.set(1usize, 1u8, val as u64) 232 | } 233 | } 234 | #[inline] 235 | pub fn al_state(&self) -> ::std::os::raw::c_uint { 236 | unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 4u8) as u32) } 237 | } 238 | #[inline] 239 | pub fn set_al_state(&mut self, val: ::std::os::raw::c_uint) { 240 | unsafe { 241 | let val: u32 = ::std::mem::transmute(val); 242 | self._bitfield_1.set(2usize, 4u8, val as u64) 243 | } 244 | } 245 | #[inline] 246 | pub fn new_bitfield_1( 247 | online: ::std::os::raw::c_uint, 248 | operational: ::std::os::raw::c_uint, 249 | al_state: ::std::os::raw::c_uint, 250 | ) -> __BindgenBitfieldUnit<[u8; 1usize]> { 251 | let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); 252 | __bindgen_bitfield_unit.set(0usize, 1u8, { 253 | let online: u32 = unsafe { ::std::mem::transmute(online) }; 254 | online as u64 255 | }); 256 | __bindgen_bitfield_unit.set(1usize, 1u8, { 257 | let operational: u32 = unsafe { ::std::mem::transmute(operational) }; 258 | operational as u64 259 | }); 260 | __bindgen_bitfield_unit.set(2usize, 4u8, { 261 | let al_state: u32 = unsafe { ::std::mem::transmute(al_state) }; 262 | al_state as u64 263 | }); 264 | __bindgen_bitfield_unit 265 | } 266 | } 267 | #[doc = "< Port is not implemented."] 268 | pub const EC_PORT_NOT_IMPLEMENTED: ec_slave_port_desc_t = 0; 269 | #[doc = "< Port is not configured."] 270 | pub const EC_PORT_NOT_CONFIGURED: ec_slave_port_desc_t = 1; 271 | #[doc = "< Port is an E-Bus."] 272 | pub const EC_PORT_EBUS: ec_slave_port_desc_t = 2; 273 | #[doc = "< Port is a MII."] 274 | pub const EC_PORT_MII: ec_slave_port_desc_t = 3; 275 | #[doc = " EtherCAT slave port descriptor."] 276 | pub type ec_slave_port_desc_t = ::std::os::raw::c_uint; 277 | #[doc = " EtherCAT slave port information."] 278 | #[repr(C)] 279 | #[derive(Default, Copy, Clone)] 280 | pub struct ec_slave_port_link_t { 281 | #[doc = "< Link detected."] 282 | pub link_up: u8, 283 | #[doc = "< Loop closed."] 284 | pub loop_closed: u8, 285 | #[doc = "< Detected signal on RX port."] 286 | pub signal_detected: u8, 287 | } 288 | #[doc = "< No registered process data were exchanged."] 289 | pub const EC_WC_ZERO: ec_wc_state_t = 0; 290 | #[doc = "< Some of the registered process data were\nexchanged."] 291 | pub const EC_WC_INCOMPLETE: ec_wc_state_t = 1; 292 | #[doc = "< All registered process data were exchanged."] 293 | pub const EC_WC_COMPLETE: ec_wc_state_t = 2; 294 | #[doc = " Domain working counter interpretation.\n\n This is used in ec_domain_state_t."] 295 | pub type ec_wc_state_t = ::std::os::raw::c_uint; 296 | #[doc = " Domain state.\n\n This is used for the output parameter of ecrt_domain_state()."] 297 | #[repr(C)] 298 | #[derive(Copy, Clone)] 299 | pub struct ec_domain_state_t { 300 | #[doc = "< Value of the last working counter."] 301 | pub working_counter: ::std::os::raw::c_uint, 302 | #[doc = "< Working counter interpretation."] 303 | pub wc_state: ec_wc_state_t, 304 | #[doc = "< Redundant link is in use."] 305 | pub redundancy_active: ::std::os::raw::c_uint, 306 | } 307 | impl Default for ec_domain_state_t { 308 | fn default() -> Self { 309 | let mut s = ::std::mem::MaybeUninit::::uninit(); 310 | unsafe { 311 | ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); 312 | s.assume_init() 313 | } 314 | } 315 | } 316 | #[doc = "< Invalid direction. Do not use this value."] 317 | pub const EC_DIR_INVALID: ec_direction_t = 0; 318 | #[doc = "< Values written by the master."] 319 | pub const EC_DIR_OUTPUT: ec_direction_t = 1; 320 | #[doc = "< Values read by the master."] 321 | pub const EC_DIR_INPUT: ec_direction_t = 2; 322 | #[doc = "< Number of directions. For internal use only."] 323 | pub const EC_DIR_COUNT: ec_direction_t = 3; 324 | #[doc = " Direction type for PDO assignment functions."] 325 | pub type ec_direction_t = ::std::os::raw::c_uint; 326 | #[doc = "< Use the default setting of the sync manager."] 327 | pub const EC_WD_DEFAULT: ec_watchdog_mode_t = 0; 328 | #[doc = "< Enable the watchdog."] 329 | pub const EC_WD_ENABLE: ec_watchdog_mode_t = 1; 330 | #[doc = "< Disable the watchdog."] 331 | pub const EC_WD_DISABLE: ec_watchdog_mode_t = 2; 332 | #[doc = " Watchdog mode for sync manager configuration.\n\n Used to specify, if a sync manager's watchdog is to be enabled."] 333 | pub type ec_watchdog_mode_t = ::std::os::raw::c_uint; 334 | #[doc = "< Not requested."] 335 | pub const EC_REQUEST_UNUSED: ec_request_state_t = 0; 336 | #[doc = "< Request is being processed."] 337 | pub const EC_REQUEST_BUSY: ec_request_state_t = 1; 338 | #[doc = "< Request was processed successfully."] 339 | pub const EC_REQUEST_SUCCESS: ec_request_state_t = 2; 340 | #[doc = "< Request processing failed."] 341 | pub const EC_REQUEST_ERROR: ec_request_state_t = 3; 342 | #[doc = " Request state.\n\n This is used as return type for ecrt_sdo_request_state() and\n ecrt_voe_handler_state()."] 343 | pub type ec_request_state_t = ::std::os::raw::c_uint; 344 | #[doc = "< Init."] 345 | pub const EC_AL_STATE_INIT: ec_al_state_t = 1; 346 | #[doc = "< Pre-operational."] 347 | pub const EC_AL_STATE_PREOP: ec_al_state_t = 2; 348 | #[doc = "< Safe-operational."] 349 | pub const EC_AL_STATE_SAFEOP: ec_al_state_t = 4; 350 | #[doc = "< Operational."] 351 | pub const EC_AL_STATE_OP: ec_al_state_t = 8; 352 | #[doc = " Application-layer state."] 353 | pub type ec_al_state_t = ::std::os::raw::c_uint; 354 | #[doc = " Slave information interface CANopen over EtherCAT details flags."] 355 | #[repr(C)] 356 | #[derive(Default, Copy, Clone)] 357 | pub struct ec_sii_coe_details_t { 358 | pub _bitfield_align_1: [u8; 0], 359 | pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, 360 | } 361 | impl ec_sii_coe_details_t { 362 | #[inline] 363 | pub fn enable_sdo(&self) -> u8 { 364 | unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u8) } 365 | } 366 | #[inline] 367 | pub fn set_enable_sdo(&mut self, val: u8) { 368 | unsafe { 369 | let val: u8 = ::std::mem::transmute(val); 370 | self._bitfield_1.set(0usize, 1u8, val as u64) 371 | } 372 | } 373 | #[inline] 374 | pub fn enable_sdo_info(&self) -> u8 { 375 | unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u8) } 376 | } 377 | #[inline] 378 | pub fn set_enable_sdo_info(&mut self, val: u8) { 379 | unsafe { 380 | let val: u8 = ::std::mem::transmute(val); 381 | self._bitfield_1.set(1usize, 1u8, val as u64) 382 | } 383 | } 384 | #[inline] 385 | pub fn enable_pdo_assign(&self) -> u8 { 386 | unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u8) } 387 | } 388 | #[inline] 389 | pub fn set_enable_pdo_assign(&mut self, val: u8) { 390 | unsafe { 391 | let val: u8 = ::std::mem::transmute(val); 392 | self._bitfield_1.set(2usize, 1u8, val as u64) 393 | } 394 | } 395 | #[inline] 396 | pub fn enable_pdo_configuration(&self) -> u8 { 397 | unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 1u8) as u8) } 398 | } 399 | #[inline] 400 | pub fn set_enable_pdo_configuration(&mut self, val: u8) { 401 | unsafe { 402 | let val: u8 = ::std::mem::transmute(val); 403 | self._bitfield_1.set(3usize, 1u8, val as u64) 404 | } 405 | } 406 | #[inline] 407 | pub fn enable_upload_at_startup(&self) -> u8 { 408 | unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 1u8) as u8) } 409 | } 410 | #[inline] 411 | pub fn set_enable_upload_at_startup(&mut self, val: u8) { 412 | unsafe { 413 | let val: u8 = ::std::mem::transmute(val); 414 | self._bitfield_1.set(4usize, 1u8, val as u64) 415 | } 416 | } 417 | #[inline] 418 | pub fn enable_sdo_complete_access(&self) -> u8 { 419 | unsafe { ::std::mem::transmute(self._bitfield_1.get(5usize, 1u8) as u8) } 420 | } 421 | #[inline] 422 | pub fn set_enable_sdo_complete_access(&mut self, val: u8) { 423 | unsafe { 424 | let val: u8 = ::std::mem::transmute(val); 425 | self._bitfield_1.set(5usize, 1u8, val as u64) 426 | } 427 | } 428 | #[inline] 429 | pub fn new_bitfield_1( 430 | enable_sdo: u8, 431 | enable_sdo_info: u8, 432 | enable_pdo_assign: u8, 433 | enable_pdo_configuration: u8, 434 | enable_upload_at_startup: u8, 435 | enable_sdo_complete_access: u8, 436 | ) -> __BindgenBitfieldUnit<[u8; 1usize]> { 437 | let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); 438 | __bindgen_bitfield_unit.set(0usize, 1u8, { 439 | let enable_sdo: u8 = unsafe { ::std::mem::transmute(enable_sdo) }; 440 | enable_sdo as u64 441 | }); 442 | __bindgen_bitfield_unit.set(1usize, 1u8, { 443 | let enable_sdo_info: u8 = unsafe { ::std::mem::transmute(enable_sdo_info) }; 444 | enable_sdo_info as u64 445 | }); 446 | __bindgen_bitfield_unit.set(2usize, 1u8, { 447 | let enable_pdo_assign: u8 = unsafe { ::std::mem::transmute(enable_pdo_assign) }; 448 | enable_pdo_assign as u64 449 | }); 450 | __bindgen_bitfield_unit.set(3usize, 1u8, { 451 | let enable_pdo_configuration: u8 = 452 | unsafe { ::std::mem::transmute(enable_pdo_configuration) }; 453 | enable_pdo_configuration as u64 454 | }); 455 | __bindgen_bitfield_unit.set(4usize, 1u8, { 456 | let enable_upload_at_startup: u8 = 457 | unsafe { ::std::mem::transmute(enable_upload_at_startup) }; 458 | enable_upload_at_startup as u64 459 | }); 460 | __bindgen_bitfield_unit.set(5usize, 1u8, { 461 | let enable_sdo_complete_access: u8 = 462 | unsafe { ::std::mem::transmute(enable_sdo_complete_access) }; 463 | enable_sdo_complete_access as u64 464 | }); 465 | __bindgen_bitfield_unit 466 | } 467 | } 468 | #[doc = " Slave information interface general flags."] 469 | #[repr(C)] 470 | #[derive(Default, Copy, Clone)] 471 | pub struct ec_sii_general_flags_t { 472 | pub _bitfield_align_1: [u8; 0], 473 | pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, 474 | } 475 | impl ec_sii_general_flags_t { 476 | #[inline] 477 | pub fn enable_safeop(&self) -> u8 { 478 | unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u8) } 479 | } 480 | #[inline] 481 | pub fn set_enable_safeop(&mut self, val: u8) { 482 | unsafe { 483 | let val: u8 = ::std::mem::transmute(val); 484 | self._bitfield_1.set(0usize, 1u8, val as u64) 485 | } 486 | } 487 | #[inline] 488 | pub fn enable_not_lrw(&self) -> u8 { 489 | unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u8) } 490 | } 491 | #[inline] 492 | pub fn set_enable_not_lrw(&mut self, val: u8) { 493 | unsafe { 494 | let val: u8 = ::std::mem::transmute(val); 495 | self._bitfield_1.set(1usize, 1u8, val as u64) 496 | } 497 | } 498 | #[inline] 499 | pub fn new_bitfield_1( 500 | enable_safeop: u8, 501 | enable_not_lrw: u8, 502 | ) -> __BindgenBitfieldUnit<[u8; 1usize]> { 503 | let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); 504 | __bindgen_bitfield_unit.set(0usize, 1u8, { 505 | let enable_safeop: u8 = unsafe { ::std::mem::transmute(enable_safeop) }; 506 | enable_safeop as u64 507 | }); 508 | __bindgen_bitfield_unit.set(1usize, 1u8, { 509 | let enable_not_lrw: u8 = unsafe { ::std::mem::transmute(enable_not_lrw) }; 510 | enable_not_lrw as u64 511 | }); 512 | __bindgen_bitfield_unit 513 | } 514 | } 515 | #[doc = "< 32 bit."] 516 | pub const EC_DC_32: ec_slave_dc_range_t = 0; 517 | pub const EC_DC_64: ec_slave_dc_range_t = 1; 518 | #[doc = " EtherCAT slave distributed clocks range."] 519 | pub type ec_slave_dc_range_t = ::std::os::raw::c_uint; 520 | #[doc = " EtherCAT slave sync signal configuration."] 521 | #[repr(C)] 522 | #[derive(Default, Copy, Clone)] 523 | pub struct ec_sync_signal_t { 524 | #[doc = "< Cycle time [ns]."] 525 | pub cycle_time: u32, 526 | #[doc = "< Shift time [ns]."] 527 | pub shift_time: i32, 528 | } 529 | #[repr(C)] 530 | #[derive(Default, Copy, Clone)] 531 | pub struct ec_ioctl_module_t { 532 | pub ioctl_version_magic: u32, 533 | pub master_count: u32, 534 | } 535 | #[repr(C)] 536 | #[derive(Default, Copy, Clone)] 537 | pub struct ec_ioctl_master_t { 538 | pub slave_count: u32, 539 | pub scan_index: u32, 540 | pub config_count: u32, 541 | pub domain_count: u32, 542 | pub eoe_handler_count: u32, 543 | pub phase: u8, 544 | pub active: u8, 545 | pub scan_busy: u8, 546 | pub devices: [ec_ioctl_master_t_ec_ioctl_device; 1usize], 547 | pub num_devices: u32, 548 | pub tx_count: u64, 549 | pub rx_count: u64, 550 | pub tx_bytes: u64, 551 | pub rx_bytes: u64, 552 | pub tx_frame_rates: [i32; 3usize], 553 | pub rx_frame_rates: [i32; 3usize], 554 | pub tx_byte_rates: [i32; 3usize], 555 | pub rx_byte_rates: [i32; 3usize], 556 | pub loss_rates: [i32; 3usize], 557 | pub app_time: u64, 558 | pub dc_ref_time: u64, 559 | pub ref_clock: u16, 560 | } 561 | #[repr(C)] 562 | #[derive(Default, Copy, Clone)] 563 | pub struct ec_ioctl_master_t_ec_ioctl_device { 564 | pub address: [u8; 6usize], 565 | pub attached: u8, 566 | pub link_state: u8, 567 | pub tx_count: u64, 568 | pub rx_count: u64, 569 | pub tx_bytes: u64, 570 | pub rx_bytes: u64, 571 | pub tx_errors: u64, 572 | pub tx_frame_rates: [i32; 3usize], 573 | pub rx_frame_rates: [i32; 3usize], 574 | pub tx_byte_rates: [i32; 3usize], 575 | pub rx_byte_rates: [i32; 3usize], 576 | } 577 | #[repr(C)] 578 | #[derive(Copy, Clone)] 579 | pub struct ec_ioctl_slave_t { 580 | pub position: u16, 581 | pub device_index: ::std::os::raw::c_uint, 582 | pub vendor_id: u32, 583 | pub product_code: u32, 584 | pub revision_number: u32, 585 | pub serial_number: u32, 586 | pub alias: u16, 587 | pub boot_rx_mailbox_offset: u16, 588 | pub boot_rx_mailbox_size: u16, 589 | pub boot_tx_mailbox_offset: u16, 590 | pub boot_tx_mailbox_size: u16, 591 | pub std_rx_mailbox_offset: u16, 592 | pub std_rx_mailbox_size: u16, 593 | pub std_tx_mailbox_offset: u16, 594 | pub std_tx_mailbox_size: u16, 595 | pub mailbox_protocols: u16, 596 | pub has_general_category: u8, 597 | pub coe_details: ec_sii_coe_details_t, 598 | pub general_flags: ec_sii_general_flags_t, 599 | pub current_on_ebus: i16, 600 | pub ports: [ec_ioctl_slave_t__bindgen_ty_1; 4usize], 601 | pub fmmu_bit: u8, 602 | pub dc_supported: u8, 603 | pub dc_range: ec_slave_dc_range_t, 604 | pub has_dc_system_time: u8, 605 | pub transmission_delay: u32, 606 | pub al_state: u8, 607 | pub error_flag: u8, 608 | pub sync_count: u8, 609 | pub sdo_count: u16, 610 | pub sii_nwords: u32, 611 | pub group: [::std::os::raw::c_char; 64usize], 612 | pub image: [::std::os::raw::c_char; 64usize], 613 | pub order: [::std::os::raw::c_char; 64usize], 614 | pub name: [::std::os::raw::c_char; 64usize], 615 | } 616 | #[repr(C)] 617 | #[derive(Copy, Clone)] 618 | pub struct ec_ioctl_slave_t__bindgen_ty_1 { 619 | pub desc: ec_slave_port_desc_t, 620 | pub link: ec_slave_port_link_t, 621 | pub receive_time: u32, 622 | pub next_slave: u16, 623 | pub delay_to_next_dc: u32, 624 | } 625 | impl Default for ec_ioctl_slave_t__bindgen_ty_1 { 626 | fn default() -> Self { 627 | let mut s = ::std::mem::MaybeUninit::::uninit(); 628 | unsafe { 629 | ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); 630 | s.assume_init() 631 | } 632 | } 633 | } 634 | impl Default for ec_ioctl_slave_t { 635 | fn default() -> Self { 636 | let mut s = ::std::mem::MaybeUninit::::uninit(); 637 | unsafe { 638 | ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); 639 | s.assume_init() 640 | } 641 | } 642 | } 643 | #[repr(C)] 644 | #[derive(Default, Copy, Clone)] 645 | pub struct ec_ioctl_slave_sync_t { 646 | pub slave_position: u16, 647 | pub sync_index: u32, 648 | pub physical_start_address: u16, 649 | pub default_size: u16, 650 | pub control_register: u8, 651 | pub enable: u8, 652 | pub pdo_count: u8, 653 | } 654 | #[repr(C)] 655 | #[derive(Copy, Clone)] 656 | pub struct ec_ioctl_slave_sync_pdo_t { 657 | pub slave_position: u16, 658 | pub sync_index: u32, 659 | pub pdo_pos: u32, 660 | pub index: u16, 661 | pub entry_count: u8, 662 | pub name: [i8; 64usize], 663 | } 664 | impl Default for ec_ioctl_slave_sync_pdo_t { 665 | fn default() -> Self { 666 | let mut s = ::std::mem::MaybeUninit::::uninit(); 667 | unsafe { 668 | ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); 669 | s.assume_init() 670 | } 671 | } 672 | } 673 | #[repr(C)] 674 | #[derive(Copy, Clone)] 675 | pub struct ec_ioctl_slave_sync_pdo_entry_t { 676 | pub slave_position: u16, 677 | pub sync_index: u32, 678 | pub pdo_pos: u32, 679 | pub entry_pos: u32, 680 | pub index: u16, 681 | pub subindex: u8, 682 | pub bit_length: u8, 683 | pub name: [i8; 64usize], 684 | } 685 | impl Default for ec_ioctl_slave_sync_pdo_entry_t { 686 | fn default() -> Self { 687 | let mut s = ::std::mem::MaybeUninit::::uninit(); 688 | unsafe { 689 | ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); 690 | s.assume_init() 691 | } 692 | } 693 | } 694 | #[repr(C)] 695 | #[derive(Default, Copy, Clone)] 696 | pub struct ec_ioctl_domain_t { 697 | pub index: u32, 698 | pub data_size: u32, 699 | pub logical_base_address: u32, 700 | pub working_counter: [u16; 1usize], 701 | pub expected_working_counter: u16, 702 | pub fmmu_count: u32, 703 | } 704 | #[repr(C)] 705 | #[derive(Copy, Clone)] 706 | pub struct ec_ioctl_domain_fmmu_t { 707 | pub domain_index: u32, 708 | pub fmmu_index: u32, 709 | pub slave_config_alias: u16, 710 | pub slave_config_position: u16, 711 | pub sync_index: u8, 712 | pub dir: ec_direction_t, 713 | pub logical_address: u32, 714 | pub data_size: u32, 715 | } 716 | impl Default for ec_ioctl_domain_fmmu_t { 717 | fn default() -> Self { 718 | let mut s = ::std::mem::MaybeUninit::::uninit(); 719 | unsafe { 720 | ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); 721 | s.assume_init() 722 | } 723 | } 724 | } 725 | #[repr(C)] 726 | #[derive(Copy, Clone)] 727 | pub struct ec_ioctl_domain_data_t { 728 | pub domain_index: u32, 729 | pub data_size: u32, 730 | pub target: *mut u8, 731 | } 732 | impl Default for ec_ioctl_domain_data_t { 733 | fn default() -> Self { 734 | let mut s = ::std::mem::MaybeUninit::::uninit(); 735 | unsafe { 736 | ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); 737 | s.assume_init() 738 | } 739 | } 740 | } 741 | #[repr(C)] 742 | #[derive(Default, Copy, Clone)] 743 | pub struct ec_ioctl_slave_state_t { 744 | pub slave_position: u16, 745 | pub al_state: u8, 746 | } 747 | #[repr(C)] 748 | #[derive(Copy, Clone)] 749 | pub struct ec_ioctl_slave_sdo_t { 750 | pub slave_position: u16, 751 | pub sdo_position: u16, 752 | pub sdo_index: u16, 753 | pub max_subindex: u8, 754 | pub name: [i8; 64usize], 755 | } 756 | impl Default for ec_ioctl_slave_sdo_t { 757 | fn default() -> Self { 758 | let mut s = ::std::mem::MaybeUninit::::uninit(); 759 | unsafe { 760 | ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); 761 | s.assume_init() 762 | } 763 | } 764 | } 765 | #[repr(C)] 766 | #[derive(Copy, Clone)] 767 | pub struct ec_ioctl_slave_sdo_entry_t { 768 | pub slave_position: u16, 769 | pub sdo_spec: ::std::os::raw::c_int, 770 | pub sdo_entry_subindex: u8, 771 | pub data_type: u16, 772 | pub bit_length: u16, 773 | pub read_access: [u8; 3usize], 774 | pub write_access: [u8; 3usize], 775 | pub description: [i8; 64usize], 776 | } 777 | impl Default for ec_ioctl_slave_sdo_entry_t { 778 | fn default() -> Self { 779 | let mut s = ::std::mem::MaybeUninit::::uninit(); 780 | unsafe { 781 | ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); 782 | s.assume_init() 783 | } 784 | } 785 | } 786 | #[repr(C)] 787 | #[derive(Copy, Clone)] 788 | pub struct ec_ioctl_slave_sdo_upload_t { 789 | pub slave_position: u16, 790 | pub sdo_index: u16, 791 | pub sdo_entry_subindex: u8, 792 | pub target_size: usize, 793 | pub target: *mut u8, 794 | pub data_size: usize, 795 | pub abort_code: u32, 796 | } 797 | impl Default for ec_ioctl_slave_sdo_upload_t { 798 | fn default() -> Self { 799 | let mut s = ::std::mem::MaybeUninit::::uninit(); 800 | unsafe { 801 | ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); 802 | s.assume_init() 803 | } 804 | } 805 | } 806 | #[repr(C)] 807 | #[derive(Copy, Clone)] 808 | pub struct ec_ioctl_slave_sdo_download_t { 809 | pub slave_position: u16, 810 | pub sdo_index: u16, 811 | pub sdo_entry_subindex: u8, 812 | pub complete_access: u8, 813 | pub data_size: usize, 814 | pub data: *mut u8, 815 | pub abort_code: u32, 816 | } 817 | impl Default for ec_ioctl_slave_sdo_download_t { 818 | fn default() -> Self { 819 | let mut s = ::std::mem::MaybeUninit::::uninit(); 820 | unsafe { 821 | ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); 822 | s.assume_init() 823 | } 824 | } 825 | } 826 | #[repr(C)] 827 | #[derive(Copy, Clone)] 828 | pub struct ec_ioctl_slave_sii_t { 829 | pub slave_position: u16, 830 | pub offset: u16, 831 | pub nwords: u32, 832 | pub words: *mut u16, 833 | } 834 | impl Default for ec_ioctl_slave_sii_t { 835 | fn default() -> Self { 836 | let mut s = ::std::mem::MaybeUninit::::uninit(); 837 | unsafe { 838 | ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); 839 | s.assume_init() 840 | } 841 | } 842 | } 843 | #[repr(C)] 844 | #[derive(Copy, Clone)] 845 | pub struct ec_ioctl_slave_reg_t { 846 | pub slave_position: u16, 847 | pub emergency: u8, 848 | pub address: u16, 849 | pub size: usize, 850 | pub data: *mut u8, 851 | } 852 | impl Default for ec_ioctl_slave_reg_t { 853 | fn default() -> Self { 854 | let mut s = ::std::mem::MaybeUninit::::uninit(); 855 | unsafe { 856 | ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); 857 | s.assume_init() 858 | } 859 | } 860 | } 861 | #[repr(C)] 862 | #[derive(Copy, Clone)] 863 | pub struct ec_ioctl_slave_foe_t { 864 | pub slave_position: u16, 865 | pub offset: u16, 866 | pub buffer_size: usize, 867 | pub buffer: *mut u8, 868 | pub data_size: usize, 869 | pub result: u32, 870 | pub error_code: u32, 871 | pub file_name: [::std::os::raw::c_char; 32usize], 872 | } 873 | impl Default for ec_ioctl_slave_foe_t { 874 | fn default() -> Self { 875 | let mut s = ::std::mem::MaybeUninit::::uninit(); 876 | unsafe { 877 | ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); 878 | s.assume_init() 879 | } 880 | } 881 | } 882 | #[repr(C)] 883 | #[derive(Copy, Clone)] 884 | pub struct ec_ioctl_slave_soe_read_t { 885 | pub slave_position: u16, 886 | pub drive_no: u8, 887 | pub idn: u16, 888 | pub mem_size: usize, 889 | pub data: *mut u8, 890 | pub data_size: usize, 891 | pub error_code: u16, 892 | } 893 | impl Default for ec_ioctl_slave_soe_read_t { 894 | fn default() -> Self { 895 | let mut s = ::std::mem::MaybeUninit::::uninit(); 896 | unsafe { 897 | ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); 898 | s.assume_init() 899 | } 900 | } 901 | } 902 | #[repr(C)] 903 | #[derive(Copy, Clone)] 904 | pub struct ec_ioctl_slave_soe_write_t { 905 | pub slave_position: u16, 906 | pub drive_no: u8, 907 | pub idn: u16, 908 | pub data_size: usize, 909 | pub data: *mut u8, 910 | pub error_code: u16, 911 | } 912 | impl Default for ec_ioctl_slave_soe_write_t { 913 | fn default() -> Self { 914 | let mut s = ::std::mem::MaybeUninit::::uninit(); 915 | unsafe { 916 | ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); 917 | s.assume_init() 918 | } 919 | } 920 | } 921 | #[repr(C)] 922 | #[derive(Copy, Clone)] 923 | pub struct ec_ioctl_config_t { 924 | pub config_index: u32, 925 | pub alias: u16, 926 | pub position: u16, 927 | pub vendor_id: u32, 928 | pub product_code: u32, 929 | pub syncs: [ec_ioctl_config_t__bindgen_ty_1; 16usize], 930 | pub watchdog_divider: u16, 931 | pub watchdog_intervals: u16, 932 | pub sdo_count: u32, 933 | pub idn_count: u32, 934 | pub flag_count: u32, 935 | pub slave_position: i32, 936 | pub dc_assign_activate: u16, 937 | pub dc_sync: [ec_sync_signal_t; 2usize], 938 | } 939 | #[repr(C)] 940 | #[derive(Copy, Clone)] 941 | pub struct ec_ioctl_config_t__bindgen_ty_1 { 942 | pub dir: ec_direction_t, 943 | pub watchdog_mode: ec_watchdog_mode_t, 944 | pub pdo_count: u32, 945 | pub config_this: u8, 946 | } 947 | impl Default for ec_ioctl_config_t__bindgen_ty_1 { 948 | fn default() -> Self { 949 | let mut s = ::std::mem::MaybeUninit::::uninit(); 950 | unsafe { 951 | ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); 952 | s.assume_init() 953 | } 954 | } 955 | } 956 | impl Default for ec_ioctl_config_t { 957 | fn default() -> Self { 958 | let mut s = ::std::mem::MaybeUninit::::uninit(); 959 | unsafe { 960 | ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); 961 | s.assume_init() 962 | } 963 | } 964 | } 965 | #[repr(C)] 966 | #[derive(Copy, Clone)] 967 | pub struct ec_ioctl_config_pdo_t { 968 | pub config_index: u32, 969 | pub sync_index: u8, 970 | pub pdo_pos: u16, 971 | pub index: u16, 972 | pub entry_count: u8, 973 | pub name: [i8; 64usize], 974 | } 975 | impl Default for ec_ioctl_config_pdo_t { 976 | fn default() -> Self { 977 | let mut s = ::std::mem::MaybeUninit::::uninit(); 978 | unsafe { 979 | ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); 980 | s.assume_init() 981 | } 982 | } 983 | } 984 | #[repr(C)] 985 | #[derive(Copy, Clone)] 986 | pub struct ec_ioctl_config_pdo_entry_t { 987 | pub config_index: u32, 988 | pub sync_index: u8, 989 | pub pdo_pos: u16, 990 | pub entry_pos: u8, 991 | pub index: u16, 992 | pub subindex: u8, 993 | pub bit_length: u8, 994 | pub name: [i8; 64usize], 995 | } 996 | impl Default for ec_ioctl_config_pdo_entry_t { 997 | fn default() -> Self { 998 | let mut s = ::std::mem::MaybeUninit::::uninit(); 999 | unsafe { 1000 | ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); 1001 | s.assume_init() 1002 | } 1003 | } 1004 | } 1005 | #[repr(C)] 1006 | #[derive(Copy, Clone)] 1007 | pub struct ec_ioctl_config_sdo_t { 1008 | pub config_index: u32, 1009 | pub sdo_pos: u32, 1010 | pub index: u16, 1011 | pub subindex: u8, 1012 | pub size: usize, 1013 | pub data: [u8; 1024usize], 1014 | pub complete_access: u8, 1015 | } 1016 | impl Default for ec_ioctl_config_sdo_t { 1017 | fn default() -> Self { 1018 | let mut s = ::std::mem::MaybeUninit::::uninit(); 1019 | unsafe { 1020 | ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); 1021 | s.assume_init() 1022 | } 1023 | } 1024 | } 1025 | #[repr(C)] 1026 | #[derive(Copy, Clone)] 1027 | pub struct ec_ioctl_config_idn_t { 1028 | pub config_index: u32, 1029 | pub idn_pos: u32, 1030 | pub drive_no: u8, 1031 | pub idn: u16, 1032 | pub state: ec_al_state_t, 1033 | pub size: usize, 1034 | pub data: [u8; 1024usize], 1035 | } 1036 | impl Default for ec_ioctl_config_idn_t { 1037 | fn default() -> Self { 1038 | let mut s = ::std::mem::MaybeUninit::::uninit(); 1039 | unsafe { 1040 | ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); 1041 | s.assume_init() 1042 | } 1043 | } 1044 | } 1045 | #[repr(C)] 1046 | #[derive(Copy, Clone)] 1047 | pub struct ec_ioctl_config_flag_t { 1048 | pub config_index: u32, 1049 | pub flag_pos: u32, 1050 | pub key: [::std::os::raw::c_char; 128usize], 1051 | pub value: i32, 1052 | } 1053 | impl Default for ec_ioctl_config_flag_t { 1054 | fn default() -> Self { 1055 | let mut s = ::std::mem::MaybeUninit::::uninit(); 1056 | unsafe { 1057 | ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); 1058 | s.assume_init() 1059 | } 1060 | } 1061 | } 1062 | #[repr(C)] 1063 | #[derive(Default, Copy, Clone)] 1064 | pub struct ec_ioctl_eoe_handler_t { 1065 | pub eoe_index: u16, 1066 | pub name: [::std::os::raw::c_char; 20usize], 1067 | pub slave_position: u16, 1068 | pub open: u8, 1069 | pub rx_bytes: u32, 1070 | pub rx_rate: u32, 1071 | pub tx_bytes: u32, 1072 | pub tx_rate: u32, 1073 | pub tx_queued_frames: u32, 1074 | pub tx_queue_size: u32, 1075 | } 1076 | #[repr(C)] 1077 | #[derive(Default, Copy, Clone)] 1078 | pub struct ec_ioctl_eoe_ip_t { 1079 | pub slave_position: u16, 1080 | pub config_index: u16, 1081 | pub mac_address_included: u8, 1082 | pub ip_address_included: u8, 1083 | pub subnet_mask_included: u8, 1084 | pub gateway_included: u8, 1085 | pub dns_included: u8, 1086 | pub name_included: u8, 1087 | pub mac_address: [::std::os::raw::c_uchar; 6usize], 1088 | pub ip_address: in_addr, 1089 | pub subnet_mask: in_addr, 1090 | pub gateway: in_addr, 1091 | pub dns: in_addr, 1092 | pub name: [::std::os::raw::c_char; 32usize], 1093 | pub result: u16, 1094 | } 1095 | #[repr(C)] 1096 | #[derive(Copy, Clone)] 1097 | pub struct ec_ioctl_master_activate_t { 1098 | pub process_data: *mut ::std::os::raw::c_void, 1099 | pub process_data_size: usize, 1100 | } 1101 | impl Default for ec_ioctl_master_activate_t { 1102 | fn default() -> Self { 1103 | let mut s = ::std::mem::MaybeUninit::::uninit(); 1104 | unsafe { 1105 | ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); 1106 | s.assume_init() 1107 | } 1108 | } 1109 | } 1110 | #[repr(C)] 1111 | #[derive(Default, Copy, Clone)] 1112 | pub struct ec_ioctl_add_pdo_entry_t { 1113 | pub config_index: u32, 1114 | pub pdo_index: u16, 1115 | pub entry_index: u16, 1116 | pub entry_subindex: u8, 1117 | pub entry_bit_length: u8, 1118 | } 1119 | #[repr(C)] 1120 | #[derive(Default, Copy, Clone)] 1121 | pub struct ec_ioctl_reg_pdo_entry_t { 1122 | pub config_index: u32, 1123 | pub entry_index: u16, 1124 | pub entry_subindex: u8, 1125 | pub domain_index: u32, 1126 | pub bit_position: ::std::os::raw::c_uint, 1127 | } 1128 | #[repr(C)] 1129 | #[derive(Default, Copy, Clone)] 1130 | pub struct ec_ioctl_reg_pdo_pos_t { 1131 | pub config_index: u32, 1132 | pub sync_index: u32, 1133 | pub pdo_pos: u32, 1134 | pub entry_pos: u32, 1135 | pub domain_index: u32, 1136 | pub bit_position: ::std::os::raw::c_uint, 1137 | } 1138 | #[repr(C)] 1139 | #[derive(Copy, Clone)] 1140 | pub struct ec_ioctl_sc_sdo_t { 1141 | pub config_index: u32, 1142 | pub index: u16, 1143 | pub subindex: u8, 1144 | pub data: *const u8, 1145 | pub size: usize, 1146 | pub complete_access: u8, 1147 | } 1148 | impl Default for ec_ioctl_sc_sdo_t { 1149 | fn default() -> Self { 1150 | let mut s = ::std::mem::MaybeUninit::::uninit(); 1151 | unsafe { 1152 | ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); 1153 | s.assume_init() 1154 | } 1155 | } 1156 | } 1157 | #[repr(C)] 1158 | #[derive(Copy, Clone)] 1159 | pub struct ec_ioctl_sc_emerg_t { 1160 | pub config_index: u32, 1161 | pub size: usize, 1162 | pub target: *mut u8, 1163 | pub overruns: i32, 1164 | } 1165 | impl Default for ec_ioctl_sc_emerg_t { 1166 | fn default() -> Self { 1167 | let mut s = ::std::mem::MaybeUninit::::uninit(); 1168 | unsafe { 1169 | ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); 1170 | s.assume_init() 1171 | } 1172 | } 1173 | } 1174 | #[repr(C)] 1175 | #[derive(Copy, Clone)] 1176 | pub struct ec_ioctl_sc_state_t { 1177 | pub config_index: u32, 1178 | pub state: *mut ec_slave_config_state_t, 1179 | } 1180 | impl Default for ec_ioctl_sc_state_t { 1181 | fn default() -> Self { 1182 | let mut s = ::std::mem::MaybeUninit::::uninit(); 1183 | unsafe { 1184 | ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); 1185 | s.assume_init() 1186 | } 1187 | } 1188 | } 1189 | #[repr(C)] 1190 | #[derive(Copy, Clone)] 1191 | pub struct ec_ioctl_sc_idn_t { 1192 | pub config_index: u32, 1193 | pub drive_no: u8, 1194 | pub idn: u16, 1195 | pub al_state: ec_al_state_t, 1196 | pub data: *const u8, 1197 | pub size: usize, 1198 | } 1199 | impl Default for ec_ioctl_sc_idn_t { 1200 | fn default() -> Self { 1201 | let mut s = ::std::mem::MaybeUninit::::uninit(); 1202 | unsafe { 1203 | ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); 1204 | s.assume_init() 1205 | } 1206 | } 1207 | } 1208 | #[repr(C)] 1209 | #[derive(Copy, Clone)] 1210 | pub struct ec_ioctl_sc_flag_t { 1211 | pub config_index: u32, 1212 | pub key_size: usize, 1213 | pub key: *mut ::std::os::raw::c_char, 1214 | pub value: i32, 1215 | } 1216 | impl Default for ec_ioctl_sc_flag_t { 1217 | fn default() -> Self { 1218 | let mut s = ::std::mem::MaybeUninit::::uninit(); 1219 | unsafe { 1220 | ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); 1221 | s.assume_init() 1222 | } 1223 | } 1224 | } 1225 | #[repr(C)] 1226 | #[derive(Copy, Clone)] 1227 | pub struct ec_ioctl_sc_state_timeout_t { 1228 | pub config_index: u32, 1229 | pub from_state: ec_al_state_t, 1230 | pub to_state: ec_al_state_t, 1231 | pub timeout_ms: u32, 1232 | } 1233 | impl Default for ec_ioctl_sc_state_timeout_t { 1234 | fn default() -> Self { 1235 | let mut s = ::std::mem::MaybeUninit::::uninit(); 1236 | unsafe { 1237 | ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); 1238 | s.assume_init() 1239 | } 1240 | } 1241 | } 1242 | #[repr(C)] 1243 | #[derive(Copy, Clone)] 1244 | pub struct ec_ioctl_domain_state_t { 1245 | pub domain_index: u32, 1246 | pub state: *mut ec_domain_state_t, 1247 | } 1248 | impl Default for ec_ioctl_domain_state_t { 1249 | fn default() -> Self { 1250 | let mut s = ::std::mem::MaybeUninit::::uninit(); 1251 | unsafe { 1252 | ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); 1253 | s.assume_init() 1254 | } 1255 | } 1256 | } 1257 | #[repr(C)] 1258 | #[derive(Copy, Clone)] 1259 | pub struct ec_ioctl_sdo_request_t { 1260 | pub config_index: u32, 1261 | pub request_index: u32, 1262 | pub sdo_index: u16, 1263 | pub sdo_subindex: u8, 1264 | pub size: usize, 1265 | pub data: *mut u8, 1266 | pub timeout: u32, 1267 | pub state: ec_request_state_t, 1268 | } 1269 | impl Default for ec_ioctl_sdo_request_t { 1270 | fn default() -> Self { 1271 | let mut s = ::std::mem::MaybeUninit::::uninit(); 1272 | unsafe { 1273 | ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); 1274 | s.assume_init() 1275 | } 1276 | } 1277 | } 1278 | #[repr(C)] 1279 | #[derive(Copy, Clone)] 1280 | pub struct ec_ioctl_soe_request_t { 1281 | pub config_index: u32, 1282 | pub request_index: u32, 1283 | pub drive_no: u8, 1284 | pub idn: u16, 1285 | pub size: usize, 1286 | pub data: *mut u8, 1287 | pub timeout: u32, 1288 | pub state: ec_request_state_t, 1289 | } 1290 | impl Default for ec_ioctl_soe_request_t { 1291 | fn default() -> Self { 1292 | let mut s = ::std::mem::MaybeUninit::::uninit(); 1293 | unsafe { 1294 | ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); 1295 | s.assume_init() 1296 | } 1297 | } 1298 | } 1299 | #[repr(C)] 1300 | #[derive(Copy, Clone)] 1301 | pub struct ec_ioctl_reg_request_t { 1302 | pub config_index: u32, 1303 | pub mem_size: usize, 1304 | pub request_index: u32, 1305 | pub data: *mut u8, 1306 | pub state: ec_request_state_t, 1307 | pub new_data: u8, 1308 | pub address: u16, 1309 | pub transfer_size: usize, 1310 | } 1311 | impl Default for ec_ioctl_reg_request_t { 1312 | fn default() -> Self { 1313 | let mut s = ::std::mem::MaybeUninit::::uninit(); 1314 | unsafe { 1315 | ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); 1316 | s.assume_init() 1317 | } 1318 | } 1319 | } 1320 | #[repr(C)] 1321 | #[derive(Copy, Clone)] 1322 | pub struct ec_ioctl_voe_t { 1323 | pub config_index: u32, 1324 | pub voe_index: u32, 1325 | pub vendor_id: *mut u32, 1326 | pub vendor_type: *mut u16, 1327 | pub size: usize, 1328 | pub data: *mut u8, 1329 | pub state: ec_request_state_t, 1330 | } 1331 | impl Default for ec_ioctl_voe_t { 1332 | fn default() -> Self { 1333 | let mut s = ::std::mem::MaybeUninit::::uninit(); 1334 | unsafe { 1335 | ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); 1336 | s.assume_init() 1337 | } 1338 | } 1339 | } 1340 | #[repr(C)] 1341 | #[derive(Copy, Clone)] 1342 | pub struct ec_ioctl_link_state_t { 1343 | pub dev_idx: u32, 1344 | pub state: *mut ec_master_link_state_t, 1345 | } 1346 | impl Default for ec_ioctl_link_state_t { 1347 | fn default() -> Self { 1348 | let mut s = ::std::mem::MaybeUninit::::uninit(); 1349 | unsafe { 1350 | ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); 1351 | s.assume_init() 1352 | } 1353 | } 1354 | } 1355 | --------------------------------------------------------------------------------