= mesambccc(1)

== NAME

mesambccc - Utility for compiling hm2_modbus command control description files

== SYNOPSIS

*mesambccc* [_-h_|_--help_] [_-v_|_--verbose_] [_-o_ file|_--output_=file] <filename.source.mbccs>

== DESCRIPTION

The *mesambccc* utility is used to compile hm2_modbus driver command control
description files for running Modbus devices with Mesa cards using the
PktUARTs. The MBCCS source file is an XML formatted document which describes
the devices connected, pins to create and commands to issue to the PktUART port
using the Modbus protocol. See link:#_mbccs_file_format[*MBCCS FILE FORMAT*]
below.

== OPTIONS

*-h*, *--help*::
  Show a brief help message and exit.
*-o file*, *--output=file*::
  Save the compiled output to *file*. The file name 'mesamodbus.output.mbccb'
  is used if no file is specified on the command line.
*-v*, *--verbose*::
  Output a verbose list of configuration parameters, devices, Modbus messages
  and HAL pins.

== MBCCS FILE FORMAT
The Modbus command control source file (mbccs file) is an XML formatted
document describing the communication parameters, connected devices, HAL pins
and command functions to be sent over Modbus. The overall layout is as follows:
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<mesamodbus [attributes...]>
  <devices>...</devices>
  <initlist>...</initlist>
  <commands>...</commands>
</mesamodbus>
----

The '<devices>' tag must be defined before either '<initlist>' or '<commands>'
are defined.

=== ATTRIBUTE VALUES
Attribute values are generally case insensitive, except for the 'name'
attributes, which should always be lower case.

Boolean attributes accept values "false" and "0" for false and "true" and "1"
for true. Integer numerical values can be entered in decimal, hexadecimal,
octal or binary form. The latter three require the value to be prefixed with
"0x", "0o" or "0b" respectively. Floating point values follow standard rules
for floating point values.

All values are checked to be within an acceptable range. Errors and warnings
are emitted when values are out of bounds. In case of a warning they may be
clamped to the acceptable range.

=== MODBUS FUNCTIONS
A subset of the Modbus functions is supported (with function number in parentheses):

* `R_COILS` (`1`):
  Maps to 1..2000 HAL output pins of type 'HAL_BIT'.
* `R_INPUTS` (`2`):
  Maps to 1..2000 HAL output pins of type 'HAL_BIT'.
* `R_REGISTERS` (`3`):
  Maps to 1..125 HAL output pins depending 'haltype' and 'scale' attributes.
* `R_INPUTREGS` (`4`):
  Maps to 1..125 HAL output pins depending 'haltype' and 'scale' attributes.
* `W_COIL` (`5`):
  Maps to single HAL input pin of type 'HAL_BIT'.
* `W_REGISTER` (`6`):
  Maps to single HAL input pins depending 'haltype' and 'scale' attributes.
* `W_COILS` (`15`):
  Maps to 1..2000 HAL input pins of type 'HAL_BIT'.
* `W_REGISTERS` (`16`):
  Maps to 1..125 HAL input pins depending 'haltype' and 'scale' attributes.

You can use the function's symbolic name or numerical value in '<command>' in
the 'function' attribute (as in `function="W_REGISTERS"` or `function="16"`).

=== MODBUS TYPES
The 'modbustype' attribute declares the interpretation of values to or from a
Modbus device's registers. They can be a signed integer (S), unsigned integer
(U) or a floating point value (F). The size of the value can be 16-bit, 32-bit
or 64-bit and the byte-ordering must be specified. The Modbus default, when
speaking in "register" quantities, is an unsigned 16-bit value in big-endian
(U_AB).

Modbus devices may implement other interpretations covering multiple
consecutive registers to create larger or other types. In doing so, multiple
device vendors have created some different interpretations of the data that
needs to be covered. Differences are primarily byte-ordering.

The byte-ordering is specified with one of the following suffixes:

* `_A`, `_B`
* `_AB`, `_BA`
* `_ABCD`, `_BADC`, `_CDAB`, `_DCBA`
* `_ABCDEFGH`, `_BADCFEHG`, `_CDABGHEF`, `_DCBAHGFE`,
  `_EFGHABCD`, `_FEHGBADC`, `_GHEFCDAB`, `_HGFEDCBA`

Modbus standard byte-ordering is big-endian, which is the first in each list
(`_AB`, `_ABCD` and `_ABCDEFGH`). Little-endian is the last in each list. The user
may use any of the byte-orderings necessary and required because some device
vendors have not paid attention to the proper on-wire ordering.

The orderings `_A` and `_B` are single byte values from a modbus register. A
single byte will be taken from the register value. You cannot access successive
bytes from the same register using these types. (You require a second component
that de-multiplexes the HAL value(s) into individual bytes from the data stream
using the hm2_modbus presented pin values.) +
The ordering `_A` will use the the least significant byte (LSB), with respect
to the default big endian order for Modbus. Ordering `_B` will use the most
significant byte (MSB). Note that there is no floating point type when only
using sizes of one single byte. +
Single byte values have the additional restriction that they cannot be used as
data values in '<initlist>/<command>/<data>'.

The byte-ordering suffix is prefixed with S (signed), U (unsigned) or F (float)
to complete the 'modbustype' attribute value. For example, a 32-bit float in
big-endian is named `F_ABCD`. A 64-bit signed integer value in little-endian is
S_HGFEDCBA.

The types have following ranges and will be clamped to the min/max values if
the 'clamp' attribute is set in the '<command>':

* 8-bit:
 ** signed integer [-128..+127] (`S_A`, `S_B`)
 ** unsigned integer [0..255] (`U_A`, `U_B`)
* 16-bit:
 ** float16 [-65504.0..+65504.0] (`F_AB`, `F_BA`)
 ** signed integer [-32768..+32767] (`S_AB`, `S_BA`)
 ** unsigned integers [0..65535] (`U_AB`, `U_BA`)
* 32-bit:
  ** float [-3.4e38..+3.4e38] (`F_ABCD`...`F_DCBA`)
  ** signed integer [-2147483648..+2147483647] (`S_ABCD`...`S_DCBA`)
  ** unsigned integer [0..4294967296] (`U_ABCD`...`U_DCBA`)
* 64-bit:
  ** double [-1.7e308..+1.7e308] (`F_ABCDEFGH`...`F_HGFEDCBA`)
  ** signed integer [-9223372036854775808..9223372036854775807]
     (`S_ABCDEFGH`...`S_HGFEDCBA`)
  ** unsigned integer [0..18446744073709551615] (`U_ABCDEFGH`...`U_HGFEDCBA`)


=== <mesamodbus>
The main enclosing tag '<mesamodbus>' contains the communication parameters and
other setup values as attributes:

*baudrate* [1200..1000000]::
  Communication speed. Any speed over 460800 will result in side-effects
  because the internal hardware timers may overflow to keep track of the Modbus
  protocol requirements. Default 9600.
*drivedelay* [auto, 1..31]::
  The delay, in bit-times, before transmission begins after enabling the
  transmitter hardware output driver. Default auto.
*duplex* [full, half]::
  Whether 2-wire (half duplex) or 4-wire (full duplex) communication is set.
  Default half.
*icdelay* [auto, 1..255]::
  The maximum allowed inter-character delay between two received characters in
  bit-times. Default: auto.
*interval* [0..3600000000]::
  The default command repeat interval in micro-seconds. This is effectively the
  time between repeating the '<commands>' list (sending writes and receiving
  reads from the Modbus devices). An interval shorter than the time it takes to
  work through the '<commands>' list will just repeat the '<commands>' list as
  fast as possible. +
  The 'interval' may be overridden in the individual '<commands><command>'
  instructions. Default 0.
*parity* [N, O, E]::
  Communication parity none (N), odd (O) or even (E). Default E.
*rxdelay*, *txdelay* [auto, 1..1020]::
  Inter frame delay between packets sent/received. The value is in bit-times.
  The appropriate value will be calculated automatically when this attribute is
  omitted. If set manually, the 'txdelay' value should generally be larger
  than 'rxdelay' value. The value is limited to [1..255] for PktUART V2.
  Default auto.
*stopbits* [1, 2]::
  Communication number of stopbits. This attribute requires PktUART V3+ to have
  any effect. Default 1.
*suspend* [Boolean]::
  Start with suspended communication when set. This enables you to setup pin,
  scale and offset values in the HAL file(s) using setp/sets commands before
  data is written to any Modbus device. Default false.
*timeout* [auto, 10000..10000000]::
  The standard time a command may take in micro-seconds (send request plus
  handling plus receive reply) before the command is deemed lost. The special
  value of 'auto' will calculate an appropriate timeout value from the request
  and reply sizes. The 'timeout' value can be overridden in the '<command>'
  definitions. Default auto.
*writeflush* [Boolean]::
  Set to true when the first round of write commands must synchronize the
  internal state to the pin state. The writes are calculated but not sent to
  the Modbus device (i.e. flushed). This flush happens either once when the
  module starts, each time when the module comes out of 'suspend', or
  specifically for a command when it gets re-enabled. +
  The write flush is necessary when you need to ensure proper and correct pin
  data is present _before_ the Modbus commands start sending potentially
  harmful or invalid data because the pins have not yet been initialized to
  their proper values. When set, only pin values that are changed from their
  initial values are propagated in Modbus write commands. +
  This value represents the global default used buy the individual commands
  from the '<commands>' section and can be overridden in the
  individual '<command>' instructions. Default true.

The default parameters, without any attributes defined in '<mesamodbus>', are
half duplex serial setup using 8E1@9600 and running all commands as fast as
possible. Timeouts and other timing parameters are calculated automatically.

=== <devices>
Each connected device to the physical bus must be declared in a '<device>' tag
with a 'name' and an 'address' attribute. A device with name 'broadcast' is
implicitly added with address zero (0). Device entries may include
a '<description>' tag, which serves as a user's comment.

[source,xml]
----
<devices>
  <device address="0x01" name="binbox" />
  <device address="0x02" name="vroom">
    <description>Round and round and round...</description>
  </device>
  <device address="0x66" name="clickies">
    <description>Many, many relays</description>
  </device>
</devices>
----

Recognized '<devices>/<device>' attributes:

*address* [1..247]::
  The Modbus slave device ID. The Modbus reserved address range 248..255 is
  accepted, but a warning is emitted.
*name*::
  The 'name' of the device. The name must be in lower case ASCII and adhere to
  the HAL specification comprising of letters and numbers with optional dash
  and period. It is strongly advised to use letters only in a descriptive
  word. The device's 'name' is used to construct the HAL pin names.

=== <initlist>
The '<initlist>' tag contains a list of '<command>' tags that are only sent
_once_ at the startup of the system. The commands can be used to initialize any
devices on the bus prior to normal operation. Commands can be both read and
write functions. Write functions must have data defined to be sent.
Each '<command>' entry may include a '<description>' tag, which serves as a
user's comment.

Note: if the driver starts in suspended mode (`supend="true"` in '<mesamodbus>'),
then the '<initlist>' commands are first sent when the driver comes out of
suspend.

[source,xml]
----
<initlist>
  <command device="scd30" function="W_REGISTER" address="0x0034">
    <description>Soft reset</description>
    <data value="1" />
  </command>
  <command device="relay" function="W_COILS" address="0">
    <data value="0" />
    <data value="1" />
    <data value="1" />
    <data value="0" />
    <description>Four relays set to off-on-on-off</description>
  </command>
  <command device="boombox" function="W_COIL" address="0">
    <data value="0xff00" />
    <description>Single output set to on to hear the boombox</description>
  </command>
  <command delay="2000000">
    <description>Wait for reset to finish</description>
  </command>
  <command device="fltbox" function="W_REGISTERS" address="0xcafe">
    <data modbustype="F_ABCD" value="0.53" />
    <data modbustype="F_ABCD" value="99.999" />
    <description>Send four 16-bit words: 0x3f07 0xae14 0x42c7 0xff7d
                 (floats in binary, big-endian)</description>
  </command>
