linuxcnc-ethercat

MDP modular bus couplers (UTRIO UC20, Inovance GL20)

The lcec_mdp_coupler driver supports modular EtherCAT bus couplers that follow the ETG.5001 Modular Device Profile (MDP): one EtherCAT slave hosting up to 32 pluggable I/O modules on a backplane. The couplers differ only in data (slot geometry, module idents, each module’s PDO layout), and all of it comes from the vendor’s ESI file, so the driver works from tables generated by scripts/esi2coupler.py instead of hand-written per-brand code.

Type Coupler VID:PID Slots
UC20 UTRIO UC20-RTU-EC-A 0x00000fc4:0x0100000a 32
GL20 Inovance GL20(GL20S)-RTU-ECT32 0x00100000:0x10f41001 32

Configuration

Each populated slot is described with a <subModule> tag inside the <slave>. id is the backplane slot, counting from 0 next to the coupler; ident is the module’s ident from the vendor ESI; name is used in the module’s pin names (default: the slot id).

<slave idx="7" type="GL20" name="io">
  <subModule id="0" ident="0x10F41024" name="do1"/>
  <subModule id="1" ident="0x10F41024" name="do2"/>
  <subModule id="2" ident="0x10F41010" name="di3"/>
  <subModule id="3" ident="0x10F41010" name="di4"/>
</slave>
<slave idx="4" type="UC20" name="io">
  <subModule id="0" ident="12" name="do1"/>
  <subModule id="2" ident="1"  name="di3"/>
</slave>

The type name is case-sensitive, like every other driver’s.

Slots may be sparse (the UC20 example leaves slot 1 empty). At startup the driver checks that every slot id is below the coupler’s slot count, and that slot ids and names are unique; any violation is a configuration error. The parser rejects an ident the coupler’s module table does not contain.

Module parameters are not supported yet. A <modParam> inside a <subModule> is rejected at parse time; modules run with their power-on defaults (input filters, safe-state outputs, analog ranges). If a module needs a non-default setting, use an <sdoConfig> on the slave for its configuration object (it is re-applied on runtime re-initialization, see below).

HAL pins

Pin names are lcec.<master>.<slave>.<submodule-name>-<kind>-<n>, numbered per module from 0:

Mixed I/O modules export both their digital inputs and outputs. Temperature, counter, serial and fieldbus modules (OTHER and ENC in the generated tables) are mapped into the process image so the byte offsets of the following slots are correct, but they get no pins yet.

Module idents

The generated tables are the source of truth: lcec_mdp_uc20.h (28 modules) and lcec_mdp_gl20.h (43 modules). Each entry lists the ident, the ESI module name and the pin kind. Common ones:

Coupler ident module kind
UC20 0x00000001 UC20-8DI-NP digital in, 8
UC20 0x00000002 UC20-16DI-NP digital in, 16
UC20 0x0000000c UC20-8DO-P digital out, 8
UC20 0x00000004 UC20-16DO-P digital out, 16
UC20 0x00000006 UC20-4AI-U analog in, 4
UC20 0x00000009 UC20-4AO-U analog out, 4
GL20 0x10f41010 GL20(GL20S)-1600END digital in, 16
GL20 0x10f41011 GL20(GL20S)-3200END digital in, 32
GL20 0x10f41024 GL20(GL20S)-0016ETP digital out, 16
GL20 0x10f41060 GL20(GL20S)-0808ETN mixed I/O, 8+8
GL20 0x10f41030 GL20(GL20S)-4AD analog in, 4
GL20 0x10f41040 GL20(GL20S)-4DA analog out, 4

What the driver writes

Runtime re-initialization

The module list is kept in the coupler’s RAM only. The driver provides a proc_reinit hook, so when the coupler loses power or its cable while LinuxCNC runs and then comes back, the module list (and, for couplers that need it, the PDO assignment) is written again before the coupler returns to OP. Watch slave-reconfig, slave-reconfig-count and slave-reconfig-error. This needs the linuxcnc-ethercat EtherCAT master; see runtime-reinit.md.

Adding a coupler

  1. Add the vendor ESI under scripts/esi/ and generate its table: ./scripts/esi2coupler.py --esi scripts/esi/<file>.xml --family <id> > src/devices/lcec_mdp_<id>.h. The <slave type> name is <id> in uppercase.
  2. Include the header and add the family to registrations[] in lcec_mdp_coupler.c.
  3. Add the ESI/header pair to scripts/check-generated-headers.sh, which CI runs to keep the committed header in sync with the generator.
  4. If the hardware behaves in a way the ESI cannot express, add a quirk to its registration and document what was observed: LCEC_MDP_QUIRK_EXPLICIT_SM_ASSIGN writes 0x1C12/0x1C13 by SDO for couplers that ignore the master’s assignment; LCEC_MDP_QUIRK_NO_PDO_ASSIGN gives the master no PDO layout at all, for couplers that reject PDO assignment.