EtherCAT Slave Controller (ESC) register map.
All fixed-size registers are returned as {address, size} tuples so call
sites never need to hard-code a size separately:
{addr, size} = Registers.al_status()
Bus.transaction(bus, Transaction.fprd(station, {addr, size}))Registers whose size is determined at runtime return a bare address integer. Array-indexed registers (SyncManager, FMMU) provide a base-offset function plus named subfield accessors for individual fields within each channel.
References: Beckhoff ETG slave controller datasheet, section II (register description).
Summary
Functions
AL control write — encodes code as a 2-byte little-endian value.
DC Activation register.
DC Activation write — encodes code as a single byte.
DC Cyclic Unit Control / AssignActivate register.
DC Cyclic Unit Control write — encodes code as a 16-bit little-endian value.
LATCH0 control register. bit0=positive edge capture enable, bit1=negative edge capture enable.
LATCH0 control write — encodes control bits as a single byte.
LATCH0 negative-edge timestamp (64-bit, ns since 2000-01-01).
LATCH0 positive-edge timestamp (64-bit, ns since 2000-01-01).
LATCH0 status byte.
LATCH1 control register. bit0=positive edge capture enable, bit1=negative edge capture enable.
LATCH1 control write — encodes control bits as a single byte.
LATCH1 negative-edge timestamp (64-bit, ns since 2000-01-01).
LATCH1 positive-edge timestamp (64-bit, ns since 2000-01-01).
LATCH1 status byte.
Combined LATCH0/LATCH1 event status bytes.
Pulse length of SYNC signals in ns. 0 = acknowledged mode.
Pulse length write — encodes pulse_ns as a 16-bit little-endian value.
Receive time of port n (0–3). Latched on BWR to 0x0900. 32-bit local clock value.
Receive time at ECAT processing unit (64-bit local time). Used for offset calculation.
Trigger receive-time latch on all slaves simultaneously (BWR write).
Speed counter start — PLL bandwidth. Writing any value resets the drift filter.
Speed counter start write — encodes v as a 16-bit little-endian value.
SYNC0 cycle time in ns. 0 = single shot mode.
SYNC0 cycle time write — encodes cycle_ns as a 32-bit little-endian value.
SYNC0 start time — system time of first SYNC0 pulse (64-bit, ns since 2000-01-01).
SYNC0 start time write — encodes start_ns as a 64-bit little-endian value.
SYNC1 cycle time in ns. 0 = disabled. This is the delay from SYNC0 to SYNC1.
SYNC1 cycle time write — encodes cycle_ns as a 32-bit little-endian value.
System time — local copy of DC system time (ns since 2000-01-01). ARMW target for drift.
System time delay — propagation delay from reference clock to this slave. Written by master.
System time delay write — encodes delay_ns as a 32-bit little-endian value.
System time difference — mean deviation between local copy and received system time. Converges to 0.
System time offset — difference between local time and system time. Written by master.
System time offset write — encodes offset_ns as a signed 64-bit little-endian value.
Reset DC system time/system-time offset handling with a 32-bit zero write.
Decode the 2-byte al_status/0 response.
Decode the 8-byte rx_error_counter/0 response into a per-port map.
Base byte offset for FMMU channel index (0-based).
Full FMMU register write: {addr, data} tuple ready for Transaction.fpwr.
Activate field of FMMU index. Write 0x01 to enable.
Length of FMMU index mapping in bytes.
Logical start address of FMMU index (32-bit offset in master logical address space).
Logical start bit of FMMU index (0–7). Use 0 for byte-aligned mapping.
Logical stop bit of FMMU index (0–7). Use 7 for byte-aligned mapping.
Physical start address of FMMU index. Must match the paired SM's start address.
Physical start bit of FMMU index (0–7). Use 0 for byte-aligned mapping.
Reset count consecutive FMMU entries starting at FMMU0.
Type of FMMU index: 0x01=read (master reads from slave), 0x02=write (master writes to slave).
Base byte offset for SyncManager channel index (0-based).
Full SM register write: {addr, data} tuple ready for Transaction.fpwr.
Activate register of SM index. Bit [0]=1 enables the SyncManager.
Activate register write for SM index.
Control register of SM index.
Length field of SM index (buffer size in bytes).
PDI control register of SM index. Bit [0]=1 requests deactivation from PDI.
Reset count consecutive SyncManager entries starting at SM0.
Physical start address field of SM index. Write the RAM address where the SM buffer begins.
Status register of SM index (read-only). Bit [3]=mailbox full, [5:4]=last buffer.
Decode the 2-byte wdt_status/0 response.
Types
@type reg() :: {non_neg_integer(), pos_integer()}
@type reg_write() :: {non_neg_integer(), binary()}
Functions
@spec al_control() :: reg()
@spec al_control(non_neg_integer()) :: reg_write()
AL control write — encodes code as a 2-byte little-endian value.
@spec al_event_mask() :: reg()
@spec al_event_req() :: reg()
@spec al_status() :: reg()
@spec al_status_code() :: reg()
@spec dc_activation() :: reg()
DC Activation register.
Bit layout: bit 0 — cyclic operation enable bit 1 — SYNC0 generation enable bit 2 — SYNC1 generation enable
Common values: 0x01 — cyclic enable only 0x03 — SYNC0 enabled 0x07 — SYNC0 + SYNC1 enabled
@spec dc_activation(non_neg_integer()) :: reg_write()
DC Activation write — encodes code as a single byte.
@spec dc_cyclic_unit_control() :: reg()
DC Cyclic Unit Control / AssignActivate register.
Generic userspace masters typically write 0x0000 here to keep SYNC unit
control on the EtherCAT side before enabling 0x0981. Vendor-specific
AssignActivate words are not modeled by the generic public API.
@spec dc_cyclic_unit_control(non_neg_integer()) :: reg_write()
DC Cyclic Unit Control write — encodes code as a 16-bit little-endian value.
@spec dc_latch0_control() :: reg()
LATCH0 control register. bit0=positive edge capture enable, bit1=negative edge capture enable.
@spec dc_latch0_control(non_neg_integer()) :: reg_write()
LATCH0 control write — encodes control bits as a single byte.
@spec dc_latch0_neg_time() :: reg()
LATCH0 negative-edge timestamp (64-bit, ns since 2000-01-01).
@spec dc_latch0_pos_time() :: reg()
LATCH0 positive-edge timestamp (64-bit, ns since 2000-01-01).
@spec dc_latch0_status() :: reg()
LATCH0 status byte.
@spec dc_latch1_control() :: reg()
LATCH1 control register. bit0=positive edge capture enable, bit1=negative edge capture enable.
@spec dc_latch1_control(non_neg_integer()) :: reg_write()
LATCH1 control write — encodes control bits as a single byte.
@spec dc_latch1_neg_time() :: reg()
LATCH1 negative-edge timestamp (64-bit, ns since 2000-01-01).
@spec dc_latch1_pos_time() :: reg()
LATCH1 positive-edge timestamp (64-bit, ns since 2000-01-01).
@spec dc_latch1_status() :: reg()
LATCH1 status byte.
@spec dc_latch_event_status() :: reg()
Combined LATCH0/LATCH1 event status bytes.
Byte 0 (0x09AE): LATCH0 status bit0 event positive edge captured bit1 event negative edge captured bit2 current pin state
Byte 1 (0x09AF): LATCH1 status bit0 event positive edge captured bit1 event negative edge captured bit2 current pin state
@spec dc_pulse_length() :: reg()
Pulse length of SYNC signals in ns. 0 = acknowledged mode.
@spec dc_pulse_length(non_neg_integer()) :: reg_write()
Pulse length write — encodes pulse_ns as a 16-bit little-endian value.
@spec dc_recv_time(non_neg_integer()) :: reg()
Receive time of port n (0–3). Latched on BWR to 0x0900. 32-bit local clock value.
@spec dc_recv_time_ecat() :: reg()
Receive time at ECAT processing unit (64-bit local time). Used for offset calculation.
@spec dc_recv_time_latch() :: reg_write()
Trigger receive-time latch on all slaves simultaneously (BWR write).
@spec dc_speed_counter_start() :: reg()
Speed counter start — PLL bandwidth. Writing any value resets the drift filter.
@spec dc_speed_counter_start(non_neg_integer()) :: reg_write()
Speed counter start write — encodes v as a 16-bit little-endian value.
@spec dc_sync0_cycle_time() :: reg()
SYNC0 cycle time in ns. 0 = single shot mode.
@spec dc_sync0_cycle_time(non_neg_integer()) :: reg_write()
SYNC0 cycle time write — encodes cycle_ns as a 32-bit little-endian value.
@spec dc_sync0_start_time() :: reg()
SYNC0 start time — system time of first SYNC0 pulse (64-bit, ns since 2000-01-01).
@spec dc_sync0_start_time(non_neg_integer()) :: reg_write()
SYNC0 start time write — encodes start_ns as a 64-bit little-endian value.
@spec dc_sync1_cycle_time() :: reg()
SYNC1 cycle time in ns. 0 = disabled. This is the delay from SYNC0 to SYNC1.
@spec dc_sync1_cycle_time(non_neg_integer()) :: reg_write()
SYNC1 cycle time write — encodes cycle_ns as a 32-bit little-endian value.
@spec dc_system_time() :: reg()
System time — local copy of DC system time (ns since 2000-01-01). ARMW target for drift.
@spec dc_system_time_delay() :: reg()
System time delay — propagation delay from reference clock to this slave. Written by master.
@spec dc_system_time_delay(non_neg_integer()) :: reg_write()
System time delay write — encodes delay_ns as a 32-bit little-endian value.
@spec dc_system_time_diff() :: reg()
System time difference — mean deviation between local copy and received system time. Converges to 0.
@spec dc_system_time_offset() :: reg()
System time offset — difference between local time and system time. Written by master.
System time offset write — encodes offset_ns as a signed 64-bit little-endian value.
@spec dc_system_time_reset() :: reg_write()
Reset DC system time/system-time offset handling with a 32-bit zero write.
@spec dc_time_filter() :: reg()
@spec dc_time_filter(non_neg_integer()) :: reg_write()
@spec decode_al_status(binary()) :: {non_neg_integer(), boolean()}
Decode the 2-byte al_status/0 response.
Returns {al_state, error_indicated?} where al_state is one of:
0x1Init,0x2Pre-Op,0x4Safe-Op,0x8Op
error_indicated? is true when the slave has faulted or refused the
last transition (bit 4 of 0x0130).
@spec decode_rx_errors(binary()) :: %{ port0: integer(), port1: integer(), port2: integer(), port3: integer() }
Decode the 8-byte rx_error_counter/0 response into a per-port map.
Each value is the count of invalid frames received on that port.
@spec dl_alias_control() :: reg()
@spec dl_alias_control(non_neg_integer()) :: reg_write()
@spec dl_control() :: reg()
@spec dl_port_control() :: reg()
@spec dl_port_control(non_neg_integer()) :: reg_write()
@spec dl_status() :: reg()
@spec ecat_event_mask() :: reg()
@spec ecat_event_mask(non_neg_integer()) :: reg_write()
@spec eeprom_address() :: reg()
@spec eeprom_control() :: reg()
@spec eeprom_data() :: non_neg_integer()
@spec eeprom_ecat_access() :: reg()
@spec eeprom_ecat_access(non_neg_integer()) :: reg_write()
@spec eeprom_pdi_access() :: reg()
@spec epu_error_counter() :: reg()
@spec esc_build() :: reg()
@spec esc_revision() :: reg()
@spec esc_type() :: reg()
@spec fmmu(non_neg_integer()) :: non_neg_integer()
Base byte offset for FMMU channel index (0-based).
@spec fmmu(non_neg_integer(), binary()) :: {non_neg_integer(), binary()}
Full FMMU register write: {addr, data} tuple ready for Transaction.fpwr.
@spec fmmu_activate(non_neg_integer()) :: reg()
Activate field of FMMU index. Write 0x01 to enable.
@spec fmmu_count() :: reg()
@spec fmmu_length(non_neg_integer()) :: reg()
Length of FMMU index mapping in bytes.
@spec fmmu_log_start(non_neg_integer()) :: reg()
Logical start address of FMMU index (32-bit offset in master logical address space).
@spec fmmu_log_start_bit(non_neg_integer()) :: reg()
Logical start bit of FMMU index (0–7). Use 0 for byte-aligned mapping.
@spec fmmu_log_stop_bit(non_neg_integer()) :: reg()
Logical stop bit of FMMU index (0–7). Use 7 for byte-aligned mapping.
@spec fmmu_phys_start(non_neg_integer()) :: reg()
Physical start address of FMMU index. Must match the paired SM's start address.
@spec fmmu_phys_start_bit(non_neg_integer()) :: reg()
Physical start bit of FMMU index (0–7). Use 0 for byte-aligned mapping.
@spec fmmu_reset(pos_integer()) :: reg_write()
Reset count consecutive FMMU entries starting at FMMU0.
@spec fmmu_type(non_neg_integer()) :: reg()
Type of FMMU index: 0x01=read (master reads from slave), 0x02=write (master writes to slave).
@spec fwd_rx_error_counter() :: reg()
@spec lost_link_counter() :: reg()
@spec pd_ram() :: non_neg_integer()
@spec pdi_error_counter() :: reg()
@spec port_descriptor() :: reg()
@spec ram_size() :: reg()
@spec rx_error_counter() :: reg()
@spec rx_error_counter_clear() :: reg_write()
@spec sm(non_neg_integer()) :: non_neg_integer()
Base byte offset for SyncManager channel index (0-based).
@spec sm(non_neg_integer(), binary()) :: {non_neg_integer(), binary()}
Full SM register write: {addr, data} tuple ready for Transaction.fpwr.
@spec sm_activate(non_neg_integer()) :: reg()
Activate register of SM index. Bit [0]=1 enables the SyncManager.
@spec sm_activate(non_neg_integer(), 0 | 1) :: reg_write()
Activate register write for SM index.
@spec sm_control(non_neg_integer()) :: reg()
Control register of SM index.
Bit layout: [1:0] mode — 0b00=buffered (3-buffer), 0b10=mailbox [3:2] direction — 0b00=ECAT reads/PDI writes, 0b01=ECAT writes/PDI reads [4] ECAT interrupt enable [5] AL event interrupt enable [6] watchdog trigger enable [7] sequential mode
@spec sm_count() :: reg()
@spec sm_length(non_neg_integer()) :: reg()
Length field of SM index (buffer size in bytes).
@spec sm_pdi_control(non_neg_integer()) :: reg()
PDI control register of SM index. Bit [0]=1 requests deactivation from PDI.
@spec sm_reset(pos_integer()) :: reg_write()
Reset count consecutive SyncManager entries starting at SM0.
@spec sm_start(non_neg_integer()) :: reg()
Physical start address field of SM index. Write the RAM address where the SM buffer begins.
@spec sm_status(non_neg_integer()) :: reg()
Status register of SM index (read-only). Bit [3]=mailbox full, [5:4]=last buffer.
@spec station_address() :: reg()
@spec station_address(non_neg_integer()) :: reg_write()
@spec station_alias() :: reg()
@spec wdt_divider() :: reg()
@spec wdt_pdi() :: reg()
@spec wdt_sm() :: reg()
@spec wdt_status() :: reg()
Decode the 2-byte wdt_status/0 response.
Returns true when the SyncManager watchdog has expired (bit 0 of 0x0440).