= hm2_modbus(9)

== NAME

hm2_modbus - A hostmot2 driver that implements the Modbus protocol using the
PktUART ports.

== SYNOPSIS

*loadrt hm2_modbus ports=... mbccbs=...*

*ports* [default: <empty>]::
  A comma separated list of PktUART HAL names to use as Modbus hardware
  channel. Each must be matched with an MBCCB file specified in the *mbccbs*
  parameter. Example: `ports="hm2_7i96s.0.pktuart.0","hm2_5i25.0.pktuart.2"`
*mbccbs* [default: <empty>]::
  A comma separated list of "Modbus Command Control Binary" (MBCCB) file paths
  to use for each PktUART port as specified in the *ports* parameter. The path
  should be an absolute path to prevent nasty surprises.
  Example: `mbccbs="/path/to/rly-and-spindle.mbccb","/path/to/lightsparks.mbccb"`
*debug* [default: -1]::
  Set the message level of the running process. The message level is set
  if *debug* is set to a positive value between 0 and 5, where 0 means no
  messages at all and 5 means everything. A value of -1 does not touch the
  current message level. +
  Caveat Emptor: the driver must be compiled with debug messages enabled for it
  to start emitting messages at the debug level. Changing the message level is
  process-wide and all modules within the process will spit out messages at the
  requested level. This may cause quite some clutter in your terminal.


== DESCRIPTION

The *hm2_modbus* driver implements the Modbus protocol and maps HAL pins to
Modbus devices' coils, inputs and registers. The mappings may be a complex
combination of types and pins. The configuration format is described in
*mesambccc*(1).

The Mesa FPGA board must be flashed with a PktUART capable bit-file. It is
recommended to use an FPGA bit-file that supports PktUART version 3 or later.
The *hm2_modbus* driver will run with PktUART version 2, but it will lack
several important bug fixes and features, like 2 stop-bits, correct and
extended inter-frame delay for high speed communication and inter-character
delay measurements. Warnings will be emitted if communication settings cannot
be honored by the older PktUART version. PktUART versions older than 2 are not
supported and the driver will abort with an error if encountered.

The driver exports a set of HAL pins and parameters that can be used to inspect
status and alter some settings in a live environment.

Up to eight instances are supported, which are instantiated by setting
the *ports* and *mbccbs* parameters. The instances are
named 'hm2_modbus.0', 'hm2_modbus.1', etc.. The pin names generated by the
driver will always be prefixed with the driver's name.

[source,sh]
----
loadrt hm2_modbus ports="7i96s.0.pktuart.0" mbccbs="/path/to/myfile.mbccb"
----

The driver exports one function named 'process', which must be added to the
servo-thread _after_ hostmot2's read function and _before_ hostmot2's write
function:

[source,sh]
----
addf hm2_7i96s.0.read     servo-thread
...
# Add any functions here that process data that will be sent to
# the Modbus device(s).
...
addf hm2_modbus.0.process servo-thread
...
# Add any functions here that process data received from the
# Modbus device(s).
...
addf hm2_7i96s.0.write    servo-thread
----

There are no software limits to how many Modbus devices may share one and the
same physical bus and by extension the same hm2_modbus instance. The Modbus
protocol limits the number of devices to 247 (available device IDs). However,
the practical limit will be effective communication speed and bus load.

=== PARAMETERS
Exported parameters for driver instance `N`:

hm2_modbus.N.baudrate (u32, readonly)::
  The communication baudrate.
hm2_modbus.N.drivedelay (u32, readonly)::
  The transmitter wait time between enabling the transmitter and start sending
  in bit-times.
hm2_modbus.N.icdelay (u32, readonly)::
  The maximum inter-character delay accepted in received frames in bit-times.
  Set to zero (0) when disabled.
hm2_modbus.N.parity' (u32, readonly)::
  The communication parity (0=None, 1=Odd, 2=Even).
hm2_modbus.N.rxdelay (u32, readonly)::
  The inter-frame delay required before a packet is accepted in bit-times.
hm2_modbus.N.stopbits (u32, readonly)::
  The communication number of stopbits (1 or 2).
