Skip to content

TSR: FIRMWARE ERROR warnings fire for VOLTAGE/DRVSTAT/FANSPEED on legacy firmware #654

@ericweiner

Description

@ericweiner

Symptom

During TSR generation on a unit running legacy motor firmware (2024-09-10 in this bundle), the diagnostic-command WARNINGs surface to the user-visible log:

15:17:26.461 - serialboard.py - [XYZ Class ] FIRMWARE ERROR: VOLTAGE -> ERROR: command 'VOLTAGE' not found:
15:17:26.830 - serialboard.py - [XYZ Class ] FIRMWARE ERROR: DRVSTAT_X -> ERROR: command 'DRVSTAT_X' not found:
15:17:26.858 - serialboard.py - [XYZ Class ] FIRMWARE ERROR: DRVSTAT_Y -> ERROR: command 'DRVSTAT_Y' not found:
15:17:26.886 - serialboard.py - [XYZ Class ] FIRMWARE ERROR: DRVSTAT_Z -> ERROR: command 'DRVSTAT_Z' not found:
15:17:26.919 - serialboard.py - [XYZ Class ] FIRMWARE ERROR: DRVSTAT_T -> ERROR: command 'DRVSTAT_T' not found:
15:17:26.982 - serialboard.py - [XYZ Class ] FIRMWARE ERROR: FANSPEED -> ERROR: command 'FANSPEED' not found:
15:17:57.165 - serialboard.py - [XYZ Class ] FIRMWARE ERROR: VOLTAGE -> ERROR: command 'VOLTAGE' not found:

These are diagnostic commands added to motor firmware revisions after 2024-09-10. Legacy firmware (still in the field) doesn't have them. That is expected -- but the warnings should not surface as FIRMWARE ERROR because the driver already knows the firmware doesn't support them.

Why the warning fires

The driver layer has the right shape but the warning is emitted at the wrong layer:

  • drivers/motorboard.py:1421 _diagnostic_query() is firmware-version-tolerant: it calls exchange_command(...), catches resp.startswith('ERROR'), and returns None to the caller. Caller treats None as "INCONCLUSIVE -- firmware does not support this diagnostic."
  • BUT serialboard.py.exchange_command() logs FIRMWARE ERROR at WARNING level BEFORE returning, on any ERROR: response. So the _diagnostic_query swallow happens too late -- the warning has already surfaced.

Same shape as the recently-fixed motor_stop capability-probe warning (3f3553c), which added an expect_unsupported=False parameter to exchange_command and had motor_stop opt in. The diagnostic queries (VOLTAGE, DRVSTAT_<axis>, FANSPEED, FAN:<duty>) need the same opt-in.

Per Eric: the driver should be blocking these calls at the call site, not just swallowing the response after the warning fires. That can take two shapes:

  1. Same suppression as 3f3553c -- _diagnostic_query passes expect_unsupported=True so exchange_command logs at DEBUG instead of WARNING.
  2. Capability probe + gate (Rule 8 idiomatic) -- at startup, probe each diagnostic command once; record support in scope.capabilities (or MotorBoard._supports_diagnostics); subsequent callers gate on the flag and don't send unsupported commands at all. Combined with Testing Issue Reporting #1 for the initial probe.

Repro

Run TSR on any unit with motor firmware <= 2024-09-10 (e.g. SN12062 in tonight's bundle). The six warnings fire during TSR's diagnostic phase.

Disposition

Same shape as 3f3553c. Fix slots onto 4.0.0-wave7-decomp after Wave 7 Phase 2c lands. Not bench-blocking -- warnings are noise on legacy firmware, the diagnostic correctly returns None / inconclusive to the caller.

Bundle reference

LVP_Logbumped.wire.zip attached to issue #653. Warning lines visible in lumaviewpro_errors.log lines 281-286 (the 15:17:26 cluster) and around line 287 (the 15:17:57 retry).

Metadata

Metadata

Assignees

No one assigned

    Labels

    Fixed Needs verificationIssue originator close after verifying fix in the release.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions