Commit graph

45 commits

Author SHA1 Message Date
Marcus Kida
91043a006a Release 0.10.1
Remove the muted 'M' status-bar icon that overlapped the GPS text; the
flashing red LED indicates mute.

Bump version to 0.10.1.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 23:28:09 +02:00
Marcus Kida
c770693848 Fix: remove muted 'M' header icon that overlapped GPS text
With GPS enabled, the bold 'M' mute indicator in the status bar collided
with the GPS text. Drop the header icon; the flashing red LED already
indicates the muted state. Docs updated.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 23:27:43 +02:00
Marcus Kida
6a5731e8a4 Release 0.10.0
SMS recipient picker (GREEN in the compose recipient field selects from your
private-call DMR contacts) and a combined 'Contacts' view in Menu -> Contacts.

Bump version to 0.10.0.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 23:08:59 +02:00
Marcus Kida
15bbc1bc3a SMS: pick recipient from contacts; contacts list shows all types
- New SMS recipient picker: GREEN in the compose recipient field opens a list
  of private-call DMR contacts; selecting one fills the destination (using the
  contact's plain DMR ID) and moves to the message text. Manual ID entry still
  works (DOWN advances to the text field).
- Menu -> Contacts now defaults to a combined 'Contacts' view of all contact
  types instead of the group-only filter; HASH still cycles the per-type
  filters. Per-type code paths are unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 23:08:25 +02:00
Marcus Kida
a94fd59a10 Release 0.9.0
Pride theme: status/header bar and menu title bar now use the top rainbow
stripe colour instead of white.

Bump version to 0.9.0.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 17:52:45 +02:00
Marcus Kida
959f7f2a03 Pride theme: paint status and menu title bars in the top stripe colour
Blend the header/status bar and the menu title bar into the rainbow by
filling them with the top pride stripe colour instead of white.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 15:47:26 +02:00
Marcus Kida
3fe33b931d Release 0.8.0
New colour theme presets (Red, Neon 80s, and the rainbow-background Pride),
plus a per-region memory-usage summary printed after every build.

Bump version to 0.8.0.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 14:48:17 +02:00
Marcus Kida
3ec4eafbc9 Themes: add 'Pride' rainbow-background preset
The theme system stores one flat background colour per element, so a rainbow
background can't be expressed as a preset alone. Add a small display hook:
when Pride is selected, displayClearBuf()/displayClearRows() paint the six
pride-flag stripes across the framebuffer instead of a flat fill (gated on a
flag only the Pride preset sets, and behind HAS_COLOURS so mono builds are
untouched). Non-selected menu rows draw text straight over the canvas, while
the title/header/notifications paint solid white boxes, so chrome stays
readable over the stripes; blue/violet are lightened slightly for black-text
contrast. Docs and changelog updated.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 14:47:45 +02:00
Marcus Kida
c614ba8096 Themes: add 'Red' and multi-colour 'Neon 80s' presets
Red mirrors the two-tone Terminal/Vertexic presets (black-on-red day,
red-on-black night). Neon 80s is a synthwave palette that assigns distinct
neon colours (cyan, magenta, violet, green, yellow, red, orange) to the
individual theme items over a dark background, demonstrating that presets
are not limited to two colours.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 10:40:37 +02:00
Marcus Kida
5646d2df11 Release 0.7.1
Fix a crash when navigating the Messages menu with voice prompts enabled:
menu strings added after the voice-prompt pack was built read past the end
of the table of contents and now play silence instead.

Bump version to 0.7.1.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 17:32:26 +02:00
Marcus Kida
9eceb10013 Fix crash announcing menu strings past the voice-prompt table
voicePromptsAppendLanguageString() turns a language-string pointer into a
prompt index (NUM_VOICE_PROMPTS + offset), and voicePromptsPlay() then reads
tableOfContents[index + 1]. Strings added after the voice-prompt pack was
built (the SMS menu entries) land past the 368-entry table, so the player
read off the end of the array and the radio crashed when the Messages menu
announced a submenu name with voice prompts enabled.

Clamp any index at or beyond the last table slot to PROMPT_SILENCE, so such
strings are simply not spoken. Also protects the pre-existing strings sitting
at the very end of the table.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 17:31:09 +02:00
Marcus Kida
741578e294 Release 0.7.0
DMR text messages (SMS): compose, inbox/sent, quick texts, delivery
confirmation and an incoming-message popup, compatible with
BrandMeister/hotspots (Motorola TMS) and Anytone/"DMR standard"
senders. Also removes the main-menu icons (plain-text entries again).

Bump version to 0.7.0.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 16:53:33 +02:00
Marcus Kida
31c31df861 DMR text messages (SMS): ETSI/Motorola-TMS messaging on the radio
Full messaging support, implemented fresh in three layers:

- dmrDataProtocol: pure short-data codec (CSBK preamble, data/response
  headers, IP/UDP/TMS payload, ETSI CRCs) validated against on-air
  captures by a host-side test suite. Transmits Motorola TMS (UDP 4007),
  receives TMS and Anytone/"DMR standard" (UDP 5016).
- smsCore/smsStorage: TX queue with wait-for-channel and delivery
  confirmation (response PDU / ACK, resend prompt on timeout), ISR-side
  block assembly with layout auto-detection (confirmed/unconfirmed,
  rate-1/2 and full 18-byte rate-3/4 blocks), delivery reports to
  senders that request them, and a checksummed message store in SPI
  flash at 0xC00000 (inbox + sent, 8 each; 8 quick texts).
- UI: Messages hub (main menu or long-press GREEN), keypad compose with
  multi-tap (160 chars), inbox/sent/view with reply-resend-delete,
  quick-text picker/editor, options (Wait for ACK, My ID only), and an
  incoming-message popup with chime. Strings in all 20 languages.

The HR-C6000 does the BPTC/FEC; the driver streams 12-byte logical
bursts through the existing TX state machine (repeater wake included),
locks out PTT during a send, and leaves hotspot mode untouched.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 16:52:54 +02:00
Marcus Kida
58e8269500 Add missing LedGreenSuppress() declaration to LEDs.h
The implementation and callers landed with the 0.6.0 green-LED mute fix,
but the header declaration was left uncommitted.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 16:52:19 +02:00
Marcus Kida
8dcda476aa Revert main-menu icons: plain-text entries again
Remove the 16x16 main-menu icon bitmaps, menuIconForMenuNumber(),
menuSetNextEntryIconByMenuNum() and the icon drawing + text offset in
menuDisplayEntry(). Top-level menu entries render as plain text as before.
Docs updated.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-13 12:04:56 +02:00
Marcus Kida
ff1559ec5e Release 0.6.0
On-radio theme presets (Custom / BASIC 80s / Terminal / Vertexic), the green-LED
flicker fix while muted during a DMR QSO, and the screenshot.sh helper.

Bump version to 0.6.0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-13 10:04:01 +02:00
Marcus Kida
23fd4df110 Themes: add 'Vertexic' orange preset
New theme preset: orange (#FF6A00) background with black text by day, inverted
(orange on black) at night. Vertex-style amber/orange look. Documented in
MANUAL.md and the README.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-13 10:02:16 +02:00
Marcus Kida
8c9828e386 Themes: selectable on-device presets (Custom / BASIC 80s / Terminal)
Add a Theme selector in Display Options that cycles three presets with a live
preview: Custom (CPS-editable, default), BASIC 80s (Commodore 64 light-blue on
blue) and Terminal (green-on-black night / black-on-green day). Presets fill all
theme items for a cohesive look.

The selection is stored in the codeplug custom-data area (new THEME_PRESET
block), which is migration-safe (missing block -> Custom) and needs no settings
reset. CPS theme edits only ever change the Custom theme. Documented in MANUAL.md
and the README.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 14:41:08 +02:00
Marcus Kida
5ac77c5ae9 Fix: green LED flicker between red mute flashes during a DMR QSO
The DMR RX handler re-asserts the green LED whenever it reads it off, racing the
main-loop mute clear, so green flickered between the red flashes. Add a
LedGreenSuppress() hold in the LED driver: while muted the green LED is forced
off (the re-assert becomes a no-op); on un-mute the hold is released and green is
restored from the current RX state.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 13:15:23 +02:00
Marcus Kida
e20eabd203 Release 0.5.0
Fix the green RX LED not returning after un-muting mid-QSO, plus the MANUAL.md
user guide and the MkDocs documentation website from this cycle.

Bump version to 0.5.0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 13:54:15 +02:00
Marcus Kida
8fcfb66893 Fix: restore green RX LED after un-muting during a QSO
The mute flash forced the green LED off; on un-mute it was blanked instead of
restored, so a call in progress stayed dark. Restore green from the current RX
state (active DMR slot, or FM/digital signal received) on un-mute; the normal RX
code keeps it correct afterwards.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 13:46:51 +02:00
Marcus Kida
d5ddc4748b Release 0.4.0
On-radio channel add/delete from the Channel quick menu (with translations and a
Managing-channels manual section), flash.sh always rebuilds language packs, and
releases before v1.0.0 are flagged as pre-releases.

Bump version to 0.4.0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 12:49:45 +02:00
Marcus Kida
a8c2038552 Channels: translate the add/delete menu strings; flash.sh rebuilds packs
Add delete_channel and keep_one_channel to the language table (after mute) and
fill all 20 language files (13 translated, English fallback for the rest), with
correct single-byte ISO-8859 accents. Wire them into the Delete Channel label,
confirmation and last-channel guard. The new strings land on empty voice-table
slots, so they play as silence (no crash, no .vpr regeneration).

flash.sh now always rebuilds the .gla language packs so edits to the language
files are actually picked up (previously a stale pack was re-flashed).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 12:47:27 +02:00
Marcus Kida
e145a1188d Channels: on-radio add/delete from the Channel quick menu
Add two codeplug primitives - codeplugAllChannelsIndexSetUnused() (frees a
channel slot: clears the in-use bitmap bit, persists the header, fixes counts)
and codeplugZoneRemoveChannelFromZoneAndSave() (removes a channel from a zone's
list) - and wire two new Channel quick-menu items:

- 'new channel': allocates the first free slot, writes a blank 145.500 FM
  channel, adds it to the current zone, reloads the zone and opens Channel
  Details to edit it.
- 'Delete Channel': confirmation, then scrubs the channel from every real zone
  before freeing the slot. Guards against deleting the last channel and honours
  the read-only/APRS lock.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 11:11:48 +02:00
Marcus Kida
dd1cc0ccdf Release 0.3.0: fix Screen Dim label voice-prompt crash
The menu label 'Screen Dim' is a raw literal, and the shared menu code voices
labels through voicePromptsAppendLanguageString(), which derives the prompt
index from the pointer's offset within the language table and crashed on a
foreign pointer (v0.2.0 fixed only the value, not the label). That helper now
ignores pointers outside the language table.

Bump version to 0.3.0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-07 16:29:21 +02:00
Marcus Kida
1c59622a77 Release 0.2.0: fix Display Options crash with voice prompts on
Screen Dim passed a plain literal ('100%'/'50%'/...) to
voicePromptsAppendLanguageString(), which derives the prompt index from the
string's offset within the language table; a foreign pointer produced a garbage
index and crashed (only with voice on). Route the value through
voicePromptsAppendString() instead. Also move the 3-bit dim level's high bit off
legacy option bit 2 to bit 29 and clamp the level against the option arrays.

Bump version to 0.2.0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-07 15:41:59 +02:00
Marcus Kida
734b861917 7-segment frequency: inactive segments off, fix MHz colour, +1px RX/TX gap
- Inactive segments now render in the background colour (off) instead of dimmed.
- The 7-seg renderer left the foreground on the last segment drawn (now the
  background colour), which hid MHz; re-apply the frequency theme colour before
  drawing MHz so it reappears and matches the digits.
- Move the TX frequency line down 1px for a little more RX/TX separation.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-07 15:30:23 +02:00
Marcus Kida
7f5f3ab06f Screen dimming: add a 15% idle-dim level
Add SCREEN_DIM_15 (Off / 100 / 50 / 30 / 15). The value now needs 3 bits, so
repurpose the spare BIT_UNUSED_2 as BIT_SCREEN_DIM_2; existing codeplugs (bit 2
clear) keep their level, no reset.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-07 08:16:04 +02:00
Marcus Kida
facf5f6a6d Add FreeTRX version and show it in Firmware Info (v0.1.0)
- New freetrxVersion.h with semver (MAJOR/MINOR/PATCH + string), currently 0.1.0.
- Firmware Info top line now shows "FreeTRX v0.1.0"; the git commit ID line is
  unchanged. The version is also announced via voice prompt.
- CHANGELOG: promote the accumulated changes to a 0.1.0 section.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-06 18:34:10 +02:00
Marcus Kida
e5755be061 FreeTRX: on-screen rename, credits, and README supported-radios note
- Splash screen and Firmware Info name now show "FreeTRX".
- Firmware-info credits: "Marcus DK1DA", a separator, and a thank-you to the
  original OpenGD77 authors.
- README documents that this iteration is developed/tested only on the TYT
  MD-UV380 and Retevis RT-3S, with a contact for testing other supported radios.
- CHANGELOG updated.

Hardware/tooling identifiers (build filename, MD-UV380 model IDs, hotspot
version string) intentionally left unchanged to avoid breaking flashing and
Pi-Star/MMDVM compatibility.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-06 18:11:22 +02:00
Marcus Kida
e9cf936661 Mute: remove the mode-text strike-through, keep the header "M"
Drop the built-in strike-through over the FM/DMR mode text when muted; the
header "M" (and red LED flash) are the mute indicators now.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-06 16:04:56 +02:00
Marcus Kida
9d50d78dc0 Mute: also show mute indicators when volume knob is fully down
Treat the volume control at its minimum (lastVolume == -99, the firmware's
'muted' position) as effectively muted, so the red LED flash, the header M
and the built-in strike-through appear without an explicit SK2 mute.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-06 15:54:25 +02:00
Marcus Kida
0caeeadd51 Layout: move private-call caller ID below the S-meter labels
The private-call caller ID was drawn at a hardcoded y=16, which now collides
with the S-meter label row. Use DISPLAY_Y_POS_CONTACT (same as the group-call
contact line) so it clears the labels.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-06 15:46:57 +02:00
Marcus Kida
f67bb2fade Mute: toggle audio mute with SK2 short-tap, with LED + header indicator
Add a one-tap audio mute on the VFO and Channel screens:

- SK2 short-tap toggles mute via the built-in audioAmpMute()/audioAmpIsMuted().
  The tap is only consumed by the existing "set TX TG to incoming" behaviour
  while a DMR QSO is on screen, so mute works everywhere else.
- Header: a bold "M" is shown just left of the battery while muted (the
  firmware's built-in strike-through over the mode text also still shows).
- LED: flashes red for 0.5s every 2s while muted (main loop), overriding the
  normal RX/TX LED.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-06 15:41:29 +02:00
Marcus Kida
fe9b8d4e10 add menu icons 2026-07-06 14:41:43 +02:00
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