Skip to content

Serial channel mode commands never applied the selected mode - #2

Open
xmutantson wants to merge 1 commit into
ARSFI:masterfrom
xmutantson:fix/serial-mode-dispatch-upstream
Open

Serial channel mode commands never applied the selected mode#2
xmutantson wants to merge 1 commit into
ARSFI:masterfrom
xmutantson:fix/serial-mode-dispatch-upstream

Conversation

@xmutantson

Copy link
Copy Markdown

The defect

Selecting a channel profile over the USB serial port (WGN:, MPG:, MPM:, MPP:,
MPD:) answers OK but does not change the running channel profile. Only the target
S:N number is updated; the simulator keeps whichever profile the front-panel encoder
last selected (or WGN after power-on).

Cause: ParseSetSimParameter(String strParameter, int intMode) takes a parameter named
intMode, which shadows the global intMode. For modes 0-4 it validates the request
and sets intTargetSN, but the global mode index is never assigned. The follow-up call
ParseSetParameter(strParameter, intSerialCmdMode) has the same parameter shadowing,
so it updates the display text and S:N only. The main loop configures the IQ tap delays
and the Doppler update cadence from the unchanged global intMode, so the physical
signal path never switches. Both firmware variants (src/HFSim_BFD_2_03 and
hardware/Alternate hardware platforms/.../HFSim_BFD_2_03_Proto) have the same
dispatch code and the same defect.

How it was found

Driving the simulator from a Raspberry Pi over USB serial for automated modem testing:

  • After a commanded WGN:40, the received tone showed slow amplitude fading and
    measured about 18.5 dB SNR in a setup that had previously measured about 43 dB on a
    genuinely clean WGN channel — the profile was still a multipath/fading mode from
    earlier front-panel use.
  • After commanded MPP:9, independent SNR estimators disagreed by ~12 dB because the
    channel was not actually in the commanded profile.
  • The TFT display showed the commanded mode name while the output audibly kept the old
    profile, which is what pointed at the dispatch rather than the signal path.

The fix

In the successful serial dispatch, assign the global mode and clear blnInitialized
before applying the parameter update:

if (intSerialCmdMode < 5)
  {
    intMode = intSerialCmdMode;
    blnInitialized = false;
    ParseSetParameter(strParameter, intSerialCmdMode);
  }

Clearing blnInitialized makes the next loop() pass run the exact mode-entry
initialization a front-panel mode change runs (tap delays, path mixer gains, display),
and the Doppler update cadence follows the global intMode from then on. The target
S:N set by the command is preserved. Front-panel behavior, EEPROM handling, and the
BUSY-mode command path are untouched. Applied identically to both firmware variants.

tests/test_serial_mode_dispatch.py (plain python -m unittest tests.test_serial_mode_dispatch) guards the dispatch block of both sources: it fails
on the previous code and passes with the fix.

Validation on hardware

Flashed the fixed firmware to the Teensy 4.0 unit on the same Raspberry Pi bench and
re-ran the failing sequence:

  • Commanded WGN:40: measured 43.9 dB SNR with a flat envelope (std 0.003 dB, Doppler-band
    energy fraction 0.0005) — the clean channel is actually delivered. Before the fix the same
    command measured 18.5 dB with visible slow fading.
  • Commanded MPP:9: fading now genuinely present — envelope std 5.3 dB, p95-p05 spread
    17.5 dB, Doppler-band energy fraction 0.79, and the serial debug echo
    Line 1014 SetIQTapDelays: intMode = 3 confirms the global mode assignment on dispatch.
  • Commanded WGN:40 again: 44.2 dB, flat — live re-switching works in both directions
    without a power cycle.
  • The two independent SNR estimators that disagreed by ~38 dB on a commanded-clean channel
    before the fix now agree within 0.13 dB on it.
  • Power-cycle behavior unchanged: after RESET the unit boots to WGN as before (modes are
    deliberately not persisted), with the same banner and serial number.

Serial channel-profile commands (WGN/MPG/MPM/MPP/MPD) validated the
requested mode and updated the target S:N, but never assigned the
global intMode: ParseSetSimParameter's intMode parameter shadows the
global of the same name, so an acknowledged command left the running
channel profile unchanged. The main loop keeps configuring tap delays
and Doppler updates from the stale global, so for example MPP:9
answered OK while the simulator stayed in whichever mode the
front-panel encoder had last selected. ParseSetParameter's parameter
shadows the global the same way, so nothing on the serial path ever
wrote it.

Assign the global mode and clear blnInitialized in the serial dispatch
before applying the parameter update, so the next loop pass configures
the selected profile through the same initialization path a
front-panel mode change uses. Applied to both firmware variants, with
a regression test over both sources.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant