First find out if what you are implementing is a Module OR an actual subdevice. For example: Wago's 750-354 is an EtherCAT-Coupler, which is an actual subdevice with pdo-mappings,coe,eeprom etc.
Add the Module Identification of the Module that you are trying to add, as a productId to this match statement and set if it has tx and or rx capabilities correctly (VERY IMPORTANT)
// This is in ethercat-hal/src/devices/wago_750_354.rs get_modules
match ident_iom {
// Add Module idents here:
WAGO_750_1506_PRODUCT_ID => {
module.has_tx = true;
module.has_rx = true;
}
WAGO_750_501_PRODUCT_ID => {
module.has_tx = false;
module.has_rx = true;
}
WAGO_750_652_PRODUCT_ID => {
module.has_tx = true;
module.has_rx = true;
}
_ => println!(
"Wago-750-354 found Unknown/Unimplemented Module: {}",
ident_iom
),
}
If its not yet implemented the code will yell at you.
But how do i know if it has tx or rx? Its pretty simple actually, for most terminals you can infer it from its function.
For example: a DigitalOutput Terminal almost always only has rx, because rx is output for EtherCAT, very confusing i know ... The reverse is also true obviously, a DigitalInput terminal most likely only has tx as it only needs to read. For more complex Terminals simply read the Datasheet and or take a look with TwinCAT, where you can see the process image etc
Create an EtherCatDevice implementation for that Terminal. Examples can be found in ethercat-hal/src/devices/wago_modules/
at a minimum you need all functions implemented and either input or output implementation depending on your terminal.
Call The Constructor of your EthercatDevice Implementation:
// This is in ethercat-hal/src/devices/wago_750_354.rs in init_slot_modules
for module in self.slots {
match module {
Some(m) => {
// Map ModuleIdent's to Terminals
let dev: Arc<RwLock<dyn DynamicEthercatDevice>> = match (
m.vendor_id,
m.product_id,
) {
WAGO_750_501_MODULE_IDENT => {
Arc::new(RwLock::new(wago_750_501::Wago750_501::new()))
}
WAGO_750_1506_MODULE_IDENT => {
Arc::new(RwLock::new(wago_750_1506::Wago750_1506::new()))
}
WAGO_750_652_MODULE_IDENT => {
Arc::new(RwLock::new(wago_750_652::Wago750_652::new()))
}
_ => {
println!(
"{} Missing Implementation for Module Identification: vendor_id: {:?}, module ident: {:?} !",
module_path!(),
m.vendor_id,
m.product_id
);
return;
}
};
At this point you should have implemented RxPdo and or TxPdo Structures that read/write to the couplers process image. Now to actually use the EtherCatDevice you implemented it should be abstracted into higher level logic like a DigitalOutput, DigitalOutputDevice for a digital out terminal.