Qwen3.8 Flash reads the receive path well. It finds that the monitor inherits HR-C6000 de-emphasis and the AT1846S voice filters, and proposes exactly the right first change, 0x34=0x1C, which clears de-emphasis and nothing else. In the firmware-in-the-loop model de-emphasis alone leaves 0 of 180 frames. It also argues from the driver’s own bit meanings that the monitor’s 0xE0=0xC9 switches the microphone on, and it finds the capture bug along with the reason the tests missed it.
Its architecture claims are weaker. It calls the CPU-side chain “not the problem”, though mbelib needs 11–16 times the 72 MHz CPU. It puts DMR at “9600 Bd”, twice the real rate, and uses that to rule out the chip’s one-layer mode, and it builds Phase 2 from DMR’s BPTC code, Motorola’s X2-TDMA and IMBE voice. 21 of 33 claims hold and 6 are wrong, the most of any clean-room audit. That puts it at D.
Claims that check out
21 / 33
6 overstated, mislabelled or doubtful · 6 wrong
Decode-critical issues found
2 of 4
misses the 8 kHz rule; clears the vocoder
Frames left by de-emphasis
0 of 180
the stage its 0x34=0x1C would switch off
CPU the vocoder needs
11–16×
of 72 MHz; it calls the chain “not the problem”
ConditionsClean room: a fresh copy of the repository (46eebda with its uncommitted changes, its own docs and the HR-C6000 manual) with no earlier reviews, reviewed by one model through an isolated agent harness with no network, skills or memory.
The run, not graded57 min · 92 agent steps · 97 tool calls · 147K output tokens · OpenRouter API · one-shotSecond attempt; the first stopped on a provider rate limit.
Read the full review audit
Every claim, every rerun and the modelling behind this grade, as published.
Weights reflect the question asked: find what stops P25 decoding and say how to fix it. Accuracy carries the most weight because a wrong review does harm; coverage and root cause together outweigh it because an accurate review of the wrong things does not help.
Where the points went
The 100-point grade split into the rubric’s weighted slots: filled is earned, empty is lost, with the other models on this task for scale.
1Accuracy2Coverage3Root cause4Fix plan56
UNIONALPHA
74/ 100
Grok 4.6
70/ 100
Muse Spark 1.3 Contributor
68/ 100
DeepSeek V4.1 Flash
66/ 100
Qwen3.8 Flash
59/ 100
GLM 5.3 Flash
56/ 100
1Accuracy & evidence30 pts
2Coverage of decode problems25 pts
3Root cause & prioritisation15 pts
4Fix plan & acceptance gates15 pts
5Originality & attribution10 pts
6Clarity & calibration5 pts
Accuracy & evidence30% of the grade
6218.6 pts
21 of 33 claims hold, including every receive-path register and line it cites. Six are wrong and two steer the plan: the CPU-side chain “is not the problem”, and DMR runs at “9600 Bd”, which rules out the chip’s one-layer mode; its Phase 2 stack borrows DMR and X2-TDMA parts.
Coverage of decode problems25% of the grade
4010.0 pts
Finds both halves of the filter chain with the exact fix, the microphone evidence, the capture bug, the dead starvation counter and the discriminator tap. It misses the 8 kHz rule, the vocoder CPU wall, 72 MHz, the oracle, the parser, capture epochs and the gate/clamp mismatch, and dismisses one-layer mode on a wrong baud rate.
Root cause & prioritisation15% of the grade
6810.2 pts
Puts the unverified source, the voice filters and the microphone bit first and designs one session that separates them, but calls the CPU-side chain “not the problem” and the capture path “the only thing” blocking voice.
Fix plan & acceptance gates15% of the grade
7010.5 pts
Small, ordered, test-first steps with one decisive hardware session (a 0xE0 × 0x34 matrix that includes the right 0x1C), a tap fallback and codec ownership. No vocoder work or independent oracle, and it would keep fail-closed muting and add a 48 kHz clock the manual rules out.
Originality & attribution10% of the grade
646.4 pts
Adds why the capture bug survived testing (the tests drive the module, not the p25mon.c adapter), the exact one-bit de-emphasis change, and unmasked PTT and APRS microphone writes, and credits the repository’s notes. Much of the rest restates the stock report and bring-up log.
Clarity & calibration5% of the grade
703.5 pts
A clear bottom line, severity-labelled findings with resolutions and an honest list of what it didn’t verify, undercut by confident errors: “neither P25 phase can be demodulated by the C6000”, “not the problem”, and a Phase 2 stack stated as fact.
Weighted total 59, grade D. Grade scale: A ≥ 90 · B 80–89 · C+ 75–79 · C 70–74 · C− 65–69 · D 50–64 · F < 50
Headline findings
Six things to know about this review
Holds up
It finds the front-end fix, down to the bit
The monitor never writes HR-C6000 register 0x34, so it inherits 0x3C from the FM setup: de-emphasis on, −6 dB per octave from 300 Hz. Qwen3.8 Flash explains why that breaks the 4-level eye and proposes 0x34=0x1C, which clears de-emphasis and keeps the 3 kHz filter, plus the AT1846S DMR filter setting as the first probe. In the firmware-in-the-loop model, de-emphasis alone leaves 0 of 180 frames, and the 3 kHz filter it keeps costs none.
It makes the microphone the default and designs the test
HRC6000SetMic() toggles bit 6 of 0xE0, and the monitor pins 0xE0=0xC9 with that bit set, while the stock FM setup writes 0x89, “Turn off Microphone input”. It calls the microphone hypothesis well founded and says it must be retired with data first. Its one scripted hardware session crosses 0xE0 against 0x34 with read-back checks, and it falls back to the M17 discriminator tap if RF isn’t there.
The decoder reads the left channel, [j][i*2], but the capture exports the first 80 interleaved words of each row, so half the left samples never leave the radio. The capture tests feed p25monCaptureSamples() clean mono arrays, so they check the module and never the adapter in p25mon.c that has the bug. It also finds that PTT isn’t masked during monitoring and that APRS writes the microphone bit behind the monitor’s back.
“The CPU-side P25 Phase 1 decode chain … is not the problem”, and the capture path is “the only thing that actually blocks Phase 1 voice”. Emulated instruction counts put mbelib’s IMBE synthesis at 11–16 times the radio’s 72 MHz CPU: one voiced 20 ms frame takes 134–458 ms, so the decoder falls behind on every voiced frame, whatever the front end does. The review never looks at CPU time or mentions the 72 MHz clock.
QWEN38FLASH_REVIEW.md bottom line · mbelib.c:306 · Core/Src/main.c:269–274
Critical error
It rules out the chip’s modem at the wrong baud rate
“DMR is 9600 Bd 4FSK (19.2 kbps)”, so, it argues, the HR-C6000’s modem samples P25 at a 2:1 mismatch and can serve neither phase. DMR is 4FSK at 4,800 symbols per second, 9.6 kbps, the same symbol rate as P25 Phase 1, and the manual lists 9.6 kbps. The one-layer test mode it dismisses stores 36 bytes every 30 ms, exactly 4,800 symbols per second. Whether it needs DMR sync is an open question worth a test, not a closed door.
QWEN38FLASH_REVIEW.md §1 · manual 36, 2553–2635
Wrong
Its Phase 2 stack comes from other protocols
It gets the scope right: 6,000 symbols per second, the 20-symbol sync, 30 ms slots, and not enough memory. But it builds the stack from DMR’s BPTC(196,96) code, Motorola’s X2-TDMA decoder (x2tdma_voice.c) and IMBE voice. Phase 2 voice is AMBE+2 half-rate, and the DSD-FME Phase 2 sources use no BPTC. It also calls P25 group IDs 24-bit (they are 16), counts the linker’s 1,536-byte heap and stack reservation as headroom, and misses the manual’s 8 kHz frame-clock rule in the very sentence it quotes.
The audits track 4 issues that stop this radio decoding P25. This review: misses the 8 kHz rule; clears the vocoder. How the review treated each, from the provenance table: