Make RSSI depend on tuning instead of being a constant

The S-meter had a number to draw, but a fixed RSSI above squelch meant the band was
uniformly and permanently occupied. Scanning, squelch, and every "is this channel busy"
decision therefore faced a situation that never varied, so none of that logic was
really being tested -- the tests passed without testing much.

RSSI is now derived from where the firmware tuned. BK4819_SetFrequency splits the
frequency across REG_38 and REG_39 (driver/bk4819.c:743), which the model already
records; verified against a live guest that 0x0262/0x5A00 reads back as 400.00000 MHz,
matching the screen. A small table of virtual stations plus a noise floor and a fade
either side of centre gives a band with signals in some places and not others.

Measured through the firmware's own tuning path -- typing 410.000 on the keypad rather
than poking the registers, so the test does not check the model against itself:

    400.000 MHz (station)  RSSI 0x01E5
    410.000 MHz (empty)    RSSI 0x0091      a gap of 85 dB

What is honest and what is not, recorded in the code: the shape is real physics, power
falls off away from a carrier with a noise floor underneath. The station list is
invented. So this reproduces "the firmware copes with a band that is busy in places",
which is genuine coverage, and it reproduces no actual radio environment -- a dBm figure
from here is not a claim about the world.

Also records why backlight PWM is deliberately left stubbed. Intermediate brightness
runs TIM7 -> DMA rewriting GPIOA BSRR at 128 kHz, so modelling it costs 128,000 GPIO
writes per emulated second and changes nothing observable: backlight is LED brightness
and never touches the framebuffer. The two endpoints that are observable, off and full,
bypass the timer and already work.

Full run: 16 passed, 0 failed.
This commit is contained in:
mckero committed 2026-08-29 08:52:52 +01:00
1 parent fdcbe80056
commit 8b995aa610
5 files changed
+288 -10

No files matched your search

+4 -1
View File
@@ -42,7 +42,8 @@ has no public datasheet, so its driver is the only specification available.
| Serial output (firmware log) | works, appears in the web UI log |
| Serial input, CPS programming protocol | works, `-serial` any chardev |
| BK4819 register interface | works, RSSI and status readable |
| S-meter | works via monitor (SIDE1); reads -53 dBm, S9+40 |
| S-meter | works via monitor (SIDE1) |
| Signal strength | depends on tuning: virtual stations vs noise floor |
| PTT and transmit | works; TX annunciator, timer, and mic level bar |
| Speaker / microphone audio | **no samples exist to model**, see [Audio](#audio) |
| `millis()` / TIM2 | works; advances at roughly wall-clock rate |
@@ -91,6 +92,7 @@ keypresses silently stop working. Run the test after touching that code;
test_audio_path.py the amplifier turns on when the firmware wants sound
test_battery.py battery level and low-battery follow the ADC
test_millis.py millis() advances, so timeouts can expire
test_spectrum.py RSSI depends on tuning, not a constant
run_tests.sh runs all of the above, build-checked first
test_run_tests.sh that the runner actually notices failures
lib_kill_emulator.sh cleanup that only ever kills emulators
@@ -151,6 +153,7 @@ that was never compiled. Individual tests still run standalone:
python3 tools/test_audio_path.py
python3 tools/test_battery.py
python3 tools/test_millis.py
python3 tools/test_spectrum.py
This matters more than it looks. The keypad can break silently under -O2 without
any compiler warning -- see the `volatile` note in [Status](#status) -- so a clean