Skip to content

Message Types

The Blocks protocol defines two sets of messages: device-to-host (responses, events, topology) and host-to-device (commands, configuration, data writes). This is the complete catalog, covering everything from keepalive pings to pressure-sensitive touch events to heap memory diffs for LED updates.

Every message payload starts with a 7-bit message type followed by an 8-bit protocol version. The remaining bits depend on the message type and are decoded according to the bit sizes in the framing reference.

Device → Host Messages

These messages originate from the device and are received by blocksd.

IDNamePayload
0x01deviceTopology7b deviceCount, 8b connectionCount, then device/connection blocks
0x02packetACK10b packetCounter
0x03firmwareUpdateACK7b code, 32b detail
0x04deviceTopologyExtendcontinuation of topology (multi-packet)
0x05deviceTopologyEndsignals end of multi-packet topology
0x06deviceVersionindex + version string
0x07deviceNameindex + name string
0x10touchStart7b devIdx, 5b touchIdx, 12b x, 12b y, 8b z
0x11touchMovesame as touchStart
0x12touchEndsame as touchStart
0x13touchStartWithVelocity+ 8b vx, 8b vy, 8b vz
0x14touchMoveWithVelocity+ velocity
0x15touchEndWithVelocity+ velocity
0x18configMessageconfig command + data
0x20controlButtonDown7b devIdx, 12b buttonID
0x21controlButtonUp7b devIdx, 12b buttonID
0x28programEventMessage3 x 32b integers
0x30logMessagestring data

deviceTopology (0x01)

The primary topology response. Contains a count of devices and connections, followed by device info blocks and connection info blocks. See Topology for the full format.

packetACK (0x02)

Acknowledges receipt of a host-to-device packet. Contains a 10-bit packet counter that matches the counter from the original message. blocksd uses ACKs to track keepalive status and data change delivery.

Touch Events (0x10-0x15)

Touch events report finger position and pressure on the device surface. The x and y fields are 12-bit fixed-point values representing position on the touch surface. The z field is an 8-bit pressure value. Velocity variants add 8-bit velocity components for each axis.

blocksd normalizes these to floating-point values in the 0.0-1.0 range before exposing them through the external API.

configMessage (0x18)

Device configuration responses. The payload starts with a 4-bit config command followed by an 8-bit item index and 32-bit value. Used for both config sync (factory and user) and individual config reads.

controlButton Events (0x20-0x21)

Button press and release events. The 12-bit button ID identifies which physical button was pressed. Used by Control Blocks, Live Blocks, and similar devices with discrete buttons.

logMessage (0x30)

Free-form log output from the device. Useful for debugging LittleFoot programs or diagnosing firmware issues. The payload is a variable-length string.

Host → Device Messages

These messages are sent by blocksd to the device.

IDNamePayload
0x01deviceCommandMessage9b command (see Device Commands below)
0x02sharedDataChange16b packetIndex + data change commands
0x03programEventMessage3 x 32b integers
0x04firmwareUpdatePacket7b size + 7-bit encoded data
0x10configMessage4b configCmd + item + value
0x11factoryReset(no payload)
0x12blockReset(no payload)
0x20setName7b length + 7-bit chars

Device Commands (inside deviceCommandMessage)

The 9-bit command field in deviceCommandMessage selects the operation:

IDNameDescription
0x00beginAPIModeEnter rich protocol mode. Required before touch events or LED control.
0x01requestTopologyMessageRequest the current topology report.
0x02endAPIModeExit rich protocol mode. Device returns to basic MIDI.
0x03pingKeepalive ping. Must arrive within 5000ms or device exits API mode.
0x04debugModeEnable debug logging on device.
0x05saveProgramAsDefaultSave the current LittleFoot program as the device's default.

sharedDataChange (0x02)

The mechanism for writing data to the device's heap memory. Used for LED bitmap updates and LittleFoot program uploads. The payload starts with a 16-bit packet index (for ACK tracking), followed by a sequence of data change commands.

See Data Change Commands below.

Config Commands

The 4-bit config command field selects the configuration operation:

IDNameDescription
0x00setConfigWrite a config value
0x01requestConfigRead a config value
0x02requestFactorySyncRequest all factory config values
0x03requestUserSyncRequest all user config values
0x04updateConfigUpdate config (factory)
0x05updateUserConfigUpdate config (user)
0x06setConfigStateSet config state
0x07factorySyncEndEnd of factory sync
0x08clusterConfigSyncCluster config sync
0x09factorySyncResetFactory sync reset

Data Change Commands

Data change commands encode diff-based heap writes using a compact RLE scheme. They are packed within sharedDataChange messages.

Each command starts with a 3-bit command ID:

IDNameExtra BitsDescription
0endOfPacketEnd of this packet's changes
1endOfChangesAll changes complete
2skipBytesFew4b countSkip 1-15 heap bytes
3skipBytesMany8b countSkip 1-255 heap bytes
4setSequenceOfBytes(8b value + 1b continue) x NWrite a sequence of distinct bytes
5setFewBytesWithValue4b count + 8b valueWrite 1-15 copies of a value
6setFewBytesWithLastValue4b countWrite 1-15 copies of the previous value
7setManyBytesWithValue8b count + 8b valueWrite 1-255 copies of a value

The data change encoder walks the heap diff and selects the most compact command for each run. Skips over unchanged regions, uses RLE for repeated bytes, and falls back to byte sequences for unique data.

Released under the ISC License.