Summary

DHD RM4200D DSP Frame controllers (RM420-850, RM420-852, RM420-853) implement the DHD External Control Protocol (ECP) over RS-232, RS-422, and TCP/IP. This spec covers the ECP command set for routing, fader control, I/O gain, logic, metering, monitoring, and snapshot save/load. DHD marks ECP deprecated as of firmware 10.2; new integrations should use the Control API.

Transport

protocols:
  - serial
  - tcp
addressing:
  port: 2008
serial:
  baud_rate: 38400
  data_bits: 8
  parity: none
  stop_bits: 1
  flow_control: none
auth:
  type: none  # inferred: no login/auth procedure described in source

Traits

- routable  # inferred from Set Output Routing commands (0x01F5xxxx, 0x11000000)
- levelable  # inferred from Set Fader Level (0x11030000), Set Monitor Level (0x11100000), Set IO Gain (0x112D0000)
- queryable  # inferred from request variants of routing, fader, gain, logic, PFL commands

Actions

- id: set_output_routing_16bit
  label: Set Output Routing (16bit)
  kind: action
  command: "0x01F5xxxx"
  params:
    - name: length
      type: integer
      description: "0=request all, 2=request one, 4=set"
    - name: output_hi
      type: integer
      description: "Output address high byte (slot 1..30)"
    - name: output_lo
      type: integer
      description: "Output address low byte (port within slot)"
    - name: input_hi
      type: integer
      description: "Input address high byte"
    - name: input_lo
      type: integer
      description: "Input address low byte (0xFFFF = Mute)"

- id: set_output_routing_32bit
  label: Set Output Routing (32bit)
  kind: action
  command: "0x01F5xxxx"
  params:
    - name: length
      type: integer
      description: "1=notification, 5=request one, 8=set"
    - name: output_id
      type: integer
      description: "32bit Output AudioID"
    - name: input_id
      type: integer
      description: "32bit Input AudioID (0x00000000 = Mute)"

- id: crosspoint_notification_enable
  label: Enable Crosspoint Notification (TCP only)
  kind: action
  command: "0x01F5xxxx"
  params:
    - name: enable
      type: integer
      description: "0=deactivate, 1=activate"

- id: set_arbitration
  label: Set Arbitration
  kind: action
  command: "0x01F90000"
  params:
    - name: length
      type: integer
      description: "4=request, 5=set"
    - name: audio_id
      type: integer
      description: "32bit Output/Input AudioID"
    - name: device_id
      type: integer
      description: "Owner device ID (0x00=no owner, 0x40..0x60=owner)"

- id: set_monitor_channel
  label: Set Monitor Channel
  kind: action
  command: "0x11000000"
  params:
    - name: input_left_hi
      type: integer
      description: "Left input address high"
    - name: input_left_lo
      type: integer
      description: "Left input address low"
    - name: monitor_number
      type: integer
      description: "Monitor selector channel (0..5 fw05, 0..199 fw06+)"
    - name: input_right_hi
      type: integer
      description: "Right input address high"
    - name: input_right_lo
      type: integer
      description: "Right input address low"

- id: set_fader_on_off
  label: Switch Fader/Channel On/Off
  kind: action
  command: "0x11020000"
  params:
    - name: fader_hi
      type: integer
      description: "Virtual Mixer selector (0x00..0x03) or 0x10 for fader channel addressing"
    - name: fader_lo
      type: integer
      description: "Fader/LogicFader number"
    - name: on
      type: integer
      description: "1=on, 0=off"

- id: set_fader_level
  label: Set Fader Level
  kind: action
  command: "0x11030000"
  params:
    - name: fader_hi
      type: integer
      description: "Virtual Mixer (0x00..0x03) or 0x10 for channel addressing"
    - name: fader_lo
      type: integer
      description: "Fader/LogicFader number"
    - name: level_hi
      type: integer
      description: "Level high (0x8000..0x7FFF = -327.68..327.67 dB)"
    - name: level_lo
      type: integer
      description: "Level low"
    - name: time_hi
      type: integer
      description: "Fade time high (ms)"
    - name: time_lo
      type: integer
      description: "Fade time low (ms, 0x0000..0x2000)"
    - name: type
      type: integer
      description: "0=level linear fade, 1=fader linear fade"

- id: fader_value_notification_enable
  label: Enable Fader Value Notification
  kind: action
  command: "0x11030000"
  params:
    - name: enable
      type: integer
      description: "0=deactivate, 1=activate (fw 07.02.09+)"

- id: set_fader_access
  label: Set Fader Access
  kind: action
  command: "0x11040000"
  params:
    - name: fader_hi
      type: integer
      description: "Virtual Mixer (0x00..0x03) or 0x10 for channel"
    - name: fader_lo
      type: integer
      description: "Fader/LogicFader number"
    - name: on
      type: integer
      description: "0=off, 1=on"
    - name: type
      type: integer
      description: "0=GAIN, 1=PAN/BAL, 2=INPUTSELECT"
    - name: channel_hi
      type: integer
      description: "Channel high (answer only)"
    - name: channel_lo
      type: integer
      description: "Channel low (answer only)"
    - name: acc_group
      type: integer
      description: "Acc-Group 1..6 (answer only)"

- id: set_channel_input_number
  label: Set Channel Input Number
  kind: action
  command: "0x110D0000"
  params:
    - name: fader_hi
      type: integer
      description: "Virtual Mixer (0x00..0x03)"
    - name: fader_lo
      type: integer
      description: "LogicFader number"
    - name: channel_hi
      type: integer
      description: "Channel number high (1..250)"
    - name: channel_lo
      type: integer
      description: "Channel number low"

- id: set_internal_logic_state
  label: Set Internal Logic State
  kind: action
  command: "0x110E0000"
  params:
    - name: logic_id_hi
      type: integer
      description: "LogicID high"
    - name: logic_id_lo
      type: integer
      description: "LogicID low"
    - name: on
      type: integer
      description: "0=false/off, 1=true/on"

- id: set_monitor_level
  label: Set Monitor Level (Potentiometer)
  kind: action
  command: "0x11100000"
  params:
    - name: pot_hi
      type: integer
      description: "Potentiometer high (0x0000..0x0077 = pot 1..120)"
    - name: pot_lo
      type: integer
      description: "Potentiometer low"
    - name: level_hi
      type: integer
      description: "Level high (0x8000..0x7FFF = -327.68..327.67 dB)"
    - name: level_lo
      type: integer
      description: "Level low"
    - name: time_hi
      type: integer
      description: "Fade time high (ms)"
    - name: time_lo
      type: integer
      description: "Fade time low (ms, 0x0000..0x2000)"
    - name: type
      type: integer
      description: "0=level linear fade, 1=fader linear fade"

- id: set_display_label
  label: Set Display or Channel Label
  kind: action
  command: "0x11140000"
  params:
    - name: channel_hi
      type: integer
      description: "Channel/module high"
    - name: channel_lo
      type: integer
      description: "Channel/module low (0x0001..0x00BA channel, 0x8001..0x800C module)"
    - name: display_nr
      type: integer
      description: "Display segment number (0x00..0x7F, 4 chars each)"
    - name: ascii1
      type: integer
      description: "ASCII char 1 (0x00..0x7F)"
    - name: ascii2
      type: integer
      description: "ASCII char 2"
    - name: ascii3
      type: integer
      description: "ASCII char 3"
    - name: ascii4
      type: integer
      description: "ASCII char 4"

- id: set_pfl_channel
  label: Set PFL for Channel
  kind: action
  command: "0x11160000"
  params:
    - name: fader_hi
      type: integer
      description: "Virtual Mixer (0x00..0x03) or 0x10 for channel"
    - name: fader_lo
      type: integer
      description: "Fader/LogicFader number"
    - name: on
      type: integer
      description: "1=PFL on, 0=PFL off"
    - name: auto_mute
      type: integer
      description: "1=all others switched off, 0=others unchanged"

- id: pfl_switch_off_all
  label: PFL Switch Off All (Virtual Mixer)
  kind: action
  command: "0x11160000"
  params:
    - name: fader_hi
      type: integer
      description: "Virtual Mixer selector 0x00..0x03 (fw 06+)"

