3.6 KiB
Devices
We need to implement devices to communicate, configure, and identify them.
Implementation Checklist
Here is a checklist of what we need to implement:
- Device Port
- derive
#[derive(Debug, Clone, Copy)]
- derive
- Device Struct
struct EL0000- derive
#[derive(Device)]derivesDevicetrait - derive or implement
Debugtrait - field
output_tsTimestamp for the output data (only if the device has outputs) - field
input_tsTimestamp for the input data (only if the device has inputs) - field
txpdoinstance ofEL0000TxPdo(only if the device has inputs) - field
rxpdoinstance ofEL0000RxPdo(only if the device has outputs) - field
configurationinstance ofEL0000Configuration(only if configurable) - implement
NewDevicetrait
- derive
- TxPdo / RxPdo Struct
struct EL0000TxPdoand/orstruct EL0000RxPdo- derive
#[derive(Debug, Clone)] - derive
#[derive(TxPdo)]and/or#[derive(RxPdo)] - fields
- tag with
#[pdo_object_index(0x1...)]for the PDO object index - wrap PDO object in
Option
- tag with
- derive
- PDO Objects
struct EL0000PdoObjector other PDO object structs- derive
#[derive(Debug, Clone, Default, PartialEq)] - derive
#[derive(PdoObject)] - tag with
#[pdo_object(bits = 16)]for the size of the object - implement
TxPdoObjectand/orRxPdoObjecttraits
- derive
- Predefined PDO Assignment
enum EL0000PdoPreset(if supported)- derive
#[derive(Debug, Clone)] - implement
PredefinedPdoAssignment<EL0000TxPdo, EL0000RxPdo>
- derive
- Configuration
struct EL0000Configuration(if supported)- derive
#[derive(Debug, Clone)] - implement
Configurationtrait - field
pdo_assignmentof typeEL0000PdoPreset - fields for the configuration parameters
- derive
- Device Identification Adresses
These are helpful resources:
- Other implementations of similar devices
- Configuration Values: the official datasheet
- Configuration Implementation: Docs
- PDO Schema: The "Process Data" tab in the TwinCAT Software by Beckhoff
- PDO Implementation: Docs
- Identification: Attach the device and read the identity values with QiTech Control in the "Setup > EtherCAT > Devices" tab
ESI Files are not needed but could be an alternative reference, though not a very readable one.
Identity
We need to extract the possible EtherCAT identity values matching this driver implementation and provide them as constants.
Beckhoff has the official vendor ID of 0x2. The product ID is a u32 which is unique for each device like EL0000-...., EL2003-...., EL3001-...., etc.
Hardware revisions or variants (like EL2521-0024) change the revision ID.
There can be multiple revisions for one product ID which should be supported by the driver so we annotate different revision constants with a suffix like _A, _B, _0024_A, etc.
For each revision, we need a tuple combining all three values. This makes pattern matching easier.
pub const EL0000_VENDOR_ID: u32 = 0x2;
pub const EL0000_PRODUCT_ID: u32 = 0x07d83052;
pub const EL0000_REVISION_A: u32 = 0x00110000;
pub const EL0000_IDENTITY_A: SubDeviceIdentityTuple =
(EL0000_VENDOR_ID, EL0000_PRODUCT_ID, EL0000_REVISION_A);
Creation
Add the device constructor to the device_from_subdevice function in the server crate.
This function is used to create the device at runtime.
pub fn (
subdevice_identity_tuple: SubDeviceIdentityTuple,
) -> Result<Arc<RwLock<dyn Device>>, anyhow::Error> {
match subdevice_identity_tuple {
EK0000_IDENTITY_A => Ok(Arc::new(RwLock::new(EL0000::new()))),
// ...
}
}