</initlist>
----

A '<command>' is either a delay instruction, a communication parameter change
or a Modbus transaction to perform. Only the 'delay' attribute is supported in
case of a delay instruction and all activity is suspended during the specified
delay. A communication parameter change can use any communication related
attribute from the '<mesamodbus>' tag and must revert to the defaults set in
the '<mesamodbus>' tag at the end on the '<initlist>'.

Modbus write functions must include one or more '<data>' tags to encapsulate
the data to send. The '<data>' tag has a mandatory attribute 'value' to capture
the value to send. An optional 'modbustype' attribute models the data to send
to the format of the 'modbustype'. The default is U_AB if the type is not
specified.

The write coils Modbus function `W_COILS` (`15`) further restrict the 'value' to
zero (0) or one (1). The write coil `W_COIL` (`5`) has a fixed type of U_AB and
expects a value of 0x0000 or 0xff00. Other values may be given, but a warning
will then be emitted.

The Modbus read functions `R_COILS` (`1`), `R_INPUTS` (`2`), `R_REGISTERS` (`3`) and
`R_INPUTREGS` (`4`) are supported in the '<initlist>/<command>' but the returned
data is ignored and discarded. Read functions are supported because some
devices require a read function as a trigger.

Recognized '<initlist>/<command>' attributes when sending Modbus commands:

*address* [0..65535]::
  The Modbus coil/input/register starting address.
*bcanswer* [Boolean]::
  Set to true if a device sends an answer on broadcast, which must be ignored.
  Default false.
*count* [1..2000]/[1..125]::
  Modbus read functions `R_COILS` (`1`), `R_INPUTS` (`2`), `R_REGISTERS` (`3`) and
  `R_INPUTREGS` (`4`) must specify the number of coils, inputs, registers or
  inputregs to read. Write functions do not require the 'count' attribute
  because the '<data>' tags dictate the size of the packet to send.
*device*::
  The Modbus device to communicate with. The 'device' attribute
  references '<device>[name]'. +
  The device name '`broadcast`' will send the command to all devices on the bus.
*function* [see link:#_modbus_functions[*MODBUS FUNCTIONS*]]::
  The attribute value is one of the supported Modbus functions.
*noanswer* [Boolean]::
  Set to true if a device does not return a reply to a command. This can be
  intentional if you send a command to a non-existing device. Default false.
*timeout* [auto, 1..60000000]::
  The override timeout of '<mesamodbus>[timeout]' for this command in
  *micro-seconds* (send request plus handling plus receive reply) before the
  command is deemed lost. See also 'timeoutbits' below.
  Default '<mesamodbus>[timeout]'.
*timeoutbits* [0..1000000]::
  The override timeout of '<mesamodbus>[timeout]' for this command
  in *bit times* (send request plus handling plus receive reply) before the
  command is deemed lost. The actual timeout is automatically calculated and
  scaled by the '<mesamodbus>[baudrate]' setting. See also 'timeout' above.
  Default use 'timeout' attribute.
*timesout* [Boolean]::
  Set to true if the command is known to (periodically) timeout and no error
  should be emitted when it does. This differs from 'noanswer' in that a reply
  may be expected within the timeout period but not after the timeout expires.
  This may be required for flaky devices. Default false.


==== Delay instruction
Recognized '<initlist>/<command>' attributes in delay commands:

*delay* [0..60000000]::
  Communication will be suspended by 'delay' micro-seconds.


==== Communication parameter change
Communication parameters may be temporarily changed to perform live setup of
Modbus devices to change their own communication parameters. Some devices will
start with a fixed rate and must be reprogrammed at start to change to a
different rate. The default setup from '<mesamodbus>' must be restored if one
or more parameters were changed or a warning will be emitted.

Recognized '<initlist>/<command>' attributes in communication parameter change
commands. Attributes not specified will be taken from the '<mesamodbus>' tag's
attributes:

*baudrate* [1200..1000000]::
  Communication speed override.
*drivedelay* [auto, 1..31]::
  The TX driver delay override.
*icdelay* [auto, 1..255]::
  The inter-character delay override.
*parity* [N, O, E]::
  Communication parity override.
*rxdelay*, *txdelay* [auto, 1..1020]::
  Inter frame delay override.
*stopbits* [1, 2]::
  Communication number of stopbits override.


==== Initialization data
Recognized '<initlist>/<command>/<data>' attributes:

*modbustype* [see link:#_modbus_types[*MODBUS TYPES*]]::
  The destination format and translation of the 'value' attribute.
*value*::
  The numerical value of the data to send. The format defaults to unsigned
  16-bit integer but depends on the 'modbustype' attribute and the range of
  acceptable values depends on the Modbus function.

=== HAL TYPES
A '<command>' in the '<commands>' section maps to one or more HAL pins with
specific type using the 'haltype' attribute. Recognized are:

* 'HAL_BIT'
* 'HAL_FLOAT'
* 'HAL_S32'
* 'HAL_U32'

The types are also recognized without the HAL_ prefix. Note that coil and
binary input functions `R_COILS` (`1`), `R_INPUTS` (`2`), `W_COIL` (`5`)
and `W_COILS` (`15`) can only map to 'HAL_BIT' and do so implicitly.

The 'HAL_BIT' and 'HAL_U32' types always map to one single HAL pin.

The 'HAL_FLOAT' and 'HAL_S32' types can generate one single pin or
can generate multiple pins with 'offset' and 'scale'. Output pins
with `R_REGISTERS` (`3`) and `R_INPUTREGS` (`4`) can add a 'scaled' pin to
the set.

Mapping HAL pins to commands requires a 'modbustype' attribute to encode the
format and necessary conversions. Register functions `R_REGISTERS` (`3`),
 `R_INPUTREGS` (`4`), `W_REGISTER` (`6`) and `W_REGISTERS` (`16`) may map
to 'HAL_BIT' only when using unsigned 'modbustype' where a value of zero (0)
is _false_ and any other value is _true_ for write functions or one (1) for
read functions.

*Note on 64-bit integer types*::
  The 'haltype' names 'HAL_S64' and 'HAL_U64' are recognized but generate an
  error. The integer 64-bit types are not supported in the 2.9 branch because
  they are lacking in the API. You need a newer LinuxCNC version for full
  64-bit support. +
  As a consequence, 64-bit integer Modbus types can only map to 32-bit HAL
  pins, which will reduce accuracy. A warning is emitted when you map the
  larger 64-bit integer Modbus types to a smaller 32-bit HAL type.

=== <commands>
The '<commands>' section defines one or more '<command>' tags to describe the
Modbus function(s) to execute in a periodical way. Each '<command>' tag maps to
one or more HAL pins and specifies data conversion between device data and HAL
pin data.

A delay command may be added using the 'delay' attribute causing the
communication to be suspended for the specified time. This may be required in
broadcast situations where the Modbus devices must have time for internal
processing before the next data is sent or requested.

The '<command>' entries may include a '<description>' child-tag, which serves
as a user's comment.
Additionally, the '<command>' tag may have one or more '<pin>' child-tags to
create user-defined HAL pin names. Each '<pin>' tag may again include
a '<description>' child-tag.

Modbus read functions `R_COILS` (`1`), `R_INPUTS` (`2`), `R_REGISTERS` (`3`)
and `R_INPUTREGS` (`4`) will always be sent at the specified interval.
However, the Modbus write functions `W_COIL` (`5`), `W_REGISTER` (`6`),
 `W_COILS` (`15`) and `W_REGISTERS` (`16`) are _only_ sent when the source data
(pin value) changed. You must specify the 'resend' attribute to force repeated
writes at the specified interval.

[source,xml]
----
<commands>
  <command device="wavebox" function="R_COILS" address="0x0000" count="4" name="state" />
    <description>Type is implicit HAL_BIT, will become HAL pins:
       - (out) hm2_modbus.0.wavebox.state-00
       - (out) hm2_modbus.0.wavebox.state-01
       - (out) hm2_modbus.0.wavebox.state-02
       - (out) hm2_modbus.0.wavebox.state-03
    </description>
  </command>
  <command device="scd30" modbustype="F_ABCD" haltype="HAL_FLOAT" function="R_REGISTERS"
           address="0x0028" scale="0">
    <pin name="co2"><description>Too much will kill you...</description></pin>
    <pin name="temperature" />
    <pin name="humidity" />
    <description>Will become HAL pins:
       - (out) hm2_modbus.0.scd30.co2
       - (out) hm2_modbus.0.scd30.temparature
       - (out) hm2_modbus.0.scd30.humidity
       Count will automatically be calculated (6 Modbus 16-bit registers).
    </description>
  </command>
  <command device="broadcast" function="W_COILS" address="0x1234" count="2"
           name="anyandall" bcanswer="1">
    <description>Will create HAL_BIT pins:
      - (in) hm2_modbus.0.anyandall-00
      - (in) hm2_modbus.0.anyandall-01
      The bcanswer flag signifies that a device erroneously sends a reply on
      broadcast (oopsie), which needs to be ignored .
    </description>
  </command>
  <!-- A delay is suggested after a broadcast to allow devices to handle the data -->
  <command delay="10000" />
  <command device="watcher" function="W_REGISTER" haltype="HAL_U32" modbustype="U_AB"
           address="0x1ee7" noanswer="1" resend="1">
    <pin name="watcher" />
    <description>Will create a HAL_U32 pin
      - (in) hm2_modbus.0.watcher
      The 'count' is implicit 1. The data is mapped to U_AB and is clamped.
      The data is sent every time (resend=1), regardless whether the HAL pin
      changed. No answer is expected to be received (noanswer=1). This
      command generates a (valid) Modbus packet on the bus and nothing more.
      You must be sure that no reply is sent from the device or errors will
      occur (for example silent watchdog).
    </description>
  </command>
</commands>
----

Recognized '<commands>/<command>' attributes:

*address* [0..65535]::
  The Modbus coil/input/register starting address.
*bcanswer* [Boolean]::
  Set to true if a device sends an answer on broadcast, which must be ignored.
  Default false.
*clamp* [Boolean]::
  Conversion from larger to smaller types are automatically clamped to their
  maximum/minimum values. It works in both ways: read => HAL-out and write <=
  HAL-in. Setting this to false can result in truncated values. Default is true.
*count* [1..2000]/[1..125]/[1..62]/[1..31]::
  The 'count' specifies the number of HAL pins to create. The data from these pins
  is read from or written to the Modbus device. Alternatively, you can specify
  the HAL pins using the '<pin>' child-tags. If both 'count' and '<pin>' are
  specified and 'count' is larger than the number of '<pin>' tags, then
  additional HAL pins will be created to match the count. +
  (the range depends on 'haltype' and 'modbustype')
*delay* [0..60000000]::
  Suspend activity and delay the next '<command>' by 'delay' micro-seconds.
*device*::
  The Modbus device to communicate with. The 'device' attribute
  references '<device>[name]'. +
  The device name '`broadcast`' will send the command to all devices on the bus.
*disabled* [Boolean]::
  Start the command in disabled state when set, preventing it from being
  executed. Using the 'disabled' flag is a fine grain per command control.
  In contrast, 'suspend' works on the entire state machine and controls
  operation of all commands in an all-or-nothing way. A command in the disabled
  state can be enabled by toggling the reset pin of the command. Using 'disable'
  can be particularly useful when you need to delay one particular command
  while others may already be run. The 'writeflush' setting is honored when
  coming out of the disabled state. Default false.
*function* [see link:#_modbus_functions[*MODBUS FUNCTIONS*]]::
  The attribute value is one of the supported Modbus functions.
*haltype* [see link:#_hal_types[*HAL TYPES*]]::
  The HAL pin type for interactions. You do not need to specify this attribute
  for the Modbus functions read/write coil(s) or inputs, `R_COILS` (`1`),
  `R_INPUTS` (`2`), `W_COIL` (`5`) and `W_COILS` (`15`), as these always use
  the 'HAL_BIT' type.
*interval* [once,0..3600000000]::
  The command repeat interval in micro-seconds. This is the time between
  repeating this '<command>'. An interval shorter than the time it takes to work
  through the '<commands>' list will just repeat this '<command>' as fast as
  possible. +
  A special value of 'once' will run this command only once. However, it will
  be retried is an error occurred.  You normally do not need the value 'once'
  and it may be better to use an entry in the '<initlist>'. But sometimes you
  need to have other periodic commands before a 'once' marked command that
  cannot be achieved in the '<initlist>' sequence. Default '<mesamodbus>[interval]'.
*modbustype* [see link:#_modbus_types[*MODBUS TYPES*]]::
  The Modbus data mapping from/to register(s) for Modbus functions read/write
  register(s) `R_REGISTERS` (`3`), `R_INPUTREGS` (`4`), `W_REGISTER` (`6`) and
  `W_REGISTERS` (`16`). The default is U_AB if not specified.
*name*::
  The name for HAL pin names. +
  Example: if `count="2"` and `name="myname"`, then the pins will have
  names _myname-00_ and _myname-01_, unless one or more '<pin>' tags override
  the name.
*noanswer* [Boolean]::
  Set to true if a device does not return a reply to a command. This can be
  intentional if you send a command to a non-existing device. Default false.
*resend* [Boolean]::
  Resend Modbus write command even though no HAL pin change (data to send
  change) was detected. Normally, only data changes are sent using Modbus write
  commands. Some devices require a constant "reminder" (like watchdogs) and
  you need to send the data regularly. Default false.
*scale* [Boolean]::
  Add scaling HAL pins. Modbus read functions `R_REGISTERS` (`3`) and `R_INPUTREGS` (`4`)
  add extra HAL pins *pin.name.offset* (in, 64-bit 'haltype'), *pin.name.scale*
  (in, 'HAL_FLOAT') and *pin.name.scaled* (out, 'HAL_FLOAT'). +
  The Modbus write functions `W_REGISTER` (`6`) and `W_REGISTERS` (`16`) create
  extra HAL pins *pin.name.offset* (in, 64-bit 'haltype') and *pin.name.scale*
  (in, 'HAL_FLOAT'). +
  The 'scale' attribute is only supported for 'HAL_FLOAT', 'HAL_S32' and 'HAL_S64'.
  Default is true for 'HAL_FLOAT' and false for others. The *scale* pin is
  initialized to one (1.0) and the *offset* pin is initialized to zero (0). +
  Scaling is always multiplicative to prevent division-by-zero. The offset is
  always subtracted before scaling. The scaling action performed and subject to
  clamping is:

  ** read: `pin.name = "readvalue"`
  ** read: `pin.name.scaled = ("readvalue" - pin.name.offset) * pin.name.scale`
  ** write: `"sendvalue" = (pin.name - pin.name.offset) * pin.name.scale`

*timeout* [auto, 1..60000000]::
  The override timeout of '<mesamodbus>[timeout]' for this command in
  *micro-seconds* (send request plus handling plus receive reply) before the
  command is deemed lost. See also 'timeoutbits' below.
  Default '<mesamodbus>[timeout]'.
*timeoutbits* [0..1000000]::
  The override timeout of '<mesamodbus>[timeout]' for this command
  in *bit times* (send request plus handling plus receive reply) before the
  command is deemed lost. The actual timeout is automatically calculated and
  scaled by the '<mesamodbus>[baudrate]' setting. See also 'timeout' above.
  Default '<mesamodbus>[timeout]'.
*timesout* [Boolean]::
  Set to true if the command is known to (periodically) timeout and no error
  should be emitted when it does. This differs from 'noanswer' in that a reply
  may be expected within the timeout period but not after the timeout expires.
  This may be required for flaky devices. Default false.
*unaligned* [Boolean]::
  Set to true to suppress the alignment warning in multi-register reads or
  writes where 32-bit or 64-bit values are not aligned to their natural Modbus
  address boundaries. This is useful for devices that do not care about
  alignment or do not use Modbus addresses in conventional ways. +
  Setting 'unaligned' is purely a cosmetic attribute to suppress console
  clutter when compiling the mbccs file. It has no functional effect on the
  communication with the device. Default false.
*writeflush* [Boolean]::
  The override the 'writeflush' value. See '<mesamodbus>[writeflush]' for
  details. Default '<mesamodbus>[writeflush]'.

==== Pins
Defining '<pin>' tags allows for custom naming schemes and allows reducing read
and write function overhead. Using '<pin>' tags enables you to combine
different 'modbustype' and 'haltype' values to be read or written to or from
consecutive addresses. A warning is emitted if 32-bit and 64-bit values are not
aligned to their native boundary (it may be an error, depending device). The
attributes of the '<command>' tag set the defaults for the '<pin>' tag
attributes and can be overridden by adding them to the '<pin>' tag.

[source,xml]
----
<command device="booboo"
         function="R_REGISTERS"
         address="0x0240"
         haltype="HAL_FLOAT"
         modbustype="F_ABCD"
         scale="1">
  <!-- addr: 0x0240-0x0241; disable scaling pins -->
  <pin name="speed" scale="0" />
  <!-- addr:0x0242; one register to bit-->
  <pin name="ping" haltype="HAL_BIT" modbustype="U_AB" />
  <!-- Align the next value -->
  <pin skip="1" />
  <!-- addr: 0x0244-0x0245; use defaults from this command -->
  <pin name="afloat" />
<!--
  The above <command><pin> tags read 6 registers and generate pins:
  hm2_modbus.0.speed         HAL_FLOAT (out)
  hm2_modbus.0.ping          HAL_BIT   (out)
  hm2_modbud.0.afloat        HAL_FLOAT (out)
  hm2_modbud.0.afloat.offset HAL_FLOAT (in)
  hm2_modbud.0.afloat.scale  HAL_FLOAT (in)
  hm2_modbud.0.afloat.scaled HAL_FLOAT (out)
-->
</command>
----

Recognized '<commands>/<command>/<pin>' attributes:

*clamp* [Boolean]::
  The clamp setting override for this pin.
*haltype* [see link:#_hal_types[*HAL TYPES*]]::
  The HAL type override for this pin.
*modbustype* [see link:#_modbus_types[*MODBUS TYPES*]]::
  The Modbus type override for this pin.
*name*::
  Specifies the pin name overriding the default '<command>[name]-xx' sequence.
  This makes the HAL names more human readable.
*scale* [Boolean]::
  The scale setting override for this pin.
*skip* [0..24]::
  Skip a number of registers ignoring them for read functions and writing
  zero (0) for write functions. There can not be other attributes if the 'skip'
  attribute is used. +
  Using a 'skip' value larger than 11 will emit a warning. Large skips make the
  transfers less efficient and skipping 12+ registers may be better off by
  splitting the function in two commands. An exception may be atomicity where
  the device allows access to the intermediate (unused) register addresses and
  only guarantees atomicity in a single read/write transaction. +
  Beware that the skipped registers *must* be readable or writable (depending
  function). The skipped values must be transferred in the Modbus transaction
  and the target device must allow read or write access to the skipped register
  addresses. +
  Beware:
  using 'skip' in write commands *writes value zero (0) to the skipped registers*.

== SEE ALSO

*linuxcnc*(1),
*hm2_modbus*(9).

https://linuxcnc.org/docs/stable/html/drivers/mesa_modbus.html

== AUTHOR

This man page written by B.Stultiens, as part of the LinuxCNC project.

== REPORTING BUGS

Report bugs at https://github.com/LinuxCNC/linuxcnc/issues

== COPYRIGHT

Copyright © 2025 B.Stultiens

This is free software; see the source for copying conditions. There is
NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.
