fix(hf): tune() must send START/MEASURE/STOP mode byte and parse uint16
CMD_MEASURE_ANTENNA_TUNING_HF requires a 1-byte mode arg (firmware rejects length!=1 with EINVARG) and returns the voltage as uint16, not uint32. tune() sent no arg (empty reply -> 0 mV) and parsed <I. Now sends mode 1/2/3 (START/MEASURE/STOP) and parses <H. Verified vs firmware appmain.c handler; C client reads the same ~15V on this firmware. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -16,9 +16,17 @@ class HFCommands:
|
|||||||
self.mfc = None # type: ignore
|
self.mfc = None # type: ignore
|
||||||
|
|
||||||
async def tune(self, on_progress: ProgressCallback = None) -> dict:
|
async def tune(self, on_progress: ProgressCallback = None) -> dict:
|
||||||
"""Measure HF antenna voltage."""
|
"""Measure HF antenna voltage.
|
||||||
resp = await self._t.send_ng(Cmd.MEASURE_ANTENNA_TUNING_HF, timeout=10.0)
|
|
||||||
voltage = struct.unpack_from("<I", resp.data, 0)[0] if len(resp.data) >= 4 else 0
|
CMD_MEASURE_ANTENNA_TUNING_HF is a START/MEASURE/STOP state machine that
|
||||||
|
requires a 1-byte mode arg (firmware rejects length!=1 with EINVARG):
|
||||||
|
mode 1 = START (spins up the HF FPGA), mode 2 = MEASURE (returns uint16 mV),
|
||||||
|
mode 3 = STOP. Voltage is a uint16_t, not uint32_t.
|
||||||
|
"""
|
||||||
|
await self._t.send_ng(Cmd.MEASURE_ANTENNA_TUNING_HF, bytes([1]), timeout=10.0) # START
|
||||||
|
resp = await self._t.send_ng(Cmd.MEASURE_ANTENNA_TUNING_HF, bytes([2]), timeout=10.0) # MEASURE
|
||||||
|
voltage = struct.unpack_from("<H", resp.data, 0)[0] if len(resp.data) >= 2 else 0
|
||||||
|
await self._t.send_ng(Cmd.MEASURE_ANTENNA_TUNING_HF, bytes([3]), timeout=10.0) # STOP
|
||||||
result = {
|
result = {
|
||||||
"voltage_mV": voltage,
|
"voltage_mV": voltage,
|
||||||
"voltage_V": round(voltage / 1000.0, 3),
|
"voltage_V": round(voltage / 1000.0, 3),
|
||||||
|
|||||||
@@ -7,7 +7,12 @@ from pm3py.core.hf import HFCommands
|
|||||||
def test_hf_tune():
|
def test_hf_tune():
|
||||||
t = AsyncMock()
|
t = AsyncMock()
|
||||||
hf = HFCommands(t)
|
hf = HFCommands(t)
|
||||||
|
# MEASURE (mode 2) returns the voltage as a uint16 mV; 15485 mV = 0x3C7D
|
||||||
t.send_ng.return_value = PM3Response(cmd=Cmd.MEASURE_ANTENNA_TUNING_HF, status=0,
|
t.send_ng.return_value = PM3Response(cmd=Cmd.MEASURE_ANTENNA_TUNING_HF, status=0,
|
||||||
reason=0, ng=True, data=b"\x00" * 4)
|
reason=0, ng=True, data=b"\x7d\x3c")
|
||||||
result = asyncio.get_event_loop().run_until_complete(hf.tune())
|
result = asyncio.get_event_loop().run_until_complete(hf.tune())
|
||||||
assert "voltage_mV" in result
|
assert result["voltage_mV"] == 15485
|
||||||
|
assert result["voltage_V"] == 15.485
|
||||||
|
# Firmware requires the START(1)/MEASURE(2)/STOP(3) mode-byte sequence
|
||||||
|
modes = [call.args[1] for call in t.send_ng.call_args_list]
|
||||||
|
assert modes == [bytes([1]), bytes([2]), bytes([3])]
|
||||||
|
|||||||
Reference in New Issue
Block a user