Motion Master 6.0.0-alpha.86
Next-generation motion control software
Loading...
Searching...
No Matches
mm::etg Namespace Reference

Classes

struct  Access
 An <Access> element together with its two restriction attributes. More...
 
struct  EniCoeCmd
 One CoE transfer the master runs at a transition (ENI CoE/InitCmds/InitCmd). More...
 
struct  EniCyclic
 The cyclic task that exchanges process data (ENI Config/Cyclic). More...
 
struct  EniCyclicCmd
 One datagram of a cyclic frame (ENI Cyclic/Frame/Cmd). More...
 
struct  EniDc
 A device's distributed-clock configuration (ENI Slave/DC). More...
 
struct  EniEcatCmd
 One EtherCAT datagram the master sends at a transition (ENI ECatCmdType). More...
 
struct  EniEoe
 The virtual Ethernet switch the master runs for Ethernet over EtherCAT (ENI Master/EoE). More...
 
struct  EniFrame
 One cyclic frame (ENI Cyclic/Frame). More...
 
struct  EniMailbox
 A device's mailbox configuration (ENI Slave/Mailbox). More...
 
struct  EniMailboxStates
 The master's cyclic check of every mailbox on the bus (ENI Master/MailboxStates). More...
 
struct  EniMailboxWindow
 One mailbox window of a device (ENI MailboxSendInfoType / MailboxRecvInfoType). More...
 
struct  EniMaster
 The master itself (ENI Config/Master). More...
 
struct  EniNetwork
 A complete network configuration (ENI EtherCATConfig/Config). More...
 
struct  EniPdo
 One process-data object of a device (ENI PdoType). More...
 
struct  EniPdoEntry
 One object mapped into a PDO (ENI EntryType). More...
 
struct  EniPreviousPort
 Where this device sits in the ring (ENI Slave/PreviousPort). More...
 
struct  EniProcessData
 A device's process-data description (ENI Slave/ProcessData). More...
 
struct  EniProcessDataWindow
 Where one device's process data sits in the master's image (ENI ProcessData/Send or ProcessData/Recv). More...
 
struct  EniProcessImage
 The master's process image (ENI Config/ProcessImage). More...
 
struct  EniProcessImageArea
 One half of the master's process image (ENI ProcessImage/Inputs or /Outputs). More...
 
struct  EniRead
 A network read out of an ENI document, and what the document held that this model does not. More...
 
struct  EniSlave
 One device on the bus (ENI Config/Slave). More...
 
struct  EniSlaveInfo
 A device's identity (ENI Slave/Info). More...
 
struct  EniSyncManager
 One Sync Manager of a device (ENI SyncManagerSettings). More...
 
struct  EniValidate
 The value a read init command must return before the master goes on (ENI Validate). More...
 
struct  EniVariable
 One named value in the master's process image (ENI ProcessImage Variable). More...
 
struct  EsiDataType
 A dictionary-scoped type definition (ETG.2000 DataTypeType). More...
 
struct  EsiDevice
 One device description (ETG.2000 DeviceType) — the dictionary-relevant subset. More...
 
struct  EsiDictionary
 A CoE object dictionary (ETG.2000 DictionaryType). More...
 
struct  EsiEntry
 One (index, subindex) row of a device's fully expanded object dictionary. More...
 
struct  EsiEntryOptions
 Knobs for buildDeviceEntries. More...
 
struct  EsiEntrySource
 Which dictionary an entry came from. More...
 
struct  EsiEntryTable
 A device's flat dictionary, plus everything questionable found while building it. More...
 
struct  EsiEnumOption
 One label/value pair of an enumerated entry. More...
 
struct  EsiFile
 A parsed ESI file. More...
 
struct  EsiModule
 One module description (ETG.2000 ModuleType). More...
 
struct  EsiObject
 One object-dictionary object (ETG.2000 ObjectType). More...
 
struct  EsiParseRequest
 What a caller wants back from an ESI document. More...
 
struct  EsiPdo
 A process-data object (ETG.2000 PdoType) — an <RxPdo>, <TxPdo>, or <SafetyParaMapping>, which all reuse the same schema type. More...
 
struct  EsiProfile
 A device or module profile (ETG.2000 ProfileType). More...
 
struct  EsiSlots
 The <Slots> block of a modular device (ETG.5001). More...
 
struct  MailboxCoe
 CoE mailbox capabilities (Mailbox/CoE attributes). More...
 
struct  PrimitiveType
 One primitive type: its ESI spelling and the CoE numbering it maps onto. More...
 
struct  Property
 A name/value annotation (ETG.2000 PropertyType). More...
 
struct  Text
 EtherCAT Slave Information (ESI) — the vendor's XML description of a device family. More...
 
struct  UnitNotation
 One entry of the built-in ETG.1004 notation catalogue. More...
 
struct  UnitParts
 The four bytes of an ETG.1004 unit notation value, split out. More...
 
struct  UnitType
 A dictionary-local unit definition (ETG.2000 UnitType, Dictionary/UnitTypes). More...
 

Enumerations

enum class  EniTransition : std::uint8_t {
  II , IP , PP , PO ,
  PS , PI , SS , SP ,
  SO , SI , OS , OP ,
  OI , IB , BI
}
 EtherCAT Network Information (ENI) — the configuration a master replays to start a bus. More...
 
enum class  EniCmd : std::uint8_t {
  Nop = 0 , Aprd = 1 , Apwr = 2 , Aprw = 3 ,
  Fprd = 4 , Fpwr = 5 , Fprw = 6 , Brd = 7 ,
  Bwr = 8 , Brw = 9 , Lrd = 10 , Lwr = 11 ,
  Lrw = 12 , Armw = 13 , Frmw = 14
}
 EtherCAT command type of an init or cyclic command (ENI Cmd, ETG.2100 Table 21). More...
 
enum class  EniRequires : std::uint8_t { None , Frame , Cycle }
 Whether an init command needs a frame or a cycle of its own (ENI <Requires>). More...
 
enum class  EniState : std::uint8_t { Init , PreOp , SafeOp , Op }
 An AL state a cyclic command is sent in (ENI Cyclic/Frame/Cmd/State). More...
 
enum class  EniSyncManagerType : std::uint8_t { MailboxOut , MailboxIn , Outputs , Inputs }
 What a Sync Manager carries (ENI SyncManagerSettings/Type). More...
 
enum class  EniMailboxProtocol : std::uint8_t {
  Aoe , Eoe , Coe , Soe ,
  Foe , Voe
}
 A mailbox protocol a device supports (ENI Mailbox/Protocol). More...
 
enum class  EniCoeCommandSpecifier : std::uint8_t { Download = 1 , Upload = 2 }
 The CoE command specifier of a mailbox init command (ENI Ccs). More...
 
enum class  EniPort : std::uint8_t { A , B , C , D }
 A port of the device upstream of this one (ENI Slave/PreviousPort Port). More...
 
enum class  AccessMode : uint8_t { Ro , Rw , Wo }
 SDO access mode — the text of a <Access> element. Spec default Ro. More...
 
enum class  StateRestriction : uint8_t {
  None , PreOp , PreOpSafeOp , PreOpOp ,
  SafeOp , SafeOpOp , Op
}
 AL-state restriction on a read or a write (Access/@ReadRestrictions, Access/@WriteRestrictions). More...
 
enum class  Category : uint8_t { Mandatory , Optional , Conditional }
 Whether an entry must be implemented (Flags/Category). Spec default Optional. More...
 
enum class  PdoMapping : uint8_t { None , Tx , Rx , TxRx }
 PDO mappability (Flags/PdoMapping). Spec default None — not mappable. More...
 
enum class  SafetyMapping : uint8_t {
  None , SafeIn , SafeOut , SafeInOut ,
  SafeParam
}
 Safety mappability (Flags/SafetyMapping, ETG.5120). Spec default None. More...
 
enum class  SdoAccess : uint8_t { SubIndexAccess , CompleteAccess }
 SDO transfer granularity (Object/Flags/SdoAccess). More...
 
enum class  ObjectCode : uint16_t { Var = 0x07 , Array = 0x08 , Record = 0x09 }
 CoE object code (ETG.1000.6 §5 Table 41 "Object Code"). More...
 
enum class  ValueKind : uint8_t {
  Bool , Int8 , Int16 , Int32 ,
  Int64 , Uint8 , Uint16 , Uint32 ,
  Uint64 , Real32 , Real64 , String ,
  Bytes
}
 The C++ type an entry's value maps to. More...
 
enum class  EsiCollisionPolicy : uint8_t { LastWins , FirstWins , Error }
 What to do when two dictionaries declare the same (index, subindex). More...
 

Functions

void to_json (nlohmann::json &j, const EniNetwork &network)
 Serialises a network as JSON, for a client that renders rather than replays it.
 
std::string eniPhysics (std::uint16_t physicalPort)
 Renders the ENI Physics string for a device from its SII physical-port word.
 
std::expected< std::string, std::string > writeEni (const EniNetwork &network)
 Renders a network as an ENI document.
 
std::expected< EniRead, std::string > readEni (std::string_view xml)
 Reads an ENI document into a network.
 
std::string_view esiText (const std::vector< Text > &texts, uint32_t lcId=kDefaultLcId)
 Picks the lcId text from texts, else the unlocalised/default one, else the first.
 
std::expected< EsiFile, std::string > parseEsi (std::string_view xml)
 Parses an ESI XML document.
 
std::expected< EsiFile, std::string > parseEsiFile (const std::filesystem::path &path)
 Reads path and parses it with parseEsi.
 
const EsiDevicefindEsiDevice (const EsiFile &file, std::string_view type)
 Finds the device whose <Type> text equals type (case-sensitive).
 
const EsiDevicefindEsiDeviceByProductCode (const EsiFile &file, uint32_t productCode, std::optional< uint32_t > revisionNo=std::nullopt)
 Finds the device with product code productCode, optionally pinned to a revision.
 
const EsiModulefindEsiModule (const EsiFile &file, uint32_t moduleIdent)
 Finds the module with the given ModuleIdent.
 
std::vector< uint32_t > esiSlotModuleIdents (const EsiDevice &device)
 Returns every ModuleIdent referenced by any of device's slots, in slot order.
 
std::string_view arrayElementTypeName (std::string_view esiName)
 Returns the element type name of an "ARRAY [a..b] OF T" composition, else empty.
 
bool isStringTypeName (std::string_view esiName)
 True when esiName is a parameterised string type — STRING(n) / OCTET_STRING(n) / UNICODE_STRING(n).
 
std::optional< PrimitiveTyperesolvePrimitiveType (std::string_view esiName)
 Resolves an ESI type name to its CoE code, width and signedness.
 
ValueKind resolveValueKind (uint16_t dataType, uint16_t bitSize)
 Resolves the C++ type an entry holds, from its ETG.1020 code and declared width.
 
void to_json (nlohmann::json &j, const PrimitiveType &type)
 Serialises a PrimitiveType to JSON (name, code, bitSize, isSigned).
 
constexpr std::string_view objectCodeName (ObjectCode code)
 Returns the ESI/CiA spelling of code"VAR", "ARRAY" or "RECORD".
 
constexpr std::string_view cxxTypeName (ValueKind kind)
 The C++ spelling of kind"int32_t", "std::string", "std::vector<uint8_t>".
 
std::expected< EsiEntryTable, std::string > buildDeviceEntries (const EsiFile &file, const EsiDevice &device, const EsiEntryOptions &options={})
 Expands a device into a flat, slot-merged vector of object-dictionary entries.
 
std::expected< std::vector< uint32_t >, std::string > parseIdentList (std::string_view csv)
 Parses a comma-separated list of hex-or-decimal values, as a query parameter carries it.
 
std::expected< nlohmann::json, std::string > buildEsiResponse (std::string_view xml, const EsiParseRequest &request, const EsiEntryOptions &options={})
 Parses an ESI document and renders it as JSON.
 
std::string esiUnitSymbol (uint32_t unit, std::span< const UnitType > local={})
 Renders a packed unit notation value as a display symbol.
 
void to_json (nlohmann::json &j, const UnitType &unit)
 Serialises a UnitType to JSON (notationIndex, index, name, symbol).
 
constexpr UnitParts esiUnitParts (uint32_t unit)
 Splits a packed ETG.1004 unit notation value into its four bytes.
 
void to_json (nlohmann::json &j, const Text &v)
 Serialises the model to JSON. Keys are lowerCamelCase mirrors of the member names; absent optionals are omitted rather than emitted as null.
 
void to_json (nlohmann::json &j, const Property &v)
 
void to_json (nlohmann::json &j, const Access &v)
 
void to_json (nlohmann::json &j, const MailboxCoe &v)
 
void to_json (nlohmann::json &j, const EsiObject::Flags &v)
 
void to_json (nlohmann::json &j, const EsiDataType::SubItem::Flags &v)
 
void to_json (nlohmann::json &j, const EsiObject::Info::SubItem &v)
 
void to_json (nlohmann::json &j, const EsiObject::Info &v)
 
void to_json (nlohmann::json &j, const EsiObject &v)
 
void to_json (nlohmann::json &j, const EsiDataType::SubItem &v)
 
void to_json (nlohmann::json &j, const EsiDataType::ArrayInfo &v)
 
void to_json (nlohmann::json &j, const EsiDataType::EnumInfo &v)
 
void to_json (nlohmann::json &j, const EsiDataType &v)
 
void to_json (nlohmann::json &j, const EsiDictionary &v)
 
void to_json (nlohmann::json &j, const EsiProfile &v)
 
void to_json (nlohmann::json &j, const EsiPdo::Entry &v)
 
void to_json (nlohmann::json &j, const EsiPdo &v)
 
void to_json (nlohmann::json &j, const EsiSlots::Slot &v)
 
void to_json (nlohmann::json &j, const EsiSlots::ModulePdoGroup &v)
 
void to_json (nlohmann::json &j, const EsiSlots &v)
 
void to_json (nlohmann::json &j, const EsiDevice &v)
 
void to_json (nlohmann::json &j, const EsiModule &v)
 
void to_json (nlohmann::json &j, const EsiFile::Vendor &v)
 
void to_json (nlohmann::json &j, const EsiFile &v)
 
constexpr std::string_view accessModeName (AccessMode v)
 Symbolic names for the flag enums, in their ESI spelling ("ro", "m", "tr", …).
 
constexpr std::string_view categoryName (Category v)
 
constexpr std::string_view pdoMappingName (PdoMapping v)
 
constexpr std::string_view safetyMappingName (SafetyMapping v)
 
constexpr std::string_view sdoAccessName (SdoAccess v)
 
constexpr std::string_view stateRestrictionName (StateRestriction v)
 
void to_json (nlohmann::json &j, const EsiEnumOption &v)
 Serialises an entry to JSON. Raw byte vectors are emitted as uppercase hexBinary strings, the same spelling the ESI itself uses; absent optionals are omitted.
 
void to_json (nlohmann::json &j, const EsiEntrySource &v)
 
void to_json (nlohmann::json &j, const EsiEntry &v)
 
void to_json (nlohmann::json &j, const EsiEntryTable &v)
 

Variables

constexpr uint32_t kDefaultLcId = 1033
 The default LcId — 1033, en-US.
 
constexpr auto kPrimitiveTypes
 Catalogue of the ESI primitive types, keyed by their IEC 61131-3 name.
 

Enumeration Type Documentation

◆ AccessMode

enum class mm::etg::AccessMode : uint8_t
strong

SDO access mode — the text of a <Access> element. Spec default Ro.

Enumerator
Ro 
Rw 
Wo 

◆ Category

enum class mm::etg::Category : uint8_t
strong

Whether an entry must be implemented (Flags/Category). Spec default Optional.

Enumerator
Mandatory 
Optional 
Conditional 

◆ EniCmd

enum class mm::etg::EniCmd : std::uint8_t
strong

EtherCAT command type of an init or cyclic command (ENI Cmd, ETG.2100 Table 21).

The addressing mode is part of the command: Aprd and Apwr address by position in the ring, Fprd and Fpwr by configured station address, the B commands address every device at once, and the L commands address logical memory. A read-write command performs its read before its write.

Enumerator
Nop 

No operation.

Aprd 

Auto-increment physical read.