- id: load_save_setups
  label: Load/Save Setups (Snapshot)
  kind: action
  command: "0x111C0000"
  params:
    - name: action
      type: integer
      description: "0x00=Load Channel, 0x01=Save Channel, 0x0a=Load Mixer, 0x0b=Save Mixer"
    - name: snapshot_number
      type: integer
      description: "Mixer 0..20 or Channel 0..250"
    - name: mixer_id
      type: integer
      description: "Virtual Mixer (0x00..0x03) or 0x10 for channel"
    - name: fader_channel
      type: integer
      description: "Fader 0..47 or Channel 0..250"

- id: set_io_gain_16bit
  label: Set IO Gain (16bit)
  kind: action
  command: "0x112D0000"
  params:
    - name: io_hi
      type: integer
      description: "I/O slot high (1..30)"
    - name: io_lo
      type: integer
      description: "I/O port low (0xFFFF = Mute)"
    - name: value_hi
      type: integer
      description: "Gain value high (0x8000..0x7FFF = -327.68..327.67 dB)"
    - name: value_lo
      type: integer
      description: "Gain value low"

- id: set_io_gain_32bit
  label: Set IO Gain (32bit)
  kind: action
  command: "0x112D0000"
  params:
    - name: audio_id
      type: integer
      description: "32bit AudioID of input/output"
    - name: value_hi
      type: integer
      description: "Gain value high (0x8000..0x7FFF = -327.68..327.67 dB)"
    - name: value_lo
      type: integer
      description: "Gain value low"

- id: metering_subscribe
  label: Metering Subscribe
  kind: action
  command: "0x111D0000"
  params:
    - name: leveldetect
      type: integer
      description: "Leveldetect position 1..48"
    - name: on
      type: integer
      description: "0=deactivate, 1=activate notification"

- id: get_set_cf_in_parameter
  label: Get/Set CleanFeed Input Parameter
  kind: action
  command: "0x11810000"
  params:
    - name: channel_hi
      type: integer
      description: "Channel high (1..250)"
    - name: channel_lo
      type: integer
      description: "Channel low"
    - name: cfin_prefix_hi
      type: integer
      description: "CFIn prefix high (0x00)"
    - name: cfin_prefix_lo
      type: integer
      description: "CFIn prefix low (0x24)"
    - name: parameter_value
      type: integer
      description: "32bit CFIn parameter (bits 7..0 = 0xD8..0x0F = -40..0..+15 dB)"

- id: get_set_cf_out_parameter
  label: Get/Set CleanFeed Output Parameter
  kind: action
  command: "0x11810000"
  params:
    - name: channel_hi
      type: integer
      description: "Channel high (1..250)"
    - name: channel_lo
      type: integer
      description: "Channel low"
    - name: cfout_prefix_hi
      type: integer
      description: "CFOut prefix high (0x00)"
    - name: cfout_prefix_lo
      type: integer
      description: "CFOut prefix low (0x25)"
    - name: parameter_value
      type: integer
      description: "32bit CFOut parameter (gain 0xD2..0x0A = -30..0..+10 dB, plus flags)"

- id: request_output_routing_all
  label: Request All Crosspoints (16bit)
  kind: query
  command: "0x01F50000"
  params:
    - name: length
      type: integer
      description: "0"

- id: request_output_routing_one_16bit
  label: Request One Crosspoint (16bit)
  kind: query
  command: "0x01F50000"
  params:
    - name: output_hi
      type: integer
      description: "Output high"
    - name: output_lo
      type: integer
      description: "Output low"

- id: request_output_routing_one_32bit
  label: Request One Crosspoint (32bit)
  kind: query
  command: "0x01F50000"
  params:
    - name: output_id
      type: integer
      description: "32bit Output AudioID"

- id: request_arbitration
  label: Request Arbitration
  kind: query
  command: "0x01F90000"
  params:
    - name: audio_id
      type: integer
      description: "32bit Output/Input AudioID"

- id: request_monitor_channel
  label: Request Monitor Channel
  kind: query
  command: "0x11000000"
  params:
    - name: monitor_number
      type: integer
      description: "Monitor selector number"

- id: request_fader_level
  label: Request Fader Level
  kind: query
  command: "0x11030000"
  params:
    - name: fader_hi
      type: integer
      description: "Virtual Mixer (0x00..0x03) or 0x10 for channel"
    - name: fader_lo
      type: integer
      description: "Fader/LogicFader number"

