Cyphal interface

Cyphal is a publish-subscribe protocol and the primary communication interface to FluxGrip. The product uses the DSDL data serialization format; the data type definitions shown here are given in DSDL notation. The .dsdl schema files are available in the zubax namespace.

Important

This chapter applies to FluxGrip firmware v1.1 and newer. Firmware v1.0 is based on the older Cyphal/CAN v1.0 specification and is documented in a separate chapter. While the two versions are very different, they remain wire-compatible.

Useful tools

  • Cynic CLI tool with the FluxGrip usage examples on the forum; this is the AI agent-friendly choice.

  • Cyanide is a browser-based human-friendly alternative; a tutorial is available on the forum.

Topics

Topic

Direction

Data type

Description

feedback

publish

zubax.fluxgrip.Feedback.1.1

Magnet state information

command.i8

subscribe

int8

Magnet control input

com.zubax.fluxgrip/<uid>/zubax.manage

subscribe

zubax.fluxgrip.Manage.0.1

Management service: info, remapping, configuration, firmware update, …

The <uid> is a placeholder for the hexadecimal 64-bit unique-ID of the device; e.g., 29fa446ac8468b73. It cannot be changed, and it globally uniquely identifies each product instance.

The Cyphal home (the topic prefix that the ~ token expands into) is set to com.zubax.fluxgrip/<uid>; thus, any topic that starts with ~ gets a unique name per magnet instance.

Feedback publication

The feedback topic carries zubax.fluxgrip.Feedback at 1 Hz.

Definition of zubax.fluxgrip.Feedback.1.1; extent 63 bytes:

 1# Zubax FluxGrip electropermanent magnet status feedback message.
 2
 3bool magnetized
 4# Preserved for wire compatibility with v1.0. Reports incorrect state during state transition. Do not use.
 5
 6int3 remagnetization
 7# Preserved for wire compatibility with v1.0. Do not use.
 8
 9void1
10
11int3 STATE_FAULT            = -4    # Inoperable; use the fault clear command to recover. Magnet state unknown.
12int3 STATE_DEMAGNETIZED     = -2
13int3 STATE_DEMAGNETIZATION  = -1    # Demagnetization in progress
14int3 STATE_UNKNOWN          =  0
15int3 STATE_MAGNETIZATION    = +1    # Magnetization in progress
16int3 STATE_MAGNETIZED       = +2
17int3 state
18# The most accurate magnet state report.
19
20@assert _offset_ == {8}
21
22uint24[2] cycles_on_off
23# The number of magnetization and demagnetization cycles commenced, respectively, since the device was powered on.
24# The values are incremented immediately at the commencement of the cycle.
25
26uint8 error_code
27# Any value other than zero indicates an error.
28
29@extent 63 * 8

Command subscription

The command topic carries an 8-bit integer (int8, one byte) which is interpreted as a command: 0 – OFF; 1 – ON; 2 – FORCE.

Management subscription

The management topic is an RPC-service implementing zubax.fluxgrip.Manage.

Definition of zubax.fluxgrip.Manage.0.1; extent 270 / 270 bytes:

 1# A structural subtype of zubax.node.Manage.
 2# Currently it looks odd because DSDL doesn't yet have built-in support for subtyping.
 3# Eventually it will replace the leading variants with something like `@extend zubax.node.Manage`.
 4
 5@union
 6
 7uint16 STRING_CAPACITY = 256
 8
 9zubax.Empty.1.0 get_info
10# Return the Info struct. Must be supported.
11# Results: info
12
13utf8[<=STRING_CAPACITY] remap
14# Set the Cyphal topic remap string of the form `from1=to1 from2=to2 ...`. Must be supported.
15# The node namespace is set as the leading `=namespace` token (the `from` part is omitted, must be the first entry).
16# Results: success | invalid | refused | internal_error
17
18bool reveal
19# If true, make the node reveal its identity through some recognizable physical signal, such as lighting an LED,
20# displaying a message, producing sound, etc. This is used for mapping network nodes to their physical bodies.
21# How long the reveal signal remains active is implementation-defined. Typically, the signal may remain active
22# until a false reveal command it sent, or until the next substantial state change of the node (e.g., reboot).
23# Results: success | unsupported | internal_error
24
25utf8[<=STRING_CAPACITY] command
26# A node-specific shell command.
27# Results: (any)
28
29zubax.Empty.1.0 reserved_tag_04
30zubax.Empty.1.0 reserved_tag_05
31zubax.Empty.1.0 reserved_tag_06
32zubax.Empty.1.0 reserved_tag_07
33zubax.Empty.1.0 reserved_tag_08
34zubax.Empty.1.0 reserved_tag_09
35zubax.Empty.1.0 reserved_tag_10
36zubax.Empty.1.0 reserved_tag_11
37zubax.Empty.1.0 reserved_tag_12
38zubax.Empty.1.0 reserved_tag_13
39zubax.Empty.1.0 reserved_tag_14
40zubax.Empty.1.0 reserved_tag_15
41zubax.Empty.1.0 reserved_tag_16
42zubax.Empty.1.0 reserved_tag_17
43zubax.Empty.1.0 reserved_tag_18
44zubax.Empty.1.0 reserved_tag_19
45
46# FluxGrip-specific commands follow.
47
48bool restart
49# If false, just restart. If true, reset to factory defaults and restart.
50
51Config.0.1[<=1] configure
52# If nonempty, apply the new configuration. If empty, read the current one. A restart is needed to save/apply.
53# Result: config | invalid | refused | internal_error
54
55@extent 270 * 8
56
57---
58
59@union
60
61uint16 STRING_CAPACITY = 256
62
63zubax.Empty.1.0           success
64zubax.Empty.1.0           unsupported
65uint32                    invalid           # implementation-specific code
66uint32                    refused           # implementation-specific code
67uint32                    internal_error    # implementation-specific code
68zubax.node.Info.0.1       info
69uint8[<=STRING_CAPACITY]  output            # Mostly intended for the command result.
70
71zubax.Empty.1.0 reserved_tag_07
72zubax.Empty.1.0 reserved_tag_08
73zubax.Empty.1.0 reserved_tag_09
74zubax.Empty.1.0 reserved_tag_10
75zubax.Empty.1.0 reserved_tag_11
76zubax.Empty.1.0 reserved_tag_12
77zubax.Empty.1.0 reserved_tag_13
78zubax.Empty.1.0 reserved_tag_14
79zubax.Empty.1.0 reserved_tag_15
80zubax.Empty.1.0 reserved_tag_16
81zubax.Empty.1.0 reserved_tag_17
82zubax.Empty.1.0 reserved_tag_18
83zubax.Empty.1.0 reserved_tag_19
84
85# FluxGrip-specific commands follow.
86
87Config.0.1 config
88# The current (applied) configuration.
89
90@extent 270 * 8

The remapping syntax is defined in the Cy documentation. The configuration structure is documented in a dedicated section. Changes to remap and configure take effect after a restart.

Firmware update

To commence firmware update, issue a management request with the command option populated with a string of the form upd <file_path> <file_server_topic>, where <file_path> carries the firmware file path on the file server (see below) and the <file_server_topic> is the name of the Cyphal topic that the file server is subscribed to.

Once the firmware update process is commenced, the device will start issuing requests of type zubax.file.Read on the <file_server_topic> until the firmware file is fully transferred. Afterward, the bootloader will be invoked to verify and install the downloaded image.

It is guaranteed that during the file transfer, the requested size does not exceed 512 bytes.

Definition of zubax.file.Read.0.1; extent 2048 / 65547 bytes:

 1# Request partial file content from the remote.
 2# The array capacities are intended to be overridable; for example, a memory-limited embedded node using this
 3# type to read files from a remote may set the path capacity to 128 bytes and the data capacity to 256 bytes.
 4
 5int48 seek
 6# Read offset in bytes. A non-negative value specifies the offset from the origin; a negative value specifies the
 7# offset from the point two bytes past the last byte of the file. Given contents "abcdef", offset values point to:
 8#
 9#   Offset  Points to
