Compare commits

...
3 changed files with 738 additions and 0 deletions

No files matched your search

@@ -0,0 +1,556 @@
// =============================================================================
// WAGO 750-XXX Device Driver Boilerplate
// =============================================================================
//
// HOW TO USE:
// 1. Copy this file and rename it to `wago_750_XXX.rs`
// 2. Find & replace the following placeholders:
// - `Wago750_XXX` -> Your device struct name (e.g. `Wago750_554`)
// - `WAGO_750_XXX` -> Your constant prefix (e.g. `WAGO_750_554`)
// - `750_XXX` -> Your module number (e.g. `750_554`)
// 3. Uncomment one of the device type sections (A through E)
// 4. Delete all other device type sections
// 5. Adjust port count / PDO fields to match your device
// 6. Set PRODUCT_ID at the bottom
// 7. Add `pub mod wago_750_XXX;` to mod.rs
//
// =============================================================================
use crate::devices::{
DynamicEthercatDevice, EthercatDevice, EthercatDeviceProcessing, EthercatDeviceUsed,
EthercatDynamicPDO, Module, NewEthercatDevice, SubDeviceProductTuple,
};
// =============================================================================
// DEVICE TYPE SECTIONS — Uncomment ONE, delete the rest
// =============================================================================
// ╔═══════════════════════════════════════════════════════════════════════════╗
// ║ Section A: Digital Input ║
// ╚═══════════════════════════════════════════════════════════════════════════╝
//
// use crate::io::digital_input::{DigitalInputDevice, DigitalInputInput};
//
// #[derive(Debug, Clone)]
// pub enum Wago750_XXXInputPort {
// DI1,
// DI2,
// DI3,
// DI4,
// }
//
// impl From<Wago750_XXXInputPort> for usize {
// fn from(value: Wago750_XXXInputPort) -> Self {
// match value {
// Wago750_XXXInputPort::DI1 => 0,
// Wago750_XXXInputPort::DI2 => 1,
// Wago750_XXXInputPort::DI3 => 2,
// Wago750_XXXInputPort::DI4 => 3,
// }
// }
// }
//
// #[derive(Clone, Default)]
// pub struct Wago750_XXXTxPdo {
// port1: bool,
// port2: bool,
// port3: bool,
// port4: bool,
// }
//
// impl DigitalInputDevice<Wago750_XXXInputPort> for Wago750_XXX {
// fn get_input(&self, port: Wago750_XXXInputPort) -> Result<DigitalInputInput, anyhow::Error> {
// Ok(DigitalInputInput {
// value: match port {
// Wago750_XXXInputPort::DI1 => self.tx_pdo.port1,
// Wago750_XXXInputPort::DI2 => self.tx_pdo.port2,
// Wago750_XXXInputPort::DI3 => self.tx_pdo.port3,
// Wago750_XXXInputPort::DI4 => self.tx_pdo.port4,
// },
// })
// }
// }
//
// // Paste into EthercatDevice::input():
// // let base = self.tx_bit_offset;
// // self.tx_pdo.port1 = *input.get(base + Into::<usize>::into(Wago750_XXXInputPort::DI1)).expect("Bit 1 out of bounds");
// // self.tx_pdo.port2 = *input.get(base + Into::<usize>::into(Wago750_XXXInputPort::DI2)).expect("Bit 2 out of bounds");
// // self.tx_pdo.port3 = *input.get(base + Into::<usize>::into(Wago750_XXXInputPort::DI3)).expect("Bit 3 out of bounds");
// // self.tx_pdo.port4 = *input.get(base + Into::<usize>::into(Wago750_XXXInputPort::DI4)).expect("Bit 4 out of bounds");
// //
// // input_len: 4 (number of digital input ports)
// // output_len: 0
// // output(): Ok(())
// // Struct fields: tx_pdo: Wago750_XXXTxPdo
// // NewEthercatDevice fields: tx_pdo: Wago750_XXXTxPdo::default()
// ╔═══════════════════════════════════════════════════════════════════════════╗
// ║ Section B: Digital Output ║
// ╚═══════════════════════════════════════════════════════════════════════════╝
//
// use crate::io::digital_output::{DigitalOutputDevice, DigitalOutputOutput};
//
// #[derive(Debug, Clone)]
// pub enum Wago750_XXXOutputPort {
// DO1,
// DO2,
// DO3,
// DO4,
// }
//
// impl From<Wago750_XXXOutputPort> for usize {
// fn from(value: Wago750_XXXOutputPort) -> Self {
// match value {
// Wago750_XXXOutputPort::DO1 => 0,
// Wago750_XXXOutputPort::DO2 => 1,
// Wago750_XXXOutputPort::DO3 => 2,
// Wago750_XXXOutputPort::DO4 => 3,
// }
// }
// }
//
// #[derive(Clone, Default)]
// pub struct Wago750_XXXRxPdo {
// port1: bool,
// port2: bool,
// port3: bool,
// port4: bool,
// }
//
// impl DigitalOutputDevice<Wago750_XXXOutputPort> for Wago750_XXX {
// fn set_output(&mut self, port: Wago750_XXXOutputPort, value: DigitalOutputOutput) {
// let output_value: bool = value.into();
// match port {
// Wago750_XXXOutputPort::DO1 => self.rx_pdo.port1 = output_value,
// Wago750_XXXOutputPort::DO2 => self.rx_pdo.port2 = output_value,
// Wago750_XXXOutputPort::DO3 => self.rx_pdo.port3 = output_value,
// Wago750_XXXOutputPort::DO4 => self.rx_pdo.port4 = output_value,
// }
// }
//
// fn get_output(&self, port: Wago750_XXXOutputPort) -> DigitalOutputOutput {
// let current_value = match port {
// Wago750_XXXOutputPort::DO1 => self.rx_pdo.port1,
// Wago750_XXXOutputPort::DO2 => self.rx_pdo.port2,
// Wago750_XXXOutputPort::DO3 => self.rx_pdo.port3,
// Wago750_XXXOutputPort::DO4 => self.rx_pdo.port4,
// };
// DigitalOutputOutput(current_value)
// }
// }
//
// // Paste into EthercatDevice::output():
// // output.set(self.rx_bit_offset + Into::<usize>::into(Wago750_XXXOutputPort::DO1), self.rx_pdo.port1);
// // output.set(self.rx_bit_offset + Into::<usize>::into(Wago750_XXXOutputPort::DO2), self.rx_pdo.port2);
// // output.set(self.rx_bit_offset + Into::<usize>::into(Wago750_XXXOutputPort::DO3), self.rx_pdo.port3);
// // output.set(self.rx_bit_offset + Into::<usize>::into(Wago750_XXXOutputPort::DO4), self.rx_pdo.port4);
// //
// // input_len: 0
// // output_len: 4 (number of digital output ports)
// // input(): Ok(())
// // Struct fields: rx_pdo: Wago750_XXXRxPdo
// // NewEthercatDevice fields: rx_pdo: Wago750_XXXRxPdo::default()
// ╔═══════════════════════════════════════════════════════════════════════════╗
// ║ Section C: Digital Input + Output (combined) ║
// ╚═══════════════════════════════════════════════════════════════════════════╝
//
// use crate::io::digital_input::{DigitalInputDevice, DigitalInputInput};
// use crate::io::digital_output::{DigitalOutputDevice, DigitalOutputOutput};
//
// #[derive(Debug, Clone)]
// pub enum Wago750_XXXInputPort {
// DI1,
// DI2,
// DI3,
// DI4,
// }
//
// impl From<Wago750_XXXInputPort> for usize {
// fn from(value: Wago750_XXXInputPort) -> Self {
// match value {
// Wago750_XXXInputPort::DI1 => 0,
// Wago750_XXXInputPort::DI2 => 1,
// Wago750_XXXInputPort::DI3 => 2,
// Wago750_XXXInputPort::DI4 => 3,
// }
// }
// }
//
// #[derive(Debug, Clone)]
// pub enum Wago750_XXXOutputPort {
// DO1,
// DO2,
// DO3,
// DO4,
// }
//
// impl From<Wago750_XXXOutputPort> for usize {
// fn from(value: Wago750_XXXOutputPort) -> Self {
// match value {
// Wago750_XXXOutputPort::DO1 => 0,
// Wago750_XXXOutputPort::DO2 => 1,
// Wago750_XXXOutputPort::DO3 => 2,
// Wago750_XXXOutputPort::DO4 => 3,
// }
// }
// }
//
// #[derive(Clone, Default)]
// pub struct Wago750_XXXTxPdo {
// port1: bool,
// port2: bool,
// port3: bool,
// port4: bool,
// }
//
// #[derive(Clone, Default)]
// pub struct Wago750_XXXRxPdo {
// port1: bool,
// port2: bool,
// port3: bool,
// port4: bool,
// }
//
// impl DigitalInputDevice<Wago750_XXXInputPort> for Wago750_XXX {
// fn get_input(&self, port: Wago750_XXXInputPort) -> Result<DigitalInputInput, anyhow::Error> {
// Ok(DigitalInputInput {
// value: match port {
// Wago750_XXXInputPort::DI1 => self.tx_pdo.port1,
// Wago750_XXXInputPort::DI2 => self.tx_pdo.port2,
// Wago750_XXXInputPort::DI3 => self.tx_pdo.port3,
// Wago750_XXXInputPort::DI4 => self.tx_pdo.port4,
// },
// })
// }
// }
//
// impl DigitalOutputDevice<Wago750_XXXOutputPort> for Wago750_XXX {
// fn set_output(&mut self, port: Wago750_XXXOutputPort, value: DigitalOutputOutput) {
// let output_value: bool = value.into();
// match port {
// Wago750_XXXOutputPort::DO1 => self.rx_pdo.port1 = output_value,
// Wago750_XXXOutputPort::DO2 => self.rx_pdo.port2 = output_value,
// Wago750_XXXOutputPort::DO3 => self.rx_pdo.port3 = output_value,
// Wago750_XXXOutputPort::DO4 => self.rx_pdo.port4 = output_value,
// }
// }
//
// fn get_output(&self, port: Wago750_XXXOutputPort) -> DigitalOutputOutput {
// let current_value = match port {
// Wago750_XXXOutputPort::DO1 => self.rx_pdo.port1,
// Wago750_XXXOutputPort::DO2 => self.rx_pdo.port2,
// Wago750_XXXOutputPort::DO3 => self.rx_pdo.port3,
// Wago750_XXXOutputPort::DO4 => self.rx_pdo.port4,
// };
// DigitalOutputOutput(current_value)
// }
// }
//
// // Paste into EthercatDevice::input():
// // let base = self.tx_bit_offset;
// // self.tx_pdo.port1 = *input.get(base + Into::<usize>::into(Wago750_XXXInputPort::DI1)).expect("Bit 1 out of bounds");
// // self.tx_pdo.port2 = *input.get(base + Into::<usize>::into(Wago750_XXXInputPort::DI2)).expect("Bit 2 out of bounds");
// // self.tx_pdo.port3 = *input.get(base + Into::<usize>::into(Wago750_XXXInputPort::DI3)).expect("Bit 3 out of bounds");
// // self.tx_pdo.port4 = *input.get(base + Into::<usize>::into(Wago750_XXXInputPort::DI4)).expect("Bit 4 out of bounds");
// //
// // Paste into EthercatDevice::output():
// // output.set(self.rx_bit_offset + Into::<usize>::into(Wago750_XXXOutputPort::DO1), self.rx_pdo.port1);
// // output.set(self.rx_bit_offset + Into::<usize>::into(Wago750_XXXOutputPort::DO2), self.rx_pdo.port2);
// // output.set(self.rx_bit_offset + Into::<usize>::into(Wago750_XXXOutputPort::DO3), self.rx_pdo.port3);
// // output.set(self.rx_bit_offset + Into::<usize>::into(Wago750_XXXOutputPort::DO4), self.rx_pdo.port4);
// //
// // input_len: 4 (number of digital input ports)
// // output_len: 4 (number of digital output ports)
// // Struct fields: tx_pdo: Wago750_XXXTxPdo, rx_pdo: Wago750_XXXRxPdo
// // NewEthercatDevice fields: tx_pdo: Wago750_XXXTxPdo::default(), rx_pdo: Wago750_XXXRxPdo::default()
// ╔═══════════════════════════════════════════════════════════════════════════╗
// ║ Section D: Analog Input ║
// ╚═══════════════════════════════════════════════════════════════════════════╝
//
// use bitvec::field::BitField;
// use crate::io::analog_input::physical::AnalogInputRange;
// use crate::io::analog_input::{AnalogInputDevice, AnalogInputInput};
//
// #[derive(Debug, Clone)]
// pub enum Wago750_XXXPort {
// AI1,
// AI2,
// AI3,
// AI4,
// }
//
// impl From<Wago750_XXXPort> for usize {
// fn from(value: Wago750_XXXPort) -> Self {
// match value {
// Wago750_XXXPort::AI1 => 0,
// Wago750_XXXPort::AI2 => 16,
// Wago750_XXXPort::AI3 => 32,
// Wago750_XXXPort::AI4 => 48,
// }
// }
// }
//
// #[derive(Clone, Default)]
// pub struct Wago750_XXXTxPdo {
// ai1: u16,
// ai2: u16,
// ai3: u16,
// ai4: u16,
// }
//
// impl AnalogInputDevice<Wago750_XXXPort> for Wago750_XXX {
// fn get_input(&self, port: Wago750_XXXPort) -> AnalogInputInput {
// let raw = match port {
// Wago750_XXXPort::AI1 => self.tx_pdo.ai1,
// Wago750_XXXPort::AI2 => self.tx_pdo.ai2,
// Wago750_XXXPort::AI3 => self.tx_pdo.ai3,
// Wago750_XXXPort::AI4 => self.tx_pdo.ai4,
// };
// let wiring_error = (raw & 0x0003) == 0x0003;
// let raw_value = (raw & 0x7FF0) as i16;
// let normalized = self.analog_input_range().raw_to_normalized(raw_value) as f32;
// AnalogInputInput {
// normalized,
// wiring_error,
// }
// }
//
// fn analog_input_range(&self) -> AnalogInputRange {
// // Adjust to match your device. Common examples:
// // Current 4-20mA: AnalogInputRange::Current { min: ..milliampere(4.0), max: ..milliampere(20.0), min_raw: 0, max_raw: 0x7FF0 }
// // Voltage 0-10V: AnalogInputRange::Voltage { min: ..volt(0.0), max: ..volt(10.0), min_raw: 0, max_raw: 0x7FF0 }
// todo!("Set the analog input range for your device")
// }
// }
//
// // Paste into EthercatDevice::input():
// // let base = self.tx_bit_offset;
// // self.tx_pdo.ai1 = input[base..(base + 16)].load_le::<u16>();
// // self.tx_pdo.ai2 = input[(base + 16)..(base + 32)].load_le::<u16>();
// // self.tx_pdo.ai3 = input[(base + 32)..(base + 48)].load_le::<u16>();
// // self.tx_pdo.ai4 = input[(base + 48)..(base + 64)].load_le::<u16>();
// //
// // input_len: 64 (channels * 16 bits)
// // output_len: 0
// // output(): Ok(())
// // input_checked(): self.input(_input) (delegate, not Ok(()))
// // Struct fields: tx_pdo: Wago750_XXXTxPdo
// // NewEthercatDevice fields: tx_pdo: Wago750_XXXTxPdo::default()
// ╔═══════════════════════════════════════════════════════════════════════════╗
// ║ Section E: Analog Output ║
// ╚═══════════════════════════════════════════════════════════════════════════╝
// AnalogOutputOutput is a newtype around f32 in clip space (0.0..1.0).
// Convert to/from raw u16 using your device's raw range (e.g. 0x0000..0x7FFF).
//
// use bitvec::field::BitField;
// use crate::io::analog_output::{AnalogOutputDevice, AnalogOutputOutput};
//
// #[derive(Debug, Clone)]
// pub enum Wago750_XXXPort {
// AO1,
// AO2,
// AO3,
// AO4,
// }
//
// impl From<Wago750_XXXPort> for usize {
// fn from(value: Wago750_XXXPort) -> Self {
// match value {
// Wago750_XXXPort::AO1 => 0,
// Wago750_XXXPort::AO2 => 16,
// Wago750_XXXPort::AO3 => 32,
// Wago750_XXXPort::AO4 => 48,
// }
// }
// }
//
// #[derive(Clone, Default)]
// pub struct Wago750_XXXRxPdo {
// ao1: u16,
// ao2: u16,
// ao3: u16,
// ao4: u16,
// }
//
// impl AnalogOutputDevice<Wago750_XXXPort> for Wago750_XXX {
// fn set_output(&mut self, port: Wago750_XXXPort, value: AnalogOutputOutput) {
// // Convert clip-space f32 (0.0..1.0) to raw u16 — adjust 0x7FFF to your device's max
// let raw = (value.0.clamp(0.0, 1.0) * 0x7FFF as f32) as u16;
// match port {
// Wago750_XXXPort::AO1 => self.rx_pdo.ao1 = raw,
// Wago750_XXXPort::AO2 => self.rx_pdo.ao2 = raw,
// Wago750_XXXPort::AO3 => self.rx_pdo.ao3 = raw,
// Wago750_XXXPort::AO4 => self.rx_pdo.ao4 = raw,
// }
// }
//
// fn get_output(&self, port: Wago750_XXXPort) -> AnalogOutputOutput {
// let raw = match port {
// Wago750_XXXPort::AO1 => self.rx_pdo.ao1,
// Wago750_XXXPort::AO2 => self.rx_pdo.ao2,
// Wago750_XXXPort::AO3 => self.rx_pdo.ao3,
// Wago750_XXXPort::AO4 => self.rx_pdo.ao4,
// };
// // Convert raw u16 back to clip-space f32 — adjust 0x7FFF to your device's max
// AnalogOutputOutput(raw as f32 / 0x7FFF as f32)
// }
// }
//
// // Paste into EthercatDevice::output():
// // let base = self.rx_bit_offset;
// // output[base..(base + 16)].store_le::<u16>(self.rx_pdo.ao1);
// // output[(base + 16)..(base + 32)].store_le::<u16>(self.rx_pdo.ao2);
// // output[(base + 32)..(base + 48)].store_le::<u16>(self.rx_pdo.ao3);
// // output[(base + 48)..(base + 64)].store_le::<u16>(self.rx_pdo.ao4);
// //
// // input_len: 0
// // output_len: 64 (channels * 16 bits)
// // input(): Ok(())
// // Struct fields: rx_pdo: Wago750_XXXRxPdo
// // NewEthercatDevice fields: rx_pdo: Wago750_XXXRxPdo::default()
// =============================================================================
// Main Device Struct
// =============================================================================
// Add the PDO fields from your chosen section's instructions.
#[derive(Clone)]
pub struct Wago750_XXX {
is_used: bool,
tx_bit_offset: usize,
rx_bit_offset: usize,
module: Option<Module>,
// TODO: add PDO fields from your chosen section above
}
// =============================================================================
// Required Trait Implementations (always needed)
// =============================================================================
// Fill in input()/output()/input_len()/output_len() using the snippets
// from your chosen section's "Paste into" instructions above.
impl DynamicEthercatDevice for Wago750_XXX {}
impl EthercatDynamicPDO for Wago750_XXX {
fn get_tx_offset(&self) -> usize {
self.tx_bit_offset
}
fn get_rx_offset(&self) -> usize {
self.rx_bit_offset
}
fn set_tx_offset(&mut self, offset: usize) {
self.tx_bit_offset = offset
}
fn set_rx_offset(&mut self, offset: usize) {
self.rx_bit_offset = offset
}
}
impl EthercatDeviceUsed for Wago750_XXX {
fn is_used(&self) -> bool {
self.is_used
}
fn set_used(&mut self, used: bool) {
self.is_used = used;
}
}
impl EthercatDevice for Wago750_XXX {
fn input(
&mut self,
_input: &bitvec::prelude::BitSlice<u8, bitvec::prelude::Lsb0>,
) -> Result<(), anyhow::Error> {
// TODO: paste input body from your chosen section
Ok(())
}
fn input_len(&self) -> usize {
todo!("Set input bit length (see section instructions)")
}
fn output(
&self,
_output: &mut bitvec::prelude::BitSlice<u8, bitvec::prelude::Lsb0>,
) -> Result<(), anyhow::Error> {
// TODO: paste output body from your chosen section
Ok(())
}
fn output_len(&self) -> usize {
todo!("Set output bit length (see section instructions)")
}
fn as_any(&self) -> &dyn std::any::Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
self
}
fn is_module(&self) -> bool {
true
}
fn input_checked(
&mut self,
_input: &bitvec::prelude::BitSlice<u8, bitvec::prelude::Lsb0>,
) -> Result<(), anyhow::Error> {
// For analog inputs: self.input(_input)
// For everything else: Ok(())
Ok(())
}
fn output_checked(
&self,
_output: &mut bitvec::prelude::BitSlice<u8, bitvec::prelude::Lsb0>,
) -> Result<(), anyhow::Error> {
Ok(())
}
fn get_module(&self) -> Option<Module> {
self.module.clone()
}
fn set_module(&mut self, module: Module) {
self.tx_bit_offset = module.tx_offset;
self.rx_bit_offset = module.rx_offset;
self.module = Some(module);
}
}
impl EthercatDeviceProcessing for Wago750_XXX {}
impl NewEthercatDevice for Wago750_XXX {
fn new() -> Self {
Self {
is_used: false,
tx_bit_offset: 0,
rx_bit_offset: 0,
module: None,
// TODO: add PDO defaults from your chosen section
}
}
}
impl std::fmt::Debug for Wago750_XXX {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Wago750_XXX")
}
}
// =============================================================================
// Device Identity
// =============================================================================
pub const WAGO_750_XXX_VENDOR_ID: u32 = 0x00000021;
pub const WAGO_750_XXX_PRODUCT_ID: u32 = todo!("Set product ID from ESI file");
pub const WAGO_750_XXX_MODULE_IDENT: SubDeviceProductTuple =
(WAGO_750_XXX_VENDOR_ID, WAGO_750_XXX_PRODUCT_ID);
@@ -5,4 +5,5 @@ pub mod wago_750_430;
pub mod wago_750_455;
pub mod wago_750_501;
pub mod wago_750_530;
pub mod wago_750_550;
pub mod wago_750_652;
@@ -0,0 +1,181 @@
use crate::devices::{
DynamicEthercatDevice, EthercatDevice, EthercatDeviceProcessing, EthercatDeviceUsed,
EthercatDynamicPDO, Module, NewEthercatDevice, SubDeviceProductTuple,
};
use crate::io::analog_output::{AnalogOutputDevice, AnalogOutputOutput};
use bitvec::field::BitField;
#[derive(Debug, Clone)]
pub enum Wago750_550Port {
AO1,
AO2,
}
impl From<Wago750_550Port> for usize {
fn from(value: Wago750_550Port) -> Self {
match value {
Wago750_550Port::AO1 => 0,
Wago750_550Port::AO2 => 16,
}
}
}
#[derive(Clone, Default)]
pub struct Wago750_550RxPdo {
ao1: u16,
ao2: u16,
}
impl AnalogOutputDevice<Wago750_550Port> for Wago750_550 {
fn set_output(&mut self, port: Wago750_550Port, value: AnalogOutputOutput) {
// Convert clip-space f32 (0.0..1.0) to raw u16 (0x0000..0x7FFF)
let raw = (value.0.clamp(0.0, 1.0) * 0x7FFF as f32) as u16;
match port {
Wago750_550Port::AO1 => self.rx_pdo.ao1 = raw,
Wago750_550Port::AO2 => self.rx_pdo.ao2 = raw,
}
}
fn get_output(&self, port: Wago750_550Port) -> AnalogOutputOutput {
let raw = match port {
Wago750_550Port::AO1 => self.rx_pdo.ao1,
Wago750_550Port::AO2 => self.rx_pdo.ao2,
};
// Convert raw u16 back to clip-space f32 (0.0..1.0)
AnalogOutputOutput(raw as f32 / 0x7FFF as f32)
}
}
#[derive(Clone)]
pub struct Wago750_550 {
is_used: bool,
tx_bit_offset: usize,
rx_bit_offset: usize,
module: Option<Module>,
rx_pdo: Wago750_550RxPdo,
}
impl DynamicEthercatDevice for Wago750_550 {}
impl EthercatDynamicPDO for Wago750_550 {
fn get_tx_offset(&self) -> usize {
self.tx_bit_offset
}
fn get_rx_offset(&self) -> usize {
self.rx_bit_offset
}
fn set_tx_offset(&mut self, offset: usize) {
self.tx_bit_offset = offset
}
fn set_rx_offset(&mut self, offset: usize) {
self.rx_bit_offset = offset
}
}
impl EthercatDeviceUsed for Wago750_550 {
fn is_used(&self) -> bool {
self.is_used
}
fn set_used(&mut self, used: bool) {
self.is_used = used;
}
}
impl EthercatDevice for Wago750_550 {
fn input(
&mut self,
_input: &bitvec::prelude::BitSlice<u8, bitvec::prelude::Lsb0>,
) -> Result<(), anyhow::Error> {
Ok(())
}
fn input_len(&self) -> usize {
0
}
fn output(
&self,
output: &mut bitvec::prelude::BitSlice<u8, bitvec::prelude::Lsb0>,
) -> Result<(), anyhow::Error> {
let base = self.rx_bit_offset;
output[base..(base + 16)].store_le::<u16>(self.rx_pdo.ao1);
output[(base + 16)..(base + 32)].store_le::<u16>(self.rx_pdo.ao2);
Ok(())
}
fn output_len(&self) -> usize {
32
}
fn as_any(&self) -> &dyn std::any::Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
self
}
fn is_module(&self) -> bool {
true
}
fn input_checked(
&mut self,
_input: &bitvec::prelude::BitSlice<u8, bitvec::prelude::Lsb0>,
) -> Result<(), anyhow::Error> {
// For analog inputs: self.input(_input)
// For everything else: Ok(())
Ok(())
}
fn output_checked(
&self,
_output: &mut bitvec::prelude::BitSlice<u8, bitvec::prelude::Lsb0>,
) -> Result<(), anyhow::Error> {
Ok(())
}
fn get_module(&self) -> Option<Module> {
self.module.clone()
}
fn set_module(&mut self, module: Module) {
self.tx_bit_offset = module.tx_offset;
self.rx_bit_offset = module.rx_offset;
self.module = Some(module);
}
}
impl EthercatDeviceProcessing for Wago750_550 {}
impl NewEthercatDevice for Wago750_550 {
fn new() -> Self {
Self {
is_used: false,
tx_bit_offset: 0,
rx_bit_offset: 0,
module: None,
rx_pdo: Wago750_550RxPdo::default(),
}
}
}
impl std::fmt::Debug for Wago750_550 {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Wago750_550")
}
}
// =============================================================================
// Device Identity
// =============================================================================
pub const WAGO_750_550_VENDOR_ID: u32 = 0x00000021;
pub const WAGO_750_550_PRODUCT_ID: u32 = todo!("Set product ID from ESI file");
pub const WAGO_750_550_MODULE_IDENT: SubDeviceProductTuple =
(WAGO_750_550_VENDOR_ID, WAGO_750_550_PRODUCT_ID);