Apwr 

Auto-increment physical write.

Aprw 

Auto-increment physical read-write.

Fprd 

Configured-address physical read.

Fpwr 

Configured-address physical write.

Fprw 

Configured-address physical read-write.

Brd 

Broadcast read.

Bwr 

Broadcast write.

Brw 

Broadcast read-write.

Lrd 

Logical-memory read.

Lwr 

Logical-memory write.

Lrw 

Logical-memory read-write.

Armw 

Auto-increment physical read, multiple write.

Frmw 

Configured-address physical read, multiple write.

◆ EniCoeCommandSpecifier

enum class mm::etg::EniCoeCommandSpecifier : std::uint8_t
strong

The CoE command specifier of a mailbox init command (ENI Ccs).

The values are CoE's own, from ETG.1000.6: 1 initiates a download, which writes to the device. ETG.2100 Table 20 states the opposite — it labels 1 as an upload and 2 as a download. The coding here follows ETG.1000.6, which owns the CoE protocol, and the ENI files ETG ships as samples agree with it: each one carries a payload under a Ccs of 1, and an upload request has no payload to carry.

Enumerator
Download 

SDO initiate download: the master writes data to the object.

Upload 

SDO initiate upload: the master reads the object.

◆ EniMailboxProtocol

enum class mm::etg::EniMailboxProtocol : std::uint8_t
strong

A mailbox protocol a device supports (ENI Mailbox/Protocol).

Enumerator
Aoe 

ADS over EtherCAT.

Eoe 

Ethernet over EtherCAT.

Coe 

CANopen over EtherCAT.

Soe 

Servo Profile over EtherCAT.

Foe 

File Access over EtherCAT.

Voe 

Vendor-specific over EtherCAT.

◆ EniPort

enum class mm::etg::EniPort : std::uint8_t
strong

A port of the device upstream of this one (ENI Slave/PreviousPort Port).

The letters are the ENI's own spelling of port numbers 0 to 3. A is spec-legal and schema-invalid: ETG.2100 Table 29 allows all four, and ENI Schema 1.7 enumerates only B, C and D. writeEni therefore refuses A, while a reader should accept it — reading a document somebody else wrote is the case that needs the tolerance.

Enumerator

Port 0. Rejected by the schema; see above.

Port 1.

Port 2.

Port 3.

◆ EniRequires

enum class mm::etg::EniRequires : std::uint8_t
strong

Whether an init command needs a frame or a cycle of its own (ENI <Requires>).

Enumerator
None 

No requirement; the element is not written and the command may share a frame.

Frame 

The command requires a separate frame.

Cycle 

The command requires a separate cycle.

◆ EniState

enum class mm::etg::EniState : std::uint8_t
strong

An AL state a cyclic command is sent in (ENI Cyclic/Frame/Cmd/State).

Enumerator
Init 

INIT.

PreOp 

PRE-OP.

SafeOp 

SAFE-OP.

Op 

OP.

◆ EniSyncManagerType

enum class mm::etg::EniSyncManagerType : std::uint8_t
strong

What a Sync Manager carries (ENI SyncManagerSettings/Type).

Enumerator
MailboxOut 

Master-to-device mailbox.

MailboxIn 

Device-to-master mailbox.

Outputs 

Master-to-device process data.

Inputs 

Device-to-master process data.

◆ EniTransition

enum class mm::etg::EniTransition : std::uint8_t
strong

EtherCAT Network Information (ENI) — the configuration a master replays to start a bus.

An ESI file describes one device family; an ENI describes one assembled network, and it is what a third-party master consumes. The two documents are not the same kind of thing. An ESI is declarative, and a configuration tool reads it to decide what to do. An ENI is imperative: every configuration step is written as an EtherCAT datagram (EniEcatCmd) or a CoE transfer (EniCoeCmd), tagged with the AL-state transition it belongs to, and a master brings the bus up by replaying them in order. So this library does not describe a network to a master. It hands the master a script.

The model below mirrors the ENI XML Schema 1.7 element by element, in schema order, because every ENI complex type is an xs:sequence — element order is part of the contract, and a document with the right elements in the wrong order does not validate. Reference: ETG.2100 (EtherCAT Network Information Specification) is the prose authority, and EtherCATConfig.xsd is the exact one.

Three conventions run through the format and are handled once, here:

  • xs:hexBinary — raw bytes in EtherCAT wire order, hex-encoded. An ESC register value is little-endian, so a write of 0x0002 to AL Control is "0200". Every payload is carried as std::vector<uint8_t> in wire order and encoded once, by writeEni.
  • Optionality is the schema's, not a preference. A field held in std::optional, or an empty string or vector, is one the schema marks optional, and writeEni omits the element rather than writing a zero. The difference matters: <Cnt>0</Cnt> tells a master to expect a working counter of zero, which no successful datagram returns.
  • Direction is written from the master's side. In EniProcessData, send is the master's output image and recv is its input image (ETG.2100 Table 14). A device's TxPDOs therefore land in recv.

writeEni is a pure transform with no fieldbus in it. A caller in mm::node fills the model from a live bus, and this library never learns that a bus exists.

An AL-state transition an init command runs on (ENI TransitionType).

Two letters, the state left and the state entered: IP is INIT to PRE-OP. The pairs with a repeated letter are the states a command may be re-sent in without a transition.

Enumerator
II 

INIT to INIT.

IP 

INIT to PRE-OP.

PP 

PRE-OP to PRE-OP.

PO 

PRE-OP to OP.

PS 

PRE-OP to SAFE-OP.

PI 

PRE-OP to INIT.

SS 

SAFE-OP to SAFE-OP.

SP 

SAFE-OP to PRE-OP.

SO 

SAFE-OP to OP.

SI 

SAFE-OP to INIT.

OS 

OP to SAFE-OP.

OP 

OP to PRE-OP.

OI 

OP to INIT.

IB 

INIT to BOOT.

BI 

BOOT to INIT.

◆ EsiCollisionPolicy

enum class mm::etg::EsiCollisionPolicy : uint8_t
strong

What to do when two dictionaries declare the same (index, subindex).

Enumerator
LastWins 

The later definition replaces the earlier one.

FirstWins 

The earlier definition is kept (device dictionary, then slots in order).

Error 

Fail the whole build.

◆ ObjectCode

enum class mm::etg::ObjectCode : uint16_t
strong

CoE object code (ETG.1000.6 §5 Table 41 "Object Code").

The enumerator values are the wire codes, so static_cast<uint16_t> yields the value a CoE SDO-Information "Get Object Description" response carries in its ObjectCode field, and an EsiEntry drops straight into mm::node::DeviceParameter::objectCode.

ETG.1000.6 also defines DEFTYPE (0x05) and DEFSTRUCT (0x06) for type definitions. Those describe entries of the data type dictionary, not the object dictionary, and an ESI expresses them as <DataType> elements rather than <Object> elements — so they never reach this enum.

Enumerator
Var 

A single value: no subindices beyond 0.

Array 

Subindex 0 is the entry count; 1..N share one element type.

Record 

Subindex 0 is the entry count; 1..N each have their own type.

◆ PdoMapping

enum class mm::etg::PdoMapping : uint8_t
strong

PDO mappability (Flags/PdoMapping). Spec default None — not mappable.

The XSD accepts "T R TR RT t r tr rt"; neither case nor order is significant, so all eight spellings fold onto these four. Tx is "t" — slave to master, a TxPDO.

Enumerator
None 
Tx 
Rx 
TxRx 

◆ SafetyMapping

enum class mm::etg::SafetyMapping : uint8_t
strong

Safety mappability (Flags/SafetyMapping, ETG.5120). Spec default None.

Enumerator
None 
SafeIn 
SafeOut 
SafeInOut 
SafeParam 

◆ SdoAccess

enum class mm::etg::SdoAccess : uint8_t
strong

SDO transfer granularity (Object/Flags/SdoAccess).

Exists only on Object/FlagsSubItemType/Flags has no such element (EtherCATBase.xsd:115-169) — so every subindex of an object necessarily shares the object's value. When the element is absent the default comes from the device's or module's Mailbox/CoE/@CompleteAccess.

Enumerator
SubIndexAccess 
CompleteAccess 

◆ StateRestriction

enum class mm::etg::StateRestriction : uint8_t
strong

AL-state restriction on a read or a write (Access/@ReadRestrictions, Access/@WriteRestrictions).

None means the attribute was absent: no restriction beyond the mailbox being up. The XSD enumerates both the modern "PreOP" and the legacy "PreOp" spelling, and ETG.2000 requires a tool to treat them identically, so parsing is case-insensitive.

Enumerator
None 
PreOp 
PreOpSafeOp 
PreOpOp 
SafeOp 
SafeOpOp 
Op 

◆ ValueKind

enum class mm::etg::ValueKind : uint8_t
strong

The C++ type an entry's value maps to.

Coarser than the ETG.1020 numbering on purpose: a dozen codes describe the same eight bytes, and what a caller needs is which C++ type holds the value, not which spelling the vendor chose. Bytes is the honest answer for everything with no scalar equivalent — octet strings, GUIDs, domains, the odd 24/40/48/56-bit integers, and anything whose declared width contradicts its code.

Enumerator
Bool 

BOOL — carried in a uint8_t, as CoE does.

Int8 

SINT.

Int16 

INT.

Int32 

DINT.

Int64 

LINT.

Uint8 

USINT, BYTE, BITARR8, BIT1..BIT8.

Uint16 

UINT, WORD, BITARR16, BIT9..BIT16.

Uint32 

UDINT, DWORD, BITARR32.

Uint64 

ULINT.

Real32 

REAL.

Real64 

LREAL.

String 

STRING(n) / UNICODE_STRING(n).

Bytes 

Everything else, including any type/width contradiction.

Function Documentation

◆ accessModeName()

constexpr std::string_view mm::etg::accessModeName ( AccessMode  v)
constexpr

Symbolic names for the flag enums, in their ESI spelling ("ro", "m", "tr", …).

◆ arrayElementTypeName()

std::string_view mm::etg::arrayElementTypeName ( std::string_view  esiName)

Returns the element type name of an "ARRAY [a..b] OF T" composition, else empty.

The bounds are not validated or returned: an ESI carries them redundantly in DataType/ArrayInfo, which is the authoritative source.

◆ buildDeviceEntries()

std::expected< EsiEntryTable, std::string > mm::etg::buildDeviceEntries ( const EsiFile file,
const EsiDevice device,
const EsiEntryOptions options = {} 
)

Expands a device into a flat, slot-merged vector of object-dictionary entries.

Walks the device's own dictionary first, then each slot in order; for every object it derives one entry per subindex, applying the ETG.2000 rules for flag inheritance (§Figure 37), subindex derivation, per-subindex type resolution, and description lookup. Per-entry problems become warnings, never failures — see EsiEntryTable::warnings.