hm2_modbus.N.txdelay (u32, readonly)::
  The inter-frame delay inserted after a packet in bit-times.

The parameters are all read/only. There is normally no need to alter any
parameters. Any tuning of values should be done in the mbccs/mbccb file.

=== PINS

Each driver instance `N` exports the following pins to control the instance's
operation and indicate the instance's status:

hm2_modbus.N.fault (bit, output)::
  Indicates a fault condition.
hm2_modbus.N.fault-command (u32, output)::
  The command index that caused the last fault condition.
hm2_modbus.N.last-error-code (u32, output)::
  The errno value of the error that caused the fault condition.
hm2_modbus.N.reset (bit, input)::
  Reset all commands error counters and re-enable disabled commands on the
  rising edge of the input pin.
hm2_modbus.N.suspend (bit, input)::
  Suspend all activity while set. The default can be set in the MBCCB file. +
  Suspended start (when set in the MBCCB file) can ensure that all HAL files
  and commands are parsed and executed (like setp and sets commands) before
  Modbus communication starts. This enables you to setup scale and offset pins
  without bad values being pushed to the Modbus device(s). The _last_ HAL
  command after setting all relevant pins and signals would be to enable Modbus
  communication by isssuing (replace `N` with actual instance number): +
  `setp hm2_modbus.N.suspend false` +
  It may be necessary to issue a delay command as the first or last init
  command to ensure flushing all pins before reading pin data that will be
  transferred to the Modbus device(s). See also 'writeflush' attribute in the
  MBCCB file. +
  It is possible to suspend the Modbus communication by setting the suspend pin
  to true in a live and running system. The suspend pin is probed every time at
  the end of the '<commands>' list and execution will become suspended if the
  pin is true.

==== Command pins
Each command in the MBCCB file (not init commands) will generate a set of pins
to reflect the current state, where `MM` is the command number counting from zero
(00):

hm2_modbus.N.command.MM.disable (bit, input)::
  Disable this command on the rising edge of this pin. You need to use the
  command's corresponding reset pin to re-enable it.
hm2_modbus.N.command.MM.disabled (bit, output)::
  Set if the command is no longer sent in the commands loop.
hm2_modbus.N.command.MM.error-code (u32, output)::
  The errno code of the last error. The following error codes can be set:

  ** 5,  0x05 (EIO): The receiver detected an overrun, a false start-bit or wrong parity.
  ** 9,  0x09 (EBADF): The reply returned an unsupported function.
  ** 11, 0x0b (EAGAIN): The command was manually disabled in the mbccb or via the disable pin.
  ** 22, 0x16 (EINVAL): An invalid value was detected (internal error).
  ** 27, 0x1b (EFBIG): The received data packet size exceeds the internally allocated buffer.
  ** 34, 0x22 (ERANGE): The received data packet was too small or the message's length indicator was wrong.
  ** 42, 0x2a (ENOMSG): The inter-character delay was too long and the packet was dropped.
  ** 44, 0x2c (ECHRNG): The reply had a different function than the sent function.
  ** 52, 0x34 (EBADE): The CRC of the received packet was wrong.
  ** 74, 0x4a (EBADMSG): The reply had the error-bit set.
  ** 75, 0x4b (EOVERFLOW): The received packet was larger than the maximum 256 bytes.
  ** 90, 0x5a (EMSGSIZE): The message did not fit into the maximum PDU size of 253.
  ** 110, 0x6e (ETIMEDOUT): The command received no reply and timed out.

hm2_modbus.N.command.MM.errors (u32, output)::
  The number of consecutive errors seen in this command. The command will be
  disabled when this count reaches five (5). The value will be reset to zero (0)
  when the command succeeds.
hm2_modbus.N.command.MM.reset (bit, input)::
  Reset this command's error counter and re-enable the command on the rising
  edge of the input pin. +
  Note: Re-enabling the command will honor the 'writeflush' setting of the
  command.

Each mbccb file will generate a set of pins as defined in the mbccb file. See
*mesambccc*(1) for details.

== SEE ALSO

*hostmot2*(9),
*mesambccc*(1).

== 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.