- id: request_fader_access
  label: Request Fader Access Status
  kind: query
  command: "0x11040000"
  params: []

- id: request_channel_input_number_all
  label: Request All Channel Input Numbers
  kind: query
  command: "0x110D0000"
  params: []

- id: request_channel_input_number
  label: Request Channel Input Number
  kind: query
  command: "0x110D0000"
  params:
    - name: fader_hi
      type: integer
      description: "Virtual Mixer"
    - name: fader_lo
      type: integer
      description: "LogicFader"

- id: request_logic_state
  label: Request Internal Logic State
  kind: query
  command: "0x110E0000"
  params:
    - name: logic_id_hi
      type: integer
      description: "LogicID high"
    - name: logic_id_lo
      type: integer
      description: "LogicID low"

- id: request_monitor_level
  label: Request Monitor Level (Pot)
  kind: query
  command: "0x11100000"
  params:
    - name: pot_hi
      type: integer
      description: "Pot high"
    - name: pot_lo
      type: integer
      description: "Pot low"

- id: request_channel_label
  label: Request Channel Label
  kind: query
  command: "0x11140000"
  params:
    - name: channel_hi
      type: integer
      description: "Channel high"
    - name: channel_lo
      type: integer
      description: "Channel low"
    - name: display_nr
      type: integer
      description: "Display segment number"

- id: request_pfl_state
  label: Request PFL State
  kind: query
  command: "0x11160000"
  params:
    - name: fader_hi
      type: integer
      description: "Virtual Mixer (0x00..0x03) or 0x10 for channel"
    - name: fader_lo
      type: integer
      description: "Fader/LogicFader number"

- id: request_io_gain_16bit
  label: Request IO Gain (16bit)
  kind: query
  command: "0x112D0000"
  params:
    - name: io_hi
      type: integer
      description: "I/O slot high"
    - name: io_lo
      type: integer
      description: "I/O port low"

- id: request_io_gain_32bit
  label: Request IO Gain (32bit)
  kind: query
  command: "0x112D0000"
  params:
    - name: audio_id
      type: integer
      description: "32bit AudioID"

- id: request_cf_in_parameter
  label: Request CleanFeed Input Parameter
  kind: query
  command: "0x11810000"
  params:
    - name: channel_hi
      type: integer
      description: "Channel high"
    - name: channel_lo
      type: integer
      description: "Channel low"
    - name: cfin_prefix_hi
      type: integer
      description: "0x00"
    - name: cfin_prefix_lo
      type: integer
      description: "0x24"

- id: request_cf_out_parameter
  label: Request CleanFeed Output Parameter
  kind: query
  command: "0x11810000"
  params:
    - name: channel_hi
      type: integer
      description: "Channel high"
    - name: channel_lo
      type: integer
      description: "Channel low"
    - name: cfout_prefix_hi
      type: integer
      description: "0x00"
    - name: cfout_prefix_lo
      type: integer
      description: "0x25"

Feedbacks

- id: crosspoint_notification
  type: bytes
  description: "Datagram of length 8 sent when internal routing changes (32bit routing, TCP only, after 0x01F5xxxx with length 1, enable=1)"
- id: fader_value_notification
  type: bytes
  description: "Datagram of length 4 sent when fader value changes (after 0x11030000 with length 1, enable=1; fw 07.02.09+)"
- id: metering_notification
  type: bytes
  description: "Datagram of length 6 with LevelL, LevelR, Correlation (after 0x111D0000 with length 2, on=1; fw 08.01.18+)"
- id: motorfader_touched
  type: bytes
  description: "Datagram of length 2 sent automatically when a motorized fader is touched (0x11820000; ChannelNr 1..250, Touch 0/1)"
- id: arbitration_answer
  type: bytes
  description: "Datagram of length 5 (0x01F90000) returning 32bit AudioID + DeviceID 0x00=free, 0x40..0x60=owner"
- id: ack
  type: bytes
  description: "0x06 - block successfully received"
- id: nak
  type: bytes
  description: "0x05 - block rejected"

Variables

# Source uses 16bit/32bit parameter slots directly in actions; no separate variable list.

Events

# Covered in Feedbacks (crosspoint_notification, fader_value_notification, metering_notification, motorfader_touched).

Macros

# Source does not document multi-step macro sequences; snapshot save/load is handled via 0x111C0000 action.

