# MSCB protocol

This section specifies the node-bus protocol implemented by the current
software and firmware.

## Communication model

MSCB uses a master/slave exchange on a half-duplex RS-485 bus. A master sends
an address cycle followed by a command. Only the addressed node replies. More
than one master can share a bus when ownership is passed through the token-ring
mechanism; ordinary node traffic remains master initiated.

Each serial character has an additional ninth data bit:

- ninth bit **1**: address byte;
- ninth bit **0**: command, parameter, response, or CRC byte.

This lets every node recognize an address cycle in hardware, without parsing
all traffic. The bit order and electrical levels are described under
[RS-485 bus](../hardware/bus.md#serial-character).

## Command-byte encoding

The upper five bits identify the command family. The lower three bits encode
the number of bytes that follow the command byte:

| Low bits | Meaning |
|---:|---|
| `0`–`6` | Exactly that many bytes follow |
| `7` | A separate length field follows |

For the extended form, a length byte below `0x80` represents 0–127 bytes. If
its high bit is set, it is the most significant byte of a two-byte, 15-bit
length, allowing 128–32767 bytes. The length counts command parameters and
data, but not the command byte or final CRC.

Examples:

```text
0xA1 index crc                         READ, 1-byte payload
0xAF 0x06 first last data... crc       WRITE_RANGE, 6-byte payload
0xBF 0x80 0x07 ... crc                 READ_MEM, long length = 7
```

## Byte order

Multi-byte parameters are generally sent least significant byte first. Several
command formats deliberately specify another
order, notably 16-bit node addresses and variable values, which are transmitted
most significant byte first. Follow the byte order shown in each command table;
it is authoritative for that field.

## CRC-8

All complete command and response telegrams use an 8-bit CRC with polynomial
x⁸ + x⁵ + x⁴ + 1 (`0x31`). The CRC covers the command or response byte and all
length, parameter, and data bytes before the CRC. Address-cycle bytes are not
part of the command CRC.

Reference algorithm:

```c
unsigned char crc8(const unsigned char *data, int len)
{
    unsigned char crc = 0;
    while (len--) {
        crc ^= *data++;
        for (int i = 0; i < 8; i++)
            crc = (crc & 0x80) ? (crc << 1) ^ 0x31 : crc << 1;
    }
    return crc;
}
```

A receiver silently discards a telegram with a bad CRC. For acknowledged
writes the node returns the received command CRC; the master compares it and
retries if it differs.

## Address cycle

An address telegram is the command byte, the address bytes listed below, and a
CRC. **Every byte of that telegram, including the CRC, is sent with the ninth
bit set.**

| Command | Value | Bytes following | Purpose |
|---|---:|---|---|
| `MCMD_ADDR_NODE8` | `0x09` | node low byte | Select an 8-bit node address |
| `MCMD_ADDR_NODE16` | `0x0A` | node MSB, node LSB | Select a 16-bit node address |
| `MCMD_ADDR_GRP8` | `0x11` | group low byte | Select an 8-bit group address |
| `MCMD_ADDR_GRP16` | `0x12` | group MSB, group LSB | Select a 16-bit group address |
| `MCMD_ADDR_BC` | `0x10` | none | Broadcast to all nodes |
| `MCMD_PING8` | `0x19` | node low byte | Probe an 8-bit node address |
| `MCMD_PING16` | `0x1A` | node MSB, node LSB | Probe a 16-bit node address |

Fresh nodes use node address `0xFFFF`. Ping is itself an address-cycle command;
a matching node responds with `0x78` and no CRC. The response target is
an acknowledgement within 100 µs, while the documented master ping timeout is
400 µs.

For an 8-bit address cycle, every participating node must have a zero high
address byte. Once a node or group is selected it remains selected for normal
commands until another address cycle is issued.

Group and broadcast addressing can only be used with operations that do not
need a unique reply: unacknowledged write, set baud rate, freeze, and
synchronization. A group address cannot safely be used with a normal read or
acknowledged write because several nodes could transmit simultaneously.

## Transaction shape

```mermaid
sequenceDiagram
    participant M as Master
    participant S as Submaster
    participant N as Addressed node
    M->>S: UDP request
    S->>N: address cycle (bit 9 = 1)
    S->>N: command + parameters + CRC (bit 9 = 0)
    N-->>S: ACK/data + CRC
    S-->>M: UDP reply
```

The UDP envelope is a submaster transport and is not placed on the RS-485
wire. See [Ethernet transport](ethernet.md).

## Variable model

A node exposes up to 256 variables at indexes 0–255. A variable has a width of
1–256 bytes, a name, flags, a unit and metric prefix, and optional status bits.
Nodes normally map variables onto RAM and copy persistent values to flash or
EEPROM when `FLASH` is issued. Metadata queries make the network
self-documenting; no central register map is required.

Node firmware invokes its application hook when a variable is read or written,
allowing the value to be transferred to an ADC, DAC, or other physical entity.
Pure configuration variables can remain as local RAM values.

## Robustness rules

- Discard any telegram whose CRC is wrong.
- An omitted channel/index defaults to zero for commands that permit that
  shorthand.
- On an acknowledged write, compare the returned CRC with the command CRC and
  retry on mismatch.
- Do not expect replies to group or broadcast operations.
- Use the timeout class appropriate to the operation; flash and upgrade are
  intentionally much slower than reads.

Continue with the [command reference](commands.md) and
[response formats](responses.md).