Parameters
fileThe parsed ESI; needed to resolve the slots' ModuleIdent references.
deviceA device belonging to file.
optionsLocale, module selection, offsets, collision policy.
Returns
The flat table, or an error when the device resolves to no dictionary at all, or when EsiCollisionPolicy::Error is set and a collision occurred.

Where an already-emitted entry sits, plus whether the object that produced it invited a module to replace it. The flag belongs to the incumbentOverwrittenByModule is set by the device on the object it is willing to give up — so it has to be remembered here rather than read off the incoming object.

◆ buildEsiResponse()

std::expected< nlohmann::json, std::string > mm::etg::buildEsiResponse ( std::string_view  xml,
const EsiParseRequest request,
const EsiEntryOptions options = {} 
)

Parses an ESI document and renders it as JSON.

The result is the vendor, every module, and every device with its own assembled entry table — each device object carries its identity, slots, counts, its flat "entries" and the "warnings" raised while assembling it. Document-level warnings sit at the top level.

Returning every device is affordable because object-level annotation is stored once, on subindex 0, rather than repeated onto each subindex (see EsiEntry::properties). A device that would otherwise cost megabytes of duplicated description HTML costs a few hundred kilobytes.

Parameters
xmlThe complete ESI document.
requestModule selection, if any.
optionsFlattening options, applied to every device.
Returns
The rendered JSON, or an error when the document will not parse.

◆ categoryName()

constexpr std::string_view mm::etg::categoryName ( Category  v)
constexpr

◆ cxxTypeName()

constexpr std::string_view mm::etg::cxxTypeName ( ValueKind  kind)
constexpr

The C++ spelling of kind"int32_t", "std::string", "std::vector<uint8_t>".

Matches the alternatives of mm::node::DeviceParameterValue, so a generated ObjectAddress<T> lines up with what decodeSdoBytes produces for the same object. The duplication is deliberate and one-directional: mm::etg cannot depend on mm::node, and a pure XML parser must not link SOEM to know what UDINT is.

◆ eniPhysics()

std::string mm::etg::eniPhysics ( std::uint16_t  physicalPort)

Renders the ENI Physics string for a device from its SII physical-port word.

The word holds one nibble per port, low nibble first, coded by ETG.2010 §Physical Port: 0 not used, 1 MII, 3 EBUS, 4 Fast Hot Connect. The ENI writes one character per port instead — 'Y' for MII, 'K' for EBUS, 'B' for Fast Hot Connect and a space for a port that is present but none of these. Unused trailing ports are dropped, so a two-port device reads "YY".

Parameters
physicalPortThe SII physical-port word (EEPROM address 0x0010).
Returns
The Physics string, empty when no port is in use.

◆ esiSlotModuleIdents()

std::vector< uint32_t > mm::etg::esiSlotModuleIdents ( const EsiDevice device)

Returns every ModuleIdent referenced by any of device's slots, in slot order.

This is the default module set buildDeviceEntries merges. Duplicates are removed, keeping the first occurrence.

◆ esiText()

std::string_view mm::etg::esiText ( const std::vector< Text > &  texts,
uint32_t  lcId = kDefaultLcId 
)

Picks the lcId text from texts, else the unlocalised/default one, else the first.

Returns an empty view when texts is empty. The result borrows from texts.

◆ esiUnitParts()

constexpr UnitParts mm::etg::esiUnitParts ( uint32_t  unit)
constexpr

Splits a packed ETG.1004 unit notation value into its four bytes.

◆ esiUnitSymbol()

std::string mm::etg::esiUnitSymbol ( uint32_t  unit,
std::span< const UnitType local = {} 
)

Renders a packed unit notation value as a display symbol.

Composes prefix + numerator + ("/" + denominator, unless the denominator is dimensionless). Every byte is looked up in local first and in the built-in ETG.1004 catalogue second, so a dictionary that redefines a notation index gets its own meaning.

Examples (with no local table): 0xFD260000"mV", 0x00B50000"Inc", 0xF756B500"nNm/Inc", 0x03200000"kHz", 0x00B44700"rpm".

Parameters
unitThe packed value from ObjectInfo/Unit. 0 yields an empty string.
localThe enclosing dictionary's <UnitTypes>, or empty when it declares none.
Returns
The composed symbol, or an empty string when unit is 0 or names nothing known.

◆ findEsiDevice()

const EsiDevice * mm::etg::findEsiDevice ( const EsiFile file,
std::string_view  type 
)

Finds the device whose <Type> text equals type (case-sensitive).

Returns
A pointer into file, or nullptr. Valid only while file lives and is unmodified.

◆ findEsiDeviceByProductCode()

const EsiDevice * mm::etg::findEsiDeviceByProductCode ( const EsiFile file,
uint32_t  productCode,
std::optional< uint32_t >  revisionNo = std::nullopt 
)

Finds the device with product code productCode, optionally pinned to a revision.

With revisionNo unset, returns the highest-revision match — the ESI convention for "the newest description of this product".

Returns
A pointer into file, or nullptr. Valid only while file lives and is unmodified.

◆ findEsiModule()

const EsiModule * mm::etg::findEsiModule ( const EsiFile file,
uint32_t  moduleIdent 
)

Finds the module with the given ModuleIdent.

Returns
A pointer into file, or nullptr. Valid only while file lives and is unmodified.

◆ isStringTypeName()

bool mm::etg::isStringTypeName ( std::string_view  esiName)

True when esiName is a parameterised string type — STRING(n) / OCTET_STRING(n) / UNICODE_STRING(n).

◆ objectCodeName()