Safety

confirmation_required_for: []
interlocks:
  - "Arbitration ownership is informational only; firmware does not enforce it. Resource control must be handled by connected applications (source warning)."
  - "I/O Gain changes (0x112D0000) are valid only until next system reset/reboot/power cycle; cannot be changed from the console (source warning)."
  - "On firmware 06.xx.xx and higher, TCP sockets are nonblocking; if data is not fetched fast enough, the socket is automatically closed."

Notes

  • ECP deprecated as of firmware 10.2; new integrations should use DHD Control API.
  • Serial: 38400, 8, N, 1, no protocol. Blocks: STX | Length | 28bit ID | 0-8 data bytes | Checksum | EOT. ACK=0x06, NAK=0x05, DLE=0x0A, STX=0x02, EOT=0x08. Bytes 0x00..0x1F escaped as DLE, byte+0x20. Block must be answered within 80ms; max 3 retransmits; buffer holds 100 blocks.
  • TCP: Port 2008. Block always 16 bytes: 0,0,0,0,L3..L0 | U0 | 0,0,0,ID28..ID24 | ID23..ID16 | ID15..ID8 | ID7..ID0 | B0..B7 | U1 | U2. Motorola-format (MSB first).
  • Multiple AudioID versions exist (V1 for 52/RM4200D/XR, V2 for 52/XS/XC/XD/XS2/XC2/XD2). AudioIDs must be looked up from the project's TB5/TB8 configuration.
  • Per-command firmware gating (from source footnotes):
    • 0x01F5xxxx 32bit: since 06.07.15 / 07.01.16
    • 0x01F90000 (Arbitration): since 07.02.32
    • 0x11030000 fader notification: since 07.02.09
    • 0x11140000 (Channel Label request): since 07.02.10
    • 0x11100000 / 0x11160000 request variants: since 07.04.11
    • 0x111D0000 (Metering): since 08.01.18
    • 0x11810000 (CF In/Out): since 09.00.05
  • Virtual Mixer addressing: FaderHi 0x00..0x03 = VM1..VM4 with FaderLo as LogicFader (0x00..0x2F); FaderHi 0x10 = FaderLo as Fader Channel Number 1..150.
  • Firmware 05.xx.xx uses FaderLo 0x00..0x27 with FaderHi=0x00.
  • Level range 0x8000..0x7FFF = -327.68..327.67 dB (signed short).
  • Time range 0x0000..0x2000 ms.
  • Source recommends 32bit commands (0x01F5 and 0x112D) for 52/XS/XC/XD and 52/XS2/XC2/XD2 devices.
  • Controller availability: RM420-850 has 1 RS-232 + RS-422 on controller and 1-3 RS-232 on each RM420-851; RM420-852 adds RS-422; RM420-853 only RS-422 on B-variants. TCP max 10 sockets (5 sockets on fw <= 7.04.06; 4 sockets on RM420-850 fw 05.05.27..05.06.01).

<!-- UNRESOLVED: RS-232 vs RS-422 pin assignment and electrical specs not stated in source; refer to module documentation. -->

## Provenance

```yaml
source_domains:
  - developer.dhd.audio
  - dhd.audio
source_urls:
  - https://developer.dhd.audio/docs/API/ECP/
  - https://developer.dhd.audio/docs/API/ECP/commands
  - https://developer.dhd.audio/docs/API/ECP/communication
  - https://dhd.audio/home/rm-4200d/
  - https://developer.dhd.audio/
retrieved_at: 2026-08-17T18:06:10.139Z
last_checked_at: 2026-08-19T09:15:10.927Z

Verification Summary

verdict: verified
checked_at: 2026-08-19T09:15:10.927Z
matched_actions: 38
action_count: 38
confidence: medium
summary: "All 38 spec actions map to documented ECP commands/opcodes; transport (38400 8N1, TCP 2008) verbatim in source. (2 unresolved item(s) noted in Known Gaps.)"

Known Gaps

- "ECP applies across many firmware versions with feature differences; per-command firmware-version gating is captured in Notes rather than per-action."
- "RS-232 vs RS-422 pin assignment and electrical specs not stated in source; refer to module documentation."

From the AI4AV catalog (https://ai4av.net) · ODbL-1.0