///|
/// EtherCAT addressing modes.
/// Auto-increment: slave position relative to first slave (negative offset).
/// Configured: fixed address assigned during configuration.
/// Broadcast: address 0x0000, all slaves respond.
/// Logical: 32-bit address mapped via FMMU.
pub(all) enum AddressType {
AutoIncrement
Configured
Broadcast
Logical
} derive(Eq, Debug)
///|
/// Build a PDU address from auto-increment position (negative offset from first slave).
/// Position 0 = first slave, 1 = second slave, etc.
pub fn auto_increment_address(position : UInt) -> UInt {
// PDU address is serialized as ADP then ADO, and codec writes the 32-bit value as LE.
// Keep ADP/position in the low 16 bits so the wire bytes are [ADP][ADO].
position & 0xFFFFU
}
///|
/// Build a PDU address from configured (fixed) station address and memory offset.
pub fn configured_address(station : UInt, offset : UInt) -> UInt {
// Low 16 bits = ADP/station, high 16 bits = ADO/register offset.
(station & 0xFFFFU) | ((offset & 0xFFFFU) << 16)
}
///|
/// Build a PDU address for broadcast with register/memory offset.
pub fn broadcast_address(offset : UInt) -> UInt {
(offset & 0xFFFFU) << 16
}
///|
/// Build a 32-bit logical address for LRD/LWR/LRW commands.
pub fn logical_address(addr : UInt) -> UInt {
addr
}
///|
/// Extract the position or station address from a PDU address (low 16 bits).
pub fn address_station(addr : UInt) -> UInt {
addr & 0xFFFFU
}
///|
/// Extract the offset from a PDU address (high 16 bits).
pub fn address_offset(addr : UInt) -> UInt {
(addr >> 16) & 0xFFFFU
}
///|
/// Determine which command to use for a read operation given an address type.
pub fn read_command(addr_type : AddressType) -> EcCommand {
match addr_type {
AutoIncrement => APRD
Configured => FPRD
Broadcast => BRD
Logical => LRD
}
}
///|
/// Determine which command to use for a write operation given an address type.
pub fn write_command(addr_type : AddressType) -> EcCommand {
match addr_type {
AutoIncrement => APWR
Configured => FPWR
Broadcast => BWR
Logical => LWR
}
}
///|
/// Determine which command to use for a read-write operation given an address type.
pub fn readwrite_command(addr_type : AddressType) -> EcCommand {
match addr_type {
AutoIncrement => APRW
Configured => FPRW
Broadcast => BRW
Logical => LRW
}
}