From 1c661d980e2c2d810b3e7e90269102b7d0c70338 Mon Sep 17 00:00:00 2001 From: Markus Kohlhase Date: Wed, 3 Mar 2021 12:18:18 +0100 Subject: [PATCH 1/6] Simplify types --- README.md | 2 +- src/lib.rs | 190 ++++++++++++++++++++++----------------------------- src/value.rs | 2 +- 3 files changed, 84 insertions(+), 110 deletions(-) diff --git a/README.md b/README.md index 7303aca..268f08c 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,6 @@ Common EtherCAT data structures ## License -Copyright 2021 [slowtec GmbH](https://www.slowtec.de) +Copyright 2020 - 2021 [slowtec GmbH](https://www.slowtec.de) MIT/Apache-2.0 diff --git a/src/lib.rs b/src/lib.rs index 3ec221e..4f81d25 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -85,80 +85,58 @@ impl From for u8 { } } -/// SDO Position +/// Object Position #[derive(Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash)] -pub struct SdoPos(u16); +pub struct ObjectPos(u16); -impl SdoPos { +impl ObjectPos { pub const fn new(p: u16) -> Self { Self(p) } } -impl From for SdoPos { +impl From for ObjectPos { fn from(pos: u16) -> Self { Self(pos) } } -impl From for u16 { - fn from(pos: SdoPos) -> Self { +impl From for u16 { + fn from(pos: ObjectPos) -> Self { pos.0 } } -/// PDO Position +/// Object Entry Position #[derive(Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash)] -pub struct PdoPos(u8); +pub struct EntryPos(u8); -impl PdoPos { +impl EntryPos { pub const fn new(p: u8) -> Self { Self(p) } } -impl From for PdoPos { +impl From for EntryPos { fn from(pos: u8) -> Self { Self(pos) } } -impl From for u8 { - fn from(pos: PdoPos) -> Self { +impl From for u8 { + fn from(pos: EntryPos) -> Self { pos.0 } } -/// PDO Entry Position -#[derive(Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash)] -pub struct PdoEntryPos(u8); - -impl PdoEntryPos { - pub const fn new(p: u8) -> Self { - Self(p) - } -} - -impl From for PdoEntryPos { - fn from(pos: u8) -> Self { - Self(pos) - } -} - -impl From for u8 { - fn from(pos: PdoEntryPos) -> Self { - pos.0 - } -} - -/// SDO Index +/// Object Entry Index #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct SdoIdx { +pub struct EntryIdx { pub idx: Idx, pub sub_idx: SubIdx, } -impl SdoIdx { +impl EntryIdx { pub const fn new(idx: u16, sub: u8) -> Self { Self { idx: Idx::new(idx), @@ -167,97 +145,42 @@ impl SdoIdx { } } -/// SDO Meta Information +/// Object Meta Information #[derive(Debug, Clone, PartialEq)] -pub struct SdoInfo { - pub pos: SdoPos, // TODO: do we need this info here? +pub struct ObjectInfo { + pub pos: ObjectPos, // TODO: do we need this info here? pub idx: Idx, pub max_sub_idx: SubIdx, pub object_code: Option, pub name: String, } -/// SDO Entry Information +/// Object Entry Information #[derive(Debug, Clone, PartialEq)] -pub struct SdoEntryInfo { - pub data_type: DataType, +pub struct EntryInfo { pub bit_len: u16, - pub access: SdoEntryAccess, - pub description: String, + pub name: String, + pub entry_idx: Option, + pub pos: Option, + pub data_type: Option, + pub access: Option, } -/// SDO Entry Address +/// Object Entry Address #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub enum SdoEntryAddr { - ByPos(SdoPos, SubIdx), - ByIdx(SdoIdx), +pub enum EntryAddr { + ByPos(ObjectPos, SubIdx), + ByIdx(EntryIdx), } -/// SDO Entry Access +/// Object Entry Access #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct SdoEntryAccess { +pub struct EntryAccess { pub pre_op: Access, pub safe_op: Access, pub op: Access, } -/// PDO Index -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct PdoIdx(u16); - -impl PdoIdx { - pub const fn new(idx: u16) -> Self { - Self(idx) - } -} - -impl From for PdoIdx { - fn from(idx: u16) -> Self { - Self(idx) - } -} - -/// PDO Meta Information -#[derive(Debug, Clone, PartialEq)] -pub struct PdoInfo { - pub sm: SmIdx, - pub pos: PdoPos, - pub idx: Idx, - pub entry_count: u8, - pub name: String, -} - -/// PDO Entry Meta Information -#[derive(Debug, Clone, PartialEq)] -pub struct PdoEntryInfo { - pub pos: PdoEntryPos, - pub entry_idx: PdoEntryIdx, - pub bit_len: u8, - pub name: String, -} - -impl From for u16 { - fn from(idx: PdoIdx) -> Self { - idx.0 - } -} - -/// PDO Entry Index -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct PdoEntryIdx { - pub idx: Idx, - pub sub_idx: SubIdx, -} - -impl PdoEntryIdx { - pub const fn new(idx: u16, sub: u8) -> Self { - Self { - idx: Idx::new(idx), - sub_idx: SubIdx::new(sub), - } - } -} - /// Domain Index #[derive(Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash)] pub struct DomainIdx(usize); @@ -414,6 +337,49 @@ pub struct Offset { pub bit: u32, } +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct PdoMapping { + /// e.g. 0x1600, 0x1601, ... + pub outputs: Vec, + /// e.g. 0x1A00, 0x1A001, ... + pub inputs: Vec, +} + +impl PdoMapping { + pub fn contains_sdo_entry(&self, sdo: EntryIdx) -> bool { + self.outputs.iter().any(|i| i.contains_sdo_entry(sdo)) + || self.inputs.iter().any(|i| i.contains_sdo_entry(sdo)) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct PdoInfo { + pub idx: EntryIdx, + pub entries: Vec, +} + +impl PdoInfo { + pub fn contains_sdo_entry(&self, sdo: EntryIdx) -> bool { + self.entries.iter().any(|e| e.sdo == sdo) + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct PdoInfoEntry { + pub sdo: EntryIdx, + pub bit_len: usize, +} + +impl From for PdoInfoEntry { + fn from(data: u32) -> Self { + let bit_len = (data & 0x_00FF) as usize; + let obj_idx = (data >> 16) as u16; + let obj_subidx = ((data >> 8) & 0x_0000_00FF) as u8; + let sdo = EntryIdx::new(obj_idx, obj_subidx); + Self { sdo, bit_len } + } +} + /// ESM states #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub enum AlState { @@ -535,4 +501,12 @@ mod tests { assert_eq!(format!("{:?}", Idx::new(0)), "Idx(0x0000)"); assert_eq!(format!("{:?}", Idx::new(u16::MAX)), "Idx(0xFFFF)"); } + + #[test] + fn pdo_info_entry_from_u32() { + let e = PdoInfoEntry::from(0x70000320_u32); + assert_eq!(e.sdo.idx, Idx::new(0x7000)); + assert_eq!(e.sdo.sub_idx, SubIdx::new(0x03)); + assert_eq!(e.bit_len, 32); + } } diff --git a/src/value.rs b/src/value.rs index d23e46c..88d0654 100644 --- a/src/value.rs +++ b/src/value.rs @@ -1,4 +1,4 @@ -/// EtherCAT SDO/PDO Value +/// EtherCAT Value #[derive(Debug, Clone, PartialEq)] pub enum Value { /// BIT From 687ca135bdbc392a204922295e385661904c36d3 Mon Sep 17 00:00:00 2001 From: Markus Kohlhase Date: Wed, 3 Mar 2021 18:00:27 +0100 Subject: [PATCH 2/6] Add ObjectDict --- src/lib.rs | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 4f81d25..3db6e50 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,7 @@ #[macro_use] extern crate num_derive; -use std::{convert::TryFrom, fmt, num::TryFromIntError}; +use std::{collections::HashMap, convert::TryFrom, fmt, num::TryFromIntError}; mod value; @@ -145,11 +145,29 @@ impl EntryIdx { } } +#[derive(Debug, Clone, PartialEq, Default)] +pub struct ObjectDict { + pub objects: HashMap, + pub entries: HashMap, +} + +impl ObjectDict { + pub fn add_obj(&mut self, o: ObjectInfo) { + self.objects.insert(o.idx, o); + } + pub fn add_entry(&mut self, e: EntryInfo) { + self.entries.insert(e.entry_idx, e); + } + pub fn object_entries(&self, idx: Idx) -> impl Iterator { + self.entries.iter().filter(move |(x, _)| x.idx == idx) + } +} + /// Object Meta Information #[derive(Debug, Clone, PartialEq)] pub struct ObjectInfo { - pub pos: ObjectPos, // TODO: do we need this info here? pub idx: Idx, + pub pos: ObjectPos, // TODO: do we need this info here? pub max_sub_idx: SubIdx, pub object_code: Option, pub name: String, @@ -158,9 +176,9 @@ pub struct ObjectInfo { /// Object Entry Information #[derive(Debug, Clone, PartialEq)] pub struct EntryInfo { + pub entry_idx: EntryIdx, pub bit_len: u16, pub name: String, - pub entry_idx: Option, pub pos: Option, pub data_type: Option, pub access: Option, From aaa3a8962f1e210abfe73e1fd462c71deaf1c373 Mon Sep 17 00:00:00 2001 From: Markus Kohlhase Date: Wed, 3 Mar 2021 18:47:25 +0100 Subject: [PATCH 3/6] Fix idx field in PdoInfo --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 3db6e50..ce5896d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -372,7 +372,7 @@ impl PdoMapping { #[derive(Debug, Clone, PartialEq, Eq)] pub struct PdoInfo { - pub idx: EntryIdx, + pub idx: Idx, pub entries: Vec, } From d6173c7cd84ca978f916880267dc3c210144ad07 Mon Sep 17 00:00:00 2001 From: Markus Kohlhase Date: Wed, 3 Mar 2021 18:52:22 +0100 Subject: [PATCH 4/6] Derive Default for PdoMapping --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index ce5896d..bf9117c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -355,7 +355,7 @@ pub struct Offset { pub bit: u32, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Default)] pub struct PdoMapping { /// e.g. 0x1600, 0x1601, ... pub outputs: Vec, From f71950c407a484cf4870557e5712c5c4591319c9 Mon Sep 17 00:00:00 2001 From: Markus Kohlhase Date: Wed, 3 Mar 2021 23:00:55 +0100 Subject: [PATCH 5/6] Rename PdoInfoEntry to PdoEntryInfo --- src/lib.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index bf9117c..dd5232d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -373,7 +373,7 @@ impl PdoMapping { #[derive(Debug, Clone, PartialEq, Eq)] pub struct PdoInfo { pub idx: Idx, - pub entries: Vec, + pub entries: Vec, } impl PdoInfo { @@ -383,12 +383,12 @@ impl PdoInfo { } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct PdoInfoEntry { +pub struct PdoEntryInfo { pub sdo: EntryIdx, pub bit_len: usize, } -impl From for PdoInfoEntry { +impl From for PdoEntryInfo { fn from(data: u32) -> Self { let bit_len = (data & 0x_00FF) as usize; let obj_idx = (data >> 16) as u16; @@ -522,7 +522,7 @@ mod tests { #[test] fn pdo_info_entry_from_u32() { - let e = PdoInfoEntry::from(0x70000320_u32); + let e = PdoEntryInfo::from(0x70000320_u32); assert_eq!(e.sdo.idx, Idx::new(0x7000)); assert_eq!(e.sdo.sub_idx, SubIdx::new(0x03)); assert_eq!(e.bit_len, 32); From b65236a8ddbf14778f21e200094b952ec199c123 Mon Sep 17 00:00:00 2001 From: Markus Kohlhase Date: Wed, 3 Mar 2021 23:01:12 +0100 Subject: [PATCH 6/6] Add PdoAssignment struct --- src/lib.rs | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index dd5232d..7ebda2f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -356,17 +356,37 @@ pub struct Offset { } #[derive(Debug, Clone, PartialEq, Eq, Default)] -pub struct PdoMapping { - /// e.g. 0x1600, 0x1601, ... - pub outputs: Vec, - /// e.g. 0x1A00, 0x1A001, ... - pub inputs: Vec, -} +pub struct PdoMapping(pub Vec>); impl PdoMapping { + pub fn get(&self, slave: SlavePos) -> Option<&Vec> { + self.0.get(usize::from(slave)) + } + pub fn contains_sdo_entry(&self, slave: SlavePos, sdo: EntryIdx) -> bool { + self.get(slave) + .map(|x| x.iter().any(|x| x.contains_sdo_entry(sdo))) + .unwrap_or(false) + } + pub fn outputs(&self, slave: SlavePos) -> Option<&PdoAssignment> { + self.get(slave) + .and_then(|x| x.iter().find(|x| x.sm_type == SmType::Outputs)) + } + pub fn inputs(&self, slave: SlavePos) -> Option<&PdoAssignment> { + self.get(slave) + .and_then(|x| x.iter().find(|x| x.sm_type == SmType::Inputs)) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct PdoAssignment { + pub sm: SmIdx, + pub sm_type: SmType, + pub pdos: Vec, +} + +impl PdoAssignment { pub fn contains_sdo_entry(&self, sdo: EntryIdx) -> bool { - self.outputs.iter().any(|i| i.contains_sdo_entry(sdo)) - || self.inputs.iter().any(|i| i.contains_sdo_entry(sdo)) + self.pdos.iter().any(|i| i.contains_sdo_entry(sdo)) } }