10#    1      b
11#    0      a
12#   -1      immediately past f; append on write, return empty on read
13#   -2      f
14#   -7      a
15#   -8      implementation-defined
16#
17# If the file is empty, 0 and -1 are equivalent. Negative seek values pointing before the origin are handled in an
18# implementation-defined way. Negative seeks may result in ERROR_SEEK if not supported.
19
20uint16 size
21# Read at most this many bytes.
22# This can be used by resource-constrained nodes to specify how much data they are ready to accept.
23
24void16
25
26utf8[<=1024] path
27# Resource-limited nodes may override the capacity.
28
29@assert _offset_.min == 8 * 12
30@extent 2048 * 8
31
32---
33
34int48 seek
35# The offset of the first data byte relative to the file origin, always nonnegative.
36# Can be used to check the file size by writing zero bytes at seek=-1.
37
38Error.0.1 error
39
40bool end        # Last data byte is the last byte of entry.
41void23          # May be extended with extra flags in the future, e.g. directory, immutable...
42
43byte[<2**16] data
44# Empty data indicates that seek points past the end.
45# If error is non-zero, this field may contain implementation-defined additional error context.
46# The size cannot exceed the size specified in the request.
47# Memory-constrained nodes thus can arbitrarily override the array capacity and set the size accordingly.
48
49@assert _offset_.min == 8 * 12
50@sealed

Definition of zubax.file.Error.0.1; extent 1 bytes:

 1uint4 ERROR_OK          = 0
 2uint4 ERROR_SEEK        = 1     # Entry is not seekable.
 3uint4 ERROR_SUPPORT     = 2     # Requested protocol feature is not implemented.
 4uint4 ERROR_EXISTENCE   = 3     # Entry does not exist when it should, or exists when it shouldn't.
 5uint4 ERROR_KIND        = 4     # E.g., attempted to write an entry which is a directory.
 6uint4 ERROR_CAPACITY    = 5     # Out of storage space or entry size limit.
 7uint4 ERROR_PERMISSION  = 6     # E.g., entry is not mutable.
 8uint4 ERROR_RUNTIME     = 7     # Error coming from the low-level execution environment; e.g., IO error.
 9uint4 ERROR_OTHER       = 15
10uint4 error
11
12void4
13
14@sealed

Examples with Cynic CLI tool

# Remap the command topic to `magnets/payload-1`
cn req com.zubax.fluxgrip/29fa446ac8468b73/zubax.manage -- '{remap: "command.i8=/magnets/payload-1"}'

# Reboot two FluxGrips for the changes to take effect
cn req com.zubax.fluxgrip/29fa446ac8468b73/zubax.manage \
       com.zubax.fluxgrip/2cb553eaeab5ec95/zubax.manage -- '{restart: false}'

# Commence firmware update on several units simultaneously, assuming the file server is subscribed to `firmware-topic`
cn req com.zubax.fluxgrip/29fa446ac8468b73/zubax.manage \
       com.zubax.fluxgrip/2cb553eaeab5ec95/zubax.manage -- '{command: "upd firmware.bin firmware-topic"}'

# Run the file server
cn fs firmware-topic

Configuration

The device configuration can be read or written via the management topic. The configuration structure definition is shown below.

Definition of zubax.fluxgrip.Config.0.1; extent 256 bytes:

 1# FluxGrip device configuration. The new configuration is persisted when the node is restarted.
 2# The Cyphal topic remap string is configured separately.
 3
 4uint8 VERSION_VALID = 1
 5uint8 version
 6
 7uint3 prio_feedback     # Message priority of the feedback topic. Lower values have higher priority.
 8void20
 9bool enable_second_can_interface
10
11uint32 can_bitrate      # Nominal bitrate of all CAN interfaces [bit/s].
12
13void64
14void64
15void64
16void64
17
18int32 flyback_period_ns       # PWM period [ns].
19uint16[9] target_duty_cycle   # Target duty cycle for each bus-voltage bucket, scaled by 1e3.
20uint16[9] min_duty_cycle      # Minimum duty cycle for each bus-voltage bucket, scaled by 1e3.
21uint16[9] ramp_cap_voltage    # Capacitor voltage where the target duty is reached for each bucket [V].
22int8[64] ds
23# Do not alter unless advised by Zubax.
24
25@extent 256 * 8

Transports

Cyphal/CAN

A single or doubly-redundant CAN bus interface is available in some hardware models. The primary interface is labeled CAN0 and the redundant, if available, is labeled CAN1.

Important

Firmware revisions prior to v1.3 do not support CAN FD; only Classic CAN is supported. Contact Zubax for details.

The supported arbitration-phase bit rates are 100, 125, 250, 500, 800, and 1000 kbit/s. The factory default is 1 Mbit/s.

The device automatically recovers from the bus-off and error-passive states following the CAN bus specification.

For the CAN hardware specifications, please refer to your product documentation.

“On CAN bus topology and termination” provides recommendations on the usage of CAN bus in relevant applications.

Cyphal/UDP via SPE 10BASE-T1S

Please contact Zubax Robotics.