Commit graph

10 commits

Author SHA1 Message Date
Marcus Kida
13ecc08267 Layout: increase content top padding to clear the S-meter labels
Bump DISPLAY_MAIN_CONTENT_TOP_PAD 4 -> 8 so the DMR RX talkgroup/talker (and the
FM contact / CTCSS / squelch info sharing that strip) no longer crowds the S-meter
label row. Contact moves from y=28 to y=32, leaving a clear gap below the labels.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-06 14:10:37 +02:00
Marcus Kida
27a254feb6 Update fork comment 2026-07-06 13:40:30 +02:00
Marcus Kida
78fcccf394 Credits: add Marcus DK1DA to the firmware-info credits list
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-06 13:36:21 +02:00
Marcus Kida
70089d370f Frequency display: 7-segment "LED" font with dimmed inactive segments
Render the VFO/Channel frequency (and the SK1-held frequency view, which share
uiUtilityDisplayFrequency) as 7-segment "LED" digits instead of the normal font,
on colour displays.

- HX8353E_display.c: displayDrawFrequencySevenSeg() draws each digit's 7 segments
  as filled rectangles; lit segments use the theme frequency colour, inactive
  segments a dimmed (~3/8 intensity, same hue) version, giving the classic LED
  look with faintly-visible "off" segments. The decimal point takes half a cell.
- Digits are 12 px wide (wider than the 8 px font) to fill the space toward the
  "MHz" label; height follows the existing single/double-height frequency layout.
- Monochrome displays keep the normal font.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-06 13:34:35 +02:00
Marcus Kida
94eb00487b Add OpenGD77 screen grabber + GD-77 loader tools
gd-77_screen_grabber.py is the universal OpenGD77 screen grabber (despite the
name): it talks over the USB CDC serial port, auto-detects the radio model and
reads the MD-UV380's 160x128 RGB565 framebuffer, saving a PNG. Handy for
capturing UI changes. gd-77_firmware_loader.py is the GD-77 (MK22) SGL loader,
included for completeness (the MD-UV380 uses opengd77_stm32_firmware_loader.py).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-06 13:17:02 +02:00
Marcus Kida
43c59a7c67 Screen dimming: dim backlight to a fraction of brightness when idle
Add an optional "Screen Dim" setting (Display Options) that, in Auto backlight
mode, dims the screen to a fraction of the configured brightness after the
backlight timeout instead of going to the off level. Any activity restores full
brightness.

- Setting values: Off / 100% / 50% / 30%, stored in two spare option bits
  (no settingsStruct change, no version bump; existing codeplugs default to Off).
- display.c: displayGetIdleBacklightPercentage() computes the idle level.
- applicationMain.c: the idle-timeout tick dims to that level; an incoming
  signal (hasSignal) re-triggers full brightness so RX keeps the screen lit.
  TX already forces full brightness.
- menuDisplayOptions.c: new entry with a hardcoded English label (no language
  files touched).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-06 12:56:33 +02:00
Marcus Kida
89c0b8fa60 Layout: add 4px padding below the S-meter before the top info strip
Shift the contact/TG, CTCSS/DCS and squelch info lines down by a tunable
DISPLAY_MAIN_CONTENT_TOP_PAD (4px) on MD-UV380/DM1701, so they no longer sit
flush against the new S-meter label row. Frequency and everything below are
unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-06 12:56:33 +02:00
Marcus Kida
009d3f7bdf S-meter: segmented block bar with S-level labels (colour displays)
Rework the header RSSI bar (uiUtilityDrawRSSIBarGraph) from a solid two-stage
bar into discrete blocks, one per S-level, on colour displays:

- 9 green blocks for S1..S9 (4 dB per S-unit) plus 6 red blocks for the S9+
  region (10 dB per block, S9+10..S9+60), drawn with 2 px gaps so the header
  background shows between them.
- Proportional fill: full blocks below the level, leading block partially filled
  to reflect the exact signal.
- Bar height raised 4 -> 6 px; the FM/DMR mic-level bars follow the same height
  so nothing is left behind when switching RX <-> TX.
- Scale labels below the blocks: S1/S3/S5/S7/S9 under the green zone and
  +20/+40/+60 under the red, centred under their blocks (font_6x8). The label
  row is blanked while transmitting.

Monochrome displays keep the original solid bar. Existing analog S9+ RSSI
compression is preserved, so calibration is unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-06 11:58:46 +02:00
Marcus Kida
0867742901 Fix DMR hang: call AMBE codec via C function pointers, not inline asm
The radio hard-froze (needs battery pull) the instant it processed an incoming
DMR frame — repeater reply, or noise on a DMR channel. FM and DMR TX-without-a-
listening-repeater were fine. Cause: codec_interface.c invoked the AMBE codec
through hand-written inline assembler with no operands and no clobber list,
branching (BL) to an absolute address. That code's correctness depends entirely
on a specific compiler's register allocation; modern GNU toolchains (both ARM
GCC 10 and 14) miscompile it, corrupting state on the first codec call.

Port the official R20260504 (git ebd7100) rework: replace all five inline-asm
calls (2x decode, 2x encode, 1x ECC) with C function-pointer calls. Each call
reproduces the exact register/stack layout the assembler set up (AAPCS: args
1-4 -> r0-r3, args 5+ -> stack) and sets the Thumb bit on the target address.
Also drop the trailing semicolons from the AMBE_* address macros in codec.h so
they can be used in C expressions.

Builds cleanly with the GCC 14.2 Docker toolchain (no STM32CubeIDE needed) and
DMR RX/TX now works on the radio.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-06 11:14:06 +02:00
Marcus Kida
01467e5913 Initial Commit 2026-07-06 08:45:33 +02:00