constexpr std::string_view mm::etg::objectCodeName ( ObjectCode  code)
constexpr

Returns the ESI/CiA spelling of code"VAR", "ARRAY" or "RECORD".

◆ parseEsi()

std::expected< EsiFile, std::string > mm::etg::parseEsi ( std::string_view  xml)

Parses an ESI XML document.

Tolerates a UTF-8 BOM and either line ending. Recoverable inconsistencies do not fail the parse: a malformed object is skipped and recorded in EsiFile::warnings, because one bad element in a 50 000-line vendor file must not cost the other five hundred objects. Only three conditions are hard failures — an XML syntax error, a root element other than <EtherCATInfo>, and a missing Descriptions/Devices.

Parameters
xmlThe complete document. Not retained; every string is copied.
Returns
The parsed file, or an error naming the failure and (for a syntax error) its offset.

◆ parseEsiFile()

std::expected< EsiFile, std::string > mm::etg::parseEsiFile ( const std::filesystem::path &  path)

Reads path and parses it with parseEsi.

Returns
The parsed file, or an error on an unreadable or empty file, or on a parse failure.

◆ parseIdentList()

std::expected< std::vector< uint32_t >, std::string > mm::etg::parseIdentList ( std::string_view  csv)

Parses a comma-separated list of hex-or-decimal values, as a query parameter carries it.

Accepts the ESI "#x" prefix, a C-style "0x" prefix or plain decimal, and tolerates spaces around the separators. An empty input yields an empty list.

Returns
The parsed values, or an error naming the element that failed.

◆ pdoMappingName()

constexpr std::string_view mm::etg::pdoMappingName ( PdoMapping  v)
constexpr

◆ readEni()

std::expected< EniRead, std::string > mm::etg::readEni ( std::string_view  xml)

Reads an ENI document into a network.

Tolerant by design, and the inverse of writeEni over everything the model covers. Only three things fail a read: XML that will not parse, a root element that is not EtherCATConfig, and a missing Config. A malformed value inside the document costs that value and a warning.

**Written to be more permissive than writeEni, on purpose.** A previous port of A is accepted here and refused there, because ETG.2100 allows it and ENI Schema 1.7 does not — a reader takes what the file says, a writer emits only what validates. The same asymmetry applies to the sample documents ETG itself ships, which omit elements their own schema marks mandatory.

Parameters
xmlThe complete ENI document.
Returns
The network and any warnings, or an error naming what made the document unreadable.

◆ resolvePrimitiveType()

std::optional< PrimitiveType > mm::etg::resolvePrimitiveType ( std::string_view  esiName)

Resolves an ESI type name to its CoE code, width and signedness.

Handles three shapes:

  • a plain table name, e.g. "UDINT" → {0x0007, 32, false};
  • a parameterised string, e.g. "STRING(50)" → {0x0009, 400, false} and "OCTET_STRING(8)" → {0x000A, 64, false} (UNICODE_STRING counts 16 bits per element);
  • an array-composition name, e.g. "ARRAY [0..7] OF BYTE", which resolves to its **element** type (BYTE here). Such a name denotes the ETG.2000 Table 12 "ARRAY INFO" helper type, which never becomes an entry's own type — the entry takes the element type via <BaseType> — so returning the element keeps a caller that asks anyway from getting a surprise.
Parameters
esiNameThe <Type> / <BaseType> / <Name> text. Leading and trailing whitespace is not trimmed; callers pass an already-trimmed view.
Returns
The resolved primitive, or std::nullopt when the name is not a primitive (a composite DTxxxx name, or a spelling this table does not know).

◆ resolveValueKind()

ValueKind mm::etg::resolveValueKind ( uint16_t  dataType,
uint16_t  bitSize 
)

Resolves the C++ type an entry holds, from its ETG.1020 code and declared width.

bitSize is the cross-check, and it is not decoration. A vendor writes "ARRAY [0..24] OF BYTE" and the ESI resolves that to the code for BYTE — so a mapping that trusted the code alone would call a 25-byte object a uint8_t, and every read of it would silently return its first byte. Seven entries of the shipped SOMANET dictionary are exactly that shape (OS command 0x1023, high-resolution data 0x20E1, the FSoE device ID). Whenever the declared width contradicts the code's own, the answer is Bytes.

Parameters
dataTypeETG.1020 data type code.
bitSizeThe entry's declared width in bits; 0 means "unknown", which suppresses the cross-check rather than failing it.
Returns
The value kind; Bytes for anything with no scalar equivalent.

◆ safetyMappingName()

constexpr std::string_view mm::etg::safetyMappingName ( SafetyMapping  v)
constexpr

◆ sdoAccessName()

constexpr std::string_view mm::etg::sdoAccessName ( SdoAccess  v)
constexpr

◆ stateRestrictionName()

constexpr std::string_view mm::etg::stateRestrictionName ( StateRestriction  v)
constexpr

◆ to_json() [1/31]

void mm::etg::to_json ( nlohmann::json &  j,
const Access v 
)

◆ to_json() [2/31]

void mm::etg::to_json ( nlohmann::json &  j,
const EniNetwork network 
)

Serialises a network as JSON, for a client that renders rather than replays it.

Keys are the model's own field names in camelCase, like every other JSON this project serves. Two things are spelled out rather than left as numbers, because a reader of the JSON is a person and not a master: every enumeration carries its ENI spelling beside its value (cmd 5 with cmdName "FPWR"), and every byte payload is the hex string the document holds beside its length. Nothing is decoded further here — what an FPWR to 0x0800 means needs the ESC register tables, which this library deliberately does not depend on.

◆ to_json() [3/31]

void mm::etg::to_json ( nlohmann::json &  j,
const EsiDataType v 
)

◆ to_json() [4/31]

void mm::etg::to_json ( nlohmann::json &  j,
const EsiDataType::ArrayInfo v 
)

◆ to_json() [5/31]

void mm::etg::to_json ( nlohmann::json &  j,
const EsiDataType::EnumInfo v 
)

◆ to_json() [6/31]

void mm::etg::to_json ( nlohmann::json &  j,
const EsiDataType::SubItem v 
)

◆ to_json() [7/31]

void mm::etg::to_json ( nlohmann::json &  j,
const EsiDataType::SubItem::Flags v 
)

◆ to_json() [8/31]

void mm::etg::to_json ( nlohmann::json &  j,
const EsiDevice v 
)

◆ to_json() [9/31]

void mm::etg::to_json ( nlohmann::json &  j,
const EsiDictionary v 
)

◆ to_json() [10/31]

void mm::etg::to_json ( nlohmann::json &  j,
const EsiEntry v 
)

◆ to_json() [11/31]

void mm::etg::to_json ( nlohmann::json &  j,
const EsiEntrySource v 
)

◆ to_json() [12/31]

void mm::etg::to_json ( nlohmann::json &  j,
const EsiEntryTable v 
)

◆ to_json() [13/31]

void mm::etg::to_json ( nlohmann::json &  j,
const EsiEnumOption v 
)

Serialises an entry to JSON. Raw byte vectors are emitted as uppercase hexBinary strings, the same spelling the ESI itself uses; absent optionals are omitted.

◆ to_json() [14/31]

void mm::etg::to_json ( nlohmann::json &  j,
const EsiFile v 
)

◆ to_json() [15/31]

void mm::etg::to_json ( nlohmann::json &  j,
const EsiFile::Vendor v 
)

◆ to_json() [16/31]

void mm::etg::to_json ( nlohmann::json &  j,
const EsiModule v 
)

◆ to_json() [17/31]

void mm::etg::to_json ( nlohmann::json &  j,
const EsiObject v 
)

◆ to_json() [18/31]

void mm::etg::to_json ( nlohmann::json &  j,
const EsiObject::Flags v 
)

◆ to_json() [19/31]

void mm::etg::to_json ( nlohmann::json &  j,
const EsiObject::Info v 
)

◆ to_json() [20/31]

void mm::etg::to_json ( nlohmann::json &  j,
const EsiObject::Info::SubItem v 
)

◆ to_json() [21/31]

void mm::etg::to_json ( nlohmann::json &  j,
const EsiPdo v 
)

◆ to_json() [22/31]

void mm::etg::to_json ( nlohmann::json &  j,
const EsiPdo::Entry v 
)

◆ to_json() [23/31]

void mm::etg::to_json ( nlohmann::json &  j,
const EsiProfile v 
)

◆ to_json() [24/31]

void mm::etg::to_json ( nlohmann::json &  j,
const EsiSlots v 
)

◆ to_json() [25/31]

void mm::etg::to_json ( nlohmann::json &  j,
const EsiSlots::ModulePdoGroup v 
)

◆ to_json() [26/31]

void mm::etg::to_json ( nlohmann::json &  j,
const EsiSlots::Slot v 
)

◆ to_json() [27/31]

void mm::etg::to_json ( nlohmann::json &  j,
const MailboxCoe v 
)

◆ to_json() [28/31]

void mm::etg::to_json ( nlohmann::json &  j,
const PrimitiveType type 
)

Serialises a PrimitiveType to JSON (name, code, bitSize, isSigned).

◆ to_json() [29/31]

void mm::etg::to_json ( nlohmann::json &  j,
const Property v 
)

◆ to_json() [30/31]

void mm::etg::to_json ( nlohmann::json &  j,
const Text v 
)

Serialises the model to JSON. Keys are lowerCamelCase mirrors of the member names; absent optionals are omitted rather than emitted as null.

◆ to_json() [31/31]

void mm::etg::to_json ( nlohmann::json &  j,
const UnitType unit 
)

Serialises a UnitType to JSON (notationIndex, index, name, symbol).

◆ writeEni()

std::expected< std::string, std::string > mm::etg::writeEni ( const EniNetwork network)

Renders a network as an ENI document.

The output is indented UTF-8 XML with an XML declaration, and it validates against ENI Schema 1.7. Byte payloads are written as uppercase xs:hexBinary, which is the canonical form; the sample files ETG ships use lowercase, and a master must accept either.

Parameters
networkThe network to render.
Returns
The document, or an error naming the first field that cannot be written — a command that fills both halves of an either-or choice, a MAC that is not six bytes, or a Sync Manager index that is out of range or used twice.

Variable Documentation

◆ kDefaultLcId

constexpr uint32_t mm::etg::kDefaultLcId = 1033
inlineconstexpr

The default LcId — 1033, en-US.

◆ kPrimitiveTypes

constexpr auto mm::etg::kPrimitiveTypes
inlineconstexpr

Catalogue of the ESI primitive types, keyed by their IEC 61131-3 name.

Parameterised names (STRING(n), OCTET_STRING(n), UNICODE_STRING(n)) appear here with their base name and bitSize 0; resolvePrimitiveType computes the real width from the parenthesised element count. Composite types (RECORD/ARRAY definitions such as DT1018) are not here — they are declared per dictionary by the ESI itself.