Skip to content

IC-7300 (Icom) — CI-V manual vs implementation

Manual: Icom IC-7300 Advanced Manual (11a), §19 CONTROL COMMAND. The command table on printed pp.19-3/19-4 is the source for the APF ruling below: its 0x16 rows run through 22, continue at 40, and later continue from 4F; it has no 32 row or Audio Peak Filter entry. Driver: shared Icom CI-V core — src/rigplane/backends/ic7300/{serial,core}.py are 22-line shims over backends/_icom_serial_base._IcomSerialRadioBase + runtime/radio.CoreRadio (185 get_/set_) + _scope_runtime mixin (26) + _dual_rx_runtime (3). Zero IC-7300-specific command code — every method is shared with IC-7610 / IC-705 / IC-9700 / X6200 and routed by rigs/ic7300.toml. Profile: rigs/ic7300.toml. Validation: src/rigplane/validation/registry/* (capability-gated template; see _builders.py). Live evidence: an APF-specific read-only run on the remote testbed sent 16 32 GET twice and received protocol NAK (FA) both times. The adjacent documented 16 22 GET returned DATA before and after. No SET or TX command was sent. This was not a full validation-matrix run; other "Validation" entries below still describe declarations rather than observed pass/fail.

Derived command-domain census: the dated MOR-2188 normalization below and its 149-row CSV ledger are static design evidence pinned to source 8cc5471dbb60f246ccb7a17a5e29f75fd6f20a00; they are not the runtime source of truth, a current-profile inventory, hardware acceptance, or approval to add commands in bulk.

Protocol: Icom CI-V, FE FE 94 E0 … FD, transceiver address 0x94. Default baud 115200 (required for serial scope data).

IC-7300 vs IC-7610 divergence (7300-specific)

  • Single receiver — no dual-watch, no MAIN/SUB band select, no 0x29 (cmd29). Scope is 27 12=Main-only, 27 13=Single-only.
  • Single antenna + ATU, no antenna-select command — no 0x12 row in the IC-7300 Advanced Manual (11a) command table pp.19-3..19-8, no ANT1/ANT2 selection documented; bench 2026-09-01 NAK'd 12 00/12/12 01, with 03 answering DATA before and after (get_antenna/set_antenna declared absent). No RX antenna, no ANT1/ANT2 (profile has_rx_ant=false, tx_count=1).
  • No APF — Advanced Manual (11a) pp.19-3/19-4 omit 16 32, and the read-only remote-testbed probe NAK'd an exactly framed 16 32 GET twice while adjacent 16 22 returned DATA. The IC-7300 support contract must not declare an apf capability, domain, acquisition field, or get_/set_audio_peak_filter command.
  • 2 preamp levels (16 02: 0/1/2), no DIGI-SEL, no drive_gain, single DATA sub-mode.

Command matrix (operator-facing)

Legend — Backend: method name or . Profile: [commands] key or cap. Validation: check_id + declaration (RMVR=round-trip / PRESENCE=synthetic .presence only / MANUAL/TX-ADJ / READ / =none).

CI-V cmd Documented S/R Backend method Profile cap / cmd Validation
03 / 05 freq read/set get_freq/set_freq get_freq/set_freq freq.write RMVR (structural)
04 / 06 mode read/set get_mode/set_mode get_mode/set_mode mode.set RMVR (structural)
02 band-edge freqs get_band_edge_freq band_edge
25 / 26 sel/unsel VFO freq+mode get_selected_freq get_selected_* (structural reads)
07 VFO A/B, swap, equalize get_vfo/set_vfo get_vfo/set_vfo, vfo scheme ab (via VFO scheme)
0F split read/set set_split/get_split get_split/set_split split.set RMVR
10 tuning step get_/set_tuning_step tuning_step — (declared, presence only)
11 attenuator 0/20dB get_/set_attenuator attenuator attenuator.set RMVR
14 01 AF level get_/set_af_level af_level af_level.set RMVR
14 02 RF gain get_/set_rf_gain rf_gain rf_gain.set RMVR
14 03 squelch get_/set_squelch squelch squelch.set RMVR
14 06 NR level get_/set_nr_level nr (covered by nr.set)
14 07/08 TWIN PBT inner/outer get_/set_pbt_inner/_outer pbt pbt.presence
14 09 CW pitch get_/set_cw_pitch cw — (cw check = key_speed only)
14 0A RF power get_/set_rf_power power_control power_control.presence
14 0B MIC gain get_/set_mic_gain power_control power_control.presence
14 0C KEY SPEED get_/set_key_speed cw key_speed.set RMVR
14 0D NOTCH position get_/set_notch_filter notch (covered by notch.set)
14 0E COMP level get_/set_compressor_level compressor compressor.presence
14 0F break-in delay get_/set_break_in_delay break_in break_in.presence
14 12 NB level get_/set_nb_level nb (covered by nb.set)
14 15 monitor gain get_/set_monitor_gain monitor monitor.presence
14 16 VOX gain get_/set_vox_gain vox vox_gain.set TX-ADJ
14 17 anti-VOX gain get_/set_anti_vox_gain vox
15 02 S-meter get_s_meter meters meters.read READ
15 11/12/13/14/15/16 PO/SWR/ALC/COMP/Vd/Id meters get_power_meterget_id_meter meters (covered by meters.read)
16 02 preamp 0/1/2 get_/set_preamp preamp preamp.set RMVR
16 12 AGC FAST/MID/SLOW get_/set_agc agc agc.set RMVR
16 22 NB on/off get_/set_nb nb nb.set RMVR
16 40 NR on/off get_/set_nr nr nr.set RMVR
16 41 auto-notch get_/set_auto_notch notch (covered by notch.set)
16 42 repeater tone get_/set_repeater_tone repeater_tone repeater_tone.set RMVR
16 43 tone squelch get_/set_repeater_tsql tsql tsql.set RMVR
16 44 compressor on/off get_/set_compressor compressor compressor.presence
16 45 monitor on/off get_/set_monitor monitor monitor.presence
16 46 VOX on/off get_/set_vox vox vox.read READ + vox.set PRESENCE
16 47 BK-IN OFF/SEMI/FULL get_/set_break_in break_in break_in.presence
16 48 manual notch on/off get_/set_manual_notch notch notch.set RMVR
16 4F Twin Peak Filter get_/set_twin_peak_filter twin_peak twin_peak.presence
16 50 dial lock get_/set_dial_lock dial_lock dial_lock.set RMVR
16 56 DSP filter type get_/set_filter_shape filter_shape filter_shape.presence
16 57 manual notch width get_/set_manual_notch_width notch (covered by notch.set)
16 58 SSB TX bandwidth get_/set_ssb_tx_bandwidth ssb_tx_bw ssb_tx_bw.presence
16 32 Not documented; live GET NAK twice generic shared-Icom methods remain for radios that support APF unsupported for IC-7300
16 65 IP+ get_/set_ip_plus ip_plus ip_plus.presence
17 send/stop CW msg send_cw/stop_cw send_cw/stop_cw — (feature)
18 power on/off get_/set_powerstat power_control power_control.presence
19 00 transceiver ID get_transceiver_id get_transceiver_id discovery.identify (structural)
1A 01 band-stack register set_bsr (get_bsr NIE) bsr bsr.select MANUAL (set-only)
1A 03 filter width (BCD idx) get_/set_filter_width filter_width filter_width.set RMVR
1A 04 AGC time constant get_/set_agc_time_constant agc (covered by agc.set)
1A 05 … EQ (RX/TX bass/treble, HPF/LPF) get_/set_*_rx_bass [commands.overrides] system_settings
1A 05 0064/0065 ACC/USB MOD level get_/set_acc1_mod_level, _usb_mod_level mod cmds — (audio path)
1A 05 0066/0067 MOD input (DATA OFF / DATA) get_/set_data_off_mod_input, _data1_mod_input data inputs — (audio path)
1A 05 0071 CI-V transceive get_/set_civ_transceive civ cmds
1A 05 0073 CI-V output (for ANT) get_/set_civ_output_ant civ cmds
1A 05 0094/0095/0096 date / time / UTC offset get_/set_system_date/_time/_utc_offset system cmds system_date.read/system_time.read READ
1A 05 0189/0190 NB depth / width get_/set_nb_depth/_width nb cmds — (covered loosely by nb.set)
1A 05 0191/0192 VOX delay / voice delay get_/set_vox_delay vox cmds
1A 06 DATA mode get_/set_data_mode data_mode data_mode.presence
1B 00/01 repeater-tone freq / TSQL freq get_/set_tone_freq/_tsql_freq tone cmds tone_freq.set / tsql_freq.set RMVR
1C 00 PTT TX/RX set_ptt ptt_on/ptt_off tx.ptt TX-ADJ
1C 01 antenna tuner OFF/ON/tune get_/set_tuner_status tuner tuner.tune TX-ADJ
1C 02 TX freq monitor (XFC) get_/set_xfc_status xfc xfc.presence
1C 03 read TX freq; no SET documented generic shared-Icom methods remain get_/set_tx_freq_monitor explicitly absent/fail-closed for IC-7300 (PR #2981)
21 00 RIT freq get_/set_rit_frequency rit rit.set RMVR
21 01 RIT on/off get_/set_rit_status rit (covered by rit.set)
21 02 ∂TX (XIT) on/off get_/set_rit_tx_status xit xit.set RMVR
27 00 scope waveform data get_/set_scope_wave scope cmds (audio/scope surface)
27 10/11 scope on/off, data output scope_on/scope_data_output scope cmds scope.capture MANUAL
27 14 center/fixed mode get_/set_scope_mode scope cmds scope_mode.set RMVR
27 15 span get_/set_scope_span scope cmds scope_span.set RMVR
27 16 edge number get_/set_scope_edge scope cmds scope_edge.set RMVR
27 17 hold get_/set_scope_hold scope cmds scope_hold.set RMVR
27 19 reference level get_/set_scope_ref scope cmds scope_ref.set RMVR
27 1A sweep speed get_/set_scope_speed scope cmds scope_speed.set RMVR
27 1B scope-during-TX get_/set_scope_during_tx scope cmds scope_during_tx.set RMVR
27 1C center type get_/set_scope_center_type scope cmds scope_center_type.set RMVR
27 1D VBW get_/set_scope_vbw scope cmds scope_vbw.set RMVR
27 1E fixed-edge freqs get_/set_scope_fixed_edge scope cmds scope_fixed_edge.read READ
27 1F RBW get_/set_scope_rbw absent (MOR-2105: no row in the manual's 0x27 sub-command table) scope cmds scope_rbw.set UNSUPPORTED
27 12/13 main/sub, single/dual get_scope_single_dual scope cmds scope_dual.set/scope_receiver.set (no-op on 7300, single-RX)
0E scan start/stop scan_start/scan_stop scan scan.presence
13 speech synthesizer get_speech set_speech — (device front-panel)

Intentionally OUT OF SCOPE (device front panel / menu — nothing to mirror into browser UI)

  • 08/09/0A/0B + 1A 00/1A 02 memory & memory-keyer family — memory ops, feature, not an operator real-time control.
  • 1A 05 0021…0197 settings-menu mass (beep, screen capture, fonts, RTTY decode, QSO recorder, contest number, keyboard layout, screen saver, colors, waterfall styling) — device settings menu (hundreds of params); only the audio-path (mod level/input), clock, NB depth/width, VOX delay, and per-band scope edges are surfaced.
  • 1E user-set TX band edges · 1A 05 0072 CI-V address · 0081 LCD backlight — config, not operating controls.
  • 28 00 Voice TX memory — voice keyer (feature, same class as CW keyer).

Gap lists (priority-ordered)

A. UNDER-DECLARED — backend implements, profile/registry can't see it

CI-V rigplane symbol Fix Ticket
1B 00/01 repeater-tone freq + TSQL freq get_/set_tone_freq, get_/set_tsql_freq exist + tone_freq/tsql_freq registry checks RMVR — but they are gated on capability="repeater_tone"/"tsql"; the 7300 declares both, so they DO run. No gap (listed to confirm parity with FTX-1 audit). none
14 16/17 VOX gain + anti-VOX get_/set_vox_gain (REAL), get_/set_anti_vox_gain (REAL) — backend + profile present, but only vox_gain.set is checked (TX-adjacent, manual); anti-VOX has no check_id Add anti_vox_gain.set RMVR (or fold under vox) NEW
1A 05 0191/0192 VOX delay / voice delay get_/set_vox_delay (REAL) + get_vox_delay/set_vox_delay cmd strings present — no registry check at all Add vox_delay.set RMVR NEW
1A 05 0189/0190 NB depth / width get_/set_nb_depth/_width (REAL) + cmd strings present — no dedicated check (only generic nb.set toggle) Add nb_depth.set RMVR NEW

B. VALIDATION GAPS — implemented + declared, but no round-trip (synthetic .presence only)

Per _builders.py, a declared capability with no registry CheckSpec gets only a synthetic <cap>.presence entry at UNSUPPORTED_PENDING_EVIDENCE. These 7300 features have a REAL backend method + profile declaration but no functional check — so the matrix can never go green for them:

Capability CI-V Backend (REAL) Fix Ticket
pbt 14 07/08 get_/set_pbt_inner/_outer Add pbt.set RMVR (raw 0/128/255) NEW
compressor (+level) 16 44 / 14 0E get_/set_compressor(+_level) Add compressor.set RMVR NEW
monitor (+gain) 16 45 / 14 15 get_/set_monitor(+_gain) Add monitor.set RMVR NEW
break_in (+delay) 16 47 / 14 0F get_/set_break_in(+_delay) Add break_in.set RMVR NEW
twin_peak 16 4F get_/set_twin_peak_filter Add twin_peak.set RMVR NEW
ip_plus 16 65 get_/set_ip_plus Add ip_plus.set RMVR NEW
filter_shape 16 56 get_/set_filter_shape Add filter_shape.set RMVR (SHARP/SOFT) NEW
ssb_tx_bw 16 58 get_/set_ssb_tx_bandwidth Add ssb_tx_bw.set RMVR NEW
data_mode 1A 06 get_/set_data_mode Add data_mode.set RMVR NEW
tuning_step 10 get_/set_tuning_step Add tuning_step.set RMVR NEW
xfc 1C 02 get_/set_xfc_status Add xfc.set RMVR NEW
power_control (rf_power/mic_gain) 14 0A/0B, 18 get_/set_rf_power/_mic_gain/powerstat Split rf_power.set+mic_gain.set RMVR NEW
cw_pitch (under cw) 14 09 get_/set_cw_pitch Add cw_pitch.set RMVR (cw check currently = key_speed only) NEW

All RMVR-able level/toggle controls above are shared with IC-7610; one registry CheckSpec per capability fixes every Icom rig at once (_levels.py/_dsp.py/_tx.py).

C. MISSING BACKEND — documented operator command, no backend method

CI-V Function Value Ticket
1A 01 (read) band-stack register get_bsr raises NotImplementedError for all Icom — only set_bsr works; bsr.select is set-only/manual Med — implement BSR read (firmware DOES answer 1A 01); the NIE is a stale IC-7610-era assumption NEW
1A 05 0030 quick split no get_quick_split/set_quick_split method (profile has the cmd string get_/set_quick_split, no backend async def) Low — operating convenience NEW
0E A1–A7 ∂F scan span / select-scan variants scan_set_df_span/scan_set_resume exist; the select-memory-scan + ∂F-span enumerations are not surfaced Low — feature (scan family)
1A 02 / 17 memory & CW message keyer memory ops + CW keyer text Feature (out of scope, see above)

D. MISMATCH / WRONG — declared/checked but behaves differently

CI-V rigplane symbol Issue Ticket
14 05 / 16 32 APF shared APF methods Advanced Manual (11a) documents neither IC-7610-style 14 05 APF position nor 16 32 APF mode for the IC-7300. Any IC-7300 apf capability/domain/acquisition/active-command declaration is therefore an unsupported profile over-declaration; generic shared methods remain valid for radios whose manuals declare APF. MOR-2144
1A 01 get_bsr band-stack read get_bsr raise NotImplementedError(...) cites "IC-7610 does not support reading band stack" — inherited verbatim by the 7300 even though the 7300 §19 table documents 1A 01 as Send/read. Driver-wide stale assumption (see list C). NEW

Summary

  • Only the APF ruling has live hardware evidence: two 16 32 GET NAKs with an adjacent 16 22 DATA positive control, read-only and without TX. No full IC-7300 validation-matrix run was performed.
  • The IC-7300 is 100% shared-backend with the IC-7610 — every gap in lists A/B is also an IC-7610/IC-705/IC-9700 gap; fixes are one CheckSpec per capability, rig-agnostic.
  • Biggest single lever: list B — ~13 declared+implemented capabilities (pbt, compressor, monitor, break_in, twin_peak, ip_plus, filter_shape, ssb_tx_bw, data_mode, tuning_step, xfc, power_control, cw_pitch) have a working backend method but only a synthetic .presence stub, so they can never validate green. Add functional _levels/_dsp/_tx CheckSpecs.
  • Real bugs: get_bsr NIE blocks 1A 01 read on hardware that supports it (lists C+D); IC-7300 APF is an unsupported profile over-declaration, not a missing validation check.

Derived missing-command normalization (MOR-2188; 2026-09-01 evidence)

This section refines the earlier broad settings-menu boundary into a normalized, one-record-per-raw-key design census. It does not change that boundary by itself: zero bulk additions are approved. Each future public operation still needs a bounded owner, contract review, tests, and any stated bench evidence. The CSV is the detailed ledger; this section records its reconciliation and the few controls that must remain visible in prose.

The MOR-2158 hold applied during the census and was released after MOR-2158 and MOR-2133 closed at main bf66038c8b0ac74020d9f985677542cc3aba167d (PR #2975 merge and post-merge PASS). That historical release is not standing ownership: every later implementation must re-read current ownership and re-anchor from fresh main.

Pinned provenance and ledger shape

  • Official IC-7300 Advanced Manual (11a) SHA-256: a73a9600899e1e900bc5fbb0ecbec33d1883f68b5ff54905a660013f5f00c66c.
  • Current rigs/ic7300.toml SHA-256 after PR #2981: e6a47d7521c87e5d3944bbe723099944ed2ec0c0048c4b24c32b0f6c67552393.
  • Parsed source ref: 8cc5471dbb60f246ccb7a17a5e29f75fd6f20a00. Its profile SHA-256 355cf05958e5f3537fe8680bfec38337e44e0f725cc11506ff8c76254c26a778 is a historical census input only, not current profile state.
  • Verified menu projections: mor2188-menu-normalization.md SHA-256 4156d15cea3ec9a92fc01fe3794ed052ce656da71168215f74933af6f1d18180 and mor2188-menu-normalization.json SHA-256 c8f1591440922fccf6d55f2d9151ef71b702230a04ff478aa1d4301e82d7348a.
  • Verified non-menu projections: mor2188-nonmenu-normalization.md SHA-256 4dd98aca4bd0ed581b915fd89e2b81749e28a8ff44017ca298419ed62bd5163b and mor2188-nonmenu-normalization.json SHA-256 d7c93c7178b8d7ef9fcc7604e75700734ee03e6022662e903024c59443e323b7. The CSV's provenance, direction, group, disposition, value-domain, coverage, confidence, dependency, and next-action fields for all 141 candidate keys are direct projections of these records. The 12 exceptional control rows retain the original audit ledger and are reconciled separately below.
  • Verified normalization inputs: 133 1A 05 menu keys in 40 groups plus 8 non-menu keys in 7 groups = 141 callable missing raw keys in 47 groups. Directions are 139 read-write and 2 read-only. Notifications 00 and 01 are inbound observations outside that callable denominator, producing the requested 143-key callable-plus-notification view.
  • The CSV deliberately remains a 149-row ledger: 137 candidate rows (three parameterized rows hold more than one raw key and therefore expand to the 141 normalized records), 3 wrong-semantic control rows, 7 already-represented generic-selector rows, and 2 notification rows. The exceptional controls are retained rather than deleted to make the source audit reconcilable.
  • The seven generic selector groups (07, 08, 0E, 0F, 10, 13, 18) already represent 40 manual extension rows. They remain collapsed; neither selector values nor the 52 already-declared scope-edge menu addresses become separate operations. Scope edges stay one scope_edge_configuration(band_segment, edge=1..4) composite, distinct from live 27 16 edge selection.

Per-key routing totals

The 141 callable keys reconcile exactly as follows. These are raw-key categories, not method, PR, or implementation-batch counts.

Disposition Menu Non-menu Total
Composite 45 0 45
Existing-family extension 26 0 26
Intentional no-public-operation 34 6 40
New domain/profile candidate 24 1 25
Unresolved 2 0 2
Wrong-semantic replacement route 2 1 3
Total 133 8 141

At group level, the 47 normalized groups default to 7 composite, 15 existing-family extension, 16 intentional no-public-operation, 8 new candidate, and 1 wrong-semantic route. Five exceptional menu keys override their group's default route, so group totals must not be added to the per-key table. The only unresolved addresses are 1A 05 0098 (the printed range includes undefined value 02) and 1A 05 0169 (the newline-code mapping is ambiguous).

Mandatory semantic controls

  • 1A 05 0040 is speech speed, not scope marker position. 1A 05 0058 is reference frequency with raw domain 0000..0255; the historical ref_adjust contract was bound and parsed at wrong address 0070 with an incompatible 0..511 domain. 1A 05 0070 is external-keypad RTTY Memory.
  • PR #2981 completed MOR-2190 by making all six names get/set_tx_freq_monitor, get/set_scope_marker_position, and get/set_ref_adjust explicit absent/fail-closed declarations for the IC-7300. They are negative control rows, not callable candidates, and there is no replacement API. Correct replacement-route records 0058, 0100, and 27 20 are already included in the 141 and are not double-counted. This negative slice made no bench claim and needed no bench validation.
  • 1A 05 0144 is structurally slot 3 of the 0142/0143/0144 30–45 MHz edge triplet and uses the p.19-9 edge-pair payload. The printed command row repeats the label “edge 2”; that manual-internal inconsistency is preserved, not silently corrected into claimed source text.
  • 1E 03 has a 12-byte envelope: edge_number(1) + lower_frequency(5) + separator_2D(1) + upper_frequency(5). The 00 immediately before 2D is the fixed high byte of the lower five-byte frequency. The existing 1E 01 parser consumes only the ten frequency bytes and cannot consume this envelope without explicit handling. 1E 02/03 remain intentional no-public-operation records.
  • 1A 05 0197 is read_write under the manual's 1A* family legend and is intentionally no-public-operation. Correcting its direction is audit truth, not permission to expose a write.

Smallest verified next batches

These are bounded recommendations, not code approval or a bulk plan. MOR-2190 is complete; every remaining positive slice must re-read current ownership and start from fresh main.

  1. display_brightness (14 19) one-key vertical slice: only after approval that panel brightness belongs in the public Radio contract and after its state/acquisition behavior is defined. Add fake serialization/parser coverage first, then a non-TX hardware get/set/read-back/restore.
  2. vox_voice_delay (1A 05 01 92) one-key existing-family extension: keep the off/short/mid/long voice-delay enum distinct from numeric hang delay 0191; use RX-only hardware read/write/read-back/restore with TX inhibited.
  3. B04 design first: group tx_delay_by_band (0026..0028) and tx_timeout (0029) into one parameterized TX-safety/settings domain. Dependencies are an explicit public-scope decision, typed per-band/timeout enums, a side-effect and restore contract, and separation from PTT authority. Implementation acceptance requires bounded hardware reads/writes/restores under TX inhibit; any on-air timing claim requires separate owner-present TX-safe validation.

Do not treat the completed negative slice as approval to restore reference or marker-position operations. Do not turn 1E 02/03, local UI/keyer/recorder settings, unresolved rows, selector values, or scope-edge addresses into bulk or per-selector methods.