Motion Master 6.0.0-alpha.50
Next-generation motion control software
Loading...
Searching...
No Matches
esc_registers.h
Go to the documentation of this file.
1#pragma once
2
3#include <array>
4#include <cstdint>
5#include <nlohmann/json_fwd.hpp>
6#include <string_view>
7
8namespace mm::comm {
9
12 uint16_t address = 0;
13 uint8_t length = 0;
14 std::string_view name;
15 std::string_view
17};
18
26void to_json(nlohmann::json& j, const EscRegister& r);
27
34inline constexpr auto kEscRegisters = std::to_array<EscRegister>({
35 // ── ESC Information ─────────────────────────────────────────────────────
36 {0x0000, 1, "type", "ESC type identifier"},
37 {0x0001, 1, "revision", "ESC revision number"},
38 {0x0002, 2, "build", "ESC build number"},
39 {0x0004, 1, "fmmu_supported", "Number of supported FMMUs"},
40 {0x0005, 1, "sync_manager_count", "Number of supported SyncManagers"},
41 {0x0006, 1, "ram_size", "Internal process data RAM size in kB"},
42 {0x0007, 1, "port_descriptor",
43 "Port type per port (2 bits each: 0=not impl, 1=not configured, 2=EBUS, 3=MII/RMII)"},
44 {0x0008, 2, "esc_features", "Supported feature flags (DC, FMMU bit ops, DC sync, etc.)"},
45
46 // ── Station Addressing ──────────────────────────────────────────────────
47 {0x0010, 2, "configured_station_address",
48 "Node address used for FPRD/FPWR commands (set by master)"},
49 {0x0012, 2, "configured_station_alias",
50 "Alias address; loaded from EEPROM word 0x0004 at reset"},
51
52 // ── Data Link Layer ─────────────────────────────────────────────────────
53 {0x0100, 4, "dl_control", "DL control: loop port control, RX FIFO size, station alias enable"},
54 {0x0108, 2, "physical_rw_offset", "Offset between read and write addresses for R/W commands"},
55 {0x0110, 2, "dl_status",
56 "DL status: EEPROM load ok, link detected, communication established per port"},
57
58 // ── Application Layer ───────────────────────────────────────────────────
59 {0x0120, 2, "al_control",
60 "AL control: state request (1=Init, 2=Pre-Op, 4=Safe-Op, 8=Op) + error ack"},
61 {0x0130, 2, "al_status", "AL status: current EtherCAT state + error indicator"},
62 {0x0132, 2, "dls_user_r5",
63 "DL-user register R5: meaning defined by the application layer (unused by standard AL); "
64 "PDI-writable, master-readable"},
65 {0x0134, 2, "al_status_code", "AL status error code; non-zero when a state transition fails"},
66
67 // ── PDI ─────────────────────────────────────────────────────────────────
68 {0x0140, 1, "pdi_control",
69 "Process data interface type (0=deactivated, 4=digital I/O, 5=SPI slave, 8=async uC, "
70 "0x0A=sync uC, 0x80=on-chip bus)"},
71 {0x0141, 1, "esc_configuration",
72 "ESC configuration: AL status auto-update, enhanced link detect, DC sync/latch"},
73 {0x0150, 4, "pdi_configuration",
74 "PDI configuration: PDI-specific settings (SPI mode / uC bus config) + SYNC/LATCH PDI signal "
75 "config"},
76
77 // ── Interrupt / Event ───────────────────────────────────────────────────
78 {0x0200, 2, "ecat_event_mask", "Mask for ECAT-side IRQ events"},
79 {0x0204, 4, "al_event_mask", "Mask for PDI-side (AL) IRQ events"},
80 {0x0210, 2, "ecat_event_request",
81 "Pending ECAT-side events (DC latch, DL/AL status change, SM events)"},
82 {0x0220, 4, "al_event_request",
83 "Pending PDI-side events (state change, DC, SyncManager change, EEPROM, SM channels 0-15)"},
84
85 // ── Error Counters ──────────────────────────────────────────────────────
86 {0x0300, 8, "rx_error_counter",
87 "Invalid frame and RX error counts for ports 0–3 (1 byte each, pairs per port)"},
88 {0x0308, 4, "previous_error_counter", "Previous error counts for ports 0–3 (1 byte each)"},
89 {0x030C, 1, "malformat_frame_counter", "Counts frames with wrong EtherCAT datagram structure"},
90 {0x030D, 1, "local_problem_counter", "Counts communication problems local to the slave"},
91 {0x0310, 4, "lost_link_counter", "Lost link counts for ports 0–3 (1 byte per port)"},
92
93 // ── Watchdog ────────────────────────────────────────────────────────────
94 {0x0400, 2, "watchdog_divider",
95 "Watchdog clock prescaler (basic tick = 40 ns × (divider + 2))"},
96 {0x0410, 2, "watchdog_time_pdi", "PDI watchdog timeout in watchdog clock ticks"},
97 {0x0420, 2, "watchdog_time_process_data",
98 "Process data (SM) watchdog timeout in watchdog clock ticks"},
99 {0x0440, 2, "watchdog_status_process_data",
100 "Process data watchdog status (bit 0: 0=expired, 1=running)"},
101 {0x0442, 1, "watchdog_counter_process_data", "Number of process data watchdog expirations"},
102 {0x0443, 1, "watchdog_counter_pdi", "Number of PDI watchdog expirations"},
103
104 // ── EEPROM ──────────────────────────────────────────────────────────────
105 {0x0500, 1, "eeprom_configuration", "EEPROM: PDI access enable, force ECAT access"},
106 {0x0502, 2, "eeprom_control_status",
107 "EEPROM command register, write-enable, busy/error status"},
108 {0x0504, 4, "eeprom_address", "EEPROM word address for read/write operations"},
109 {0x0508, 8, "eeprom_data", "EEPROM data buffer (64-bit; 32-bit for older ESCs)"},
110
111 // ── MII Management (optional; PHY register access) ──────────────────────
112 {0x0510, 2, "mii_control_status",
113 "MII management control/status: write-enable, PDI access, link detection, read/write "
114 "operation, error, busy"},
115 {0x0512, 1, "mii_phy_address", "MII: PHY address to access"},
116 {0x0513, 1, "mii_phy_register_address", "MII: PHY register address to access"},
117 {0x0514, 2, "mii_phy_data", "MII: data read from / to be written to the PHY register"},
118 {0x0516, 2, "mii_access",
119 "MII management access: ECAT/PDI access assignment and PDI access state"},
120
121 // ── FMMU 0 (stride 16 bytes for FMMU 1–7) ──────────────────────────────
122 {0x0600, 16, "fmmu0",
123 "FMMU 0: logical addr (4), length (2), start bit (1), stop bit (1), physical addr (2), "
124 "physical start bit (1), type (1), activate (1), reserved (3)"},
125
126 // ── SyncManager 0 (stride 8 bytes for SM 1–7) ──────────────────────────
127 {0x0800, 8, "sm0",
128 "SyncManager 0: physical addr (2), length (2), control (1), status (1), activate (1), PDI "
129 "control (1)"},
130
131 // ── Distributed Clocks ──────────────────────────────────────────────────
132 {0x0900, 4, "dc_receive_time_port0",
133 "DC: local time at port 0 when the last frame arrived (ns, 32-bit)"},
134 {0x0904, 4, "dc_receive_time_port1",
135 "DC: local time at port 1 when the last frame arrived (ns, 32-bit)"},
136 {0x0908, 4, "dc_receive_time_port2",
137 "DC: local time at port 2 when the last frame arrived (ns, 32-bit)"},
138 {0x090C, 4, "dc_receive_time_port3",
139 "DC: local time at port 3 when the last frame arrived (ns, 32-bit)"},
140 {0x0910, 8, "dc_system_time",
141 "DC: local system time copy latched at start-of-frame (ns, 64-bit)"},
142 {0x0918, 8, "dc_receive_time_ecat_unit",
143 "DC: local time at the processing unit when the last frame arrived (ns, 64-bit)"},
144 {0x0920, 8, "dc_system_time_offset",
145 "DC: offset added to local time to derive system time (ns, 64-bit)"},
146 {0x0928, 4, "dc_system_time_delay",
147 "DC: measured propagation delay from reference clock to this ESC (ns)"},
148 {0x092C, 4, "dc_system_time_difference",
149 "DC: filtered difference between local and received system time (ns)"},
150 {0x0930, 2, "dc_speed_counter_start",
151 "DC: speed counter start value for clock drift compensation"},
152 {0x0932, 2, "dc_speed_counter_diff", "DC: current clock period deviation"},
153 {0x0934, 2, "dc_filter_depth",
154 "DC: control-loop filter depths (system-time-difference and speed-counter filtering)"},
155 {0x0980, 1, "dc_cyclic_unit_control", "DC: selects SYNC/LATCH control source (ECAT or PDI)"},
156 {0x0981, 1, "dc_activation", "DC: activate SYNC out unit and pulse generation"},
157 {0x0982, 2, "dc_sync_pulse_length", "DC: SYNC0/SYNC1 pulse duration in units of 10 ns"},
158 {0x0984, 1, "dc_activation_status",
159 "DC: SYNC out unit activation status (SYNC0/SYNC1 activated, start time in future)"},
160 {0x0985, 1, "dc_user_p14", "DC user parameter P14 (implementation-specific)"},
161 {0x098E, 1, "dc_sync0_status", "DC: SYNC0 pulse status; read to acknowledge (ack mode only)"},
162 {0x098F, 1, "dc_sync1_status", "DC: SYNC1 pulse status; read to acknowledge (ack mode only)"},
163 {0x0990, 8, "dc_start_time_cyclic",
164 "DC: system time for first SYNC0 pulse (written by master)"},
165 {0x0998, 8, "dc_next_sync1_pulse", "DC: system time of the next SYNC1 pulse"},
166 {0x09A0, 4, "dc_sync0_cycle_time", "DC: SYNC0 cycle period in ns (0 = single-shot)"},
167 {0x09A4, 4, "dc_sync1_cycle_time", "DC: SYNC1 offset from SYNC0 in ns (0 = same as SYNC0)"},
168 {0x09A8, 1, "dc_latch0_control",
169 "DC: Latch0 mode (0=continuous, 1=single event on positive edge, 2=negative)"},
170 {0x09A9, 1, "dc_latch1_control", "DC: Latch1 mode"},
171 {0x09AE, 1, "dc_latch0_status", "DC: Latch0 edge detection and current pin state"},
172 {0x09AF, 1, "dc_latch1_status", "DC: Latch1 edge detection and current pin state"},
173 {0x09B0, 8, "dc_latch0_time_pos",
174 "DC: system time captured at Latch0 positive edge (ns, 64-bit)"},
175 {0x09B8, 8, "dc_latch0_time_neg",
176 "DC: system time captured at Latch0 negative edge (ns, 64-bit)"},
177 {0x09C0, 8, "dc_latch1_time_pos",
178 "DC: system time captured at Latch1 positive edge (ns, 64-bit)"},
179 {0x09C8, 8, "dc_latch1_time_neg",
180 "DC: system time captured at Latch1 negative edge (ns, 64-bit)"},
181});
182
183} // namespace mm::comm
Definition al_status_codes.cc:5
void to_json(nlohmann::json &j, const AlStatusCode &c)
Serialises an AlStatusCode to JSON.
Definition al_status_codes.cc:7
constexpr auto kEscRegisters
Catalogue of well-known ESC registers.
Definition esc_registers.h:34
Metadata for a single ESC register entry.
Definition esc_registers.h:11
std::string_view description
Human-readable description from ETG.1000.4 / Beckhoff ESC datasheet.
Definition esc_registers.h:16
uint16_t address
Register address in the ESC address space.
Definition esc_registers.h:12
uint8_t length
Width in bytes (1/2/4/8 for scalars; 8/16 for the SM/FMMU blocks).
Definition esc_registers.h:13
std::string_view name
Short snake_case identifier.
Definition esc_registers.h:14