README differences + flashing sections; universal release script
- README: add 'What's different from OpenGD77' (incl. the new SK2 mute) and a dedicated 'Flashing' section (DFU steps, per-model flash.sh, donor note). - scripts/forgejo-release.sh: build/attach a single platform or all, reuse an existing release, replace same-named assets, and warn if freetrxVersion.h doesn't match the tag. - TOOLS.md: document the platform build argument. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
a838f9636c
commit
e50993b98f
4 changed files with 116 additions and 25 deletions
|
|
@ -10,6 +10,10 @@ single running list until the first versioned release.
|
||||||
- **DM-1701 build support** — the Docker build is now parameterized by platform;
|
- **DM-1701 build support** — the Docker build is now parameterized by platform;
|
||||||
`./build-firmware.sh DM1701` produces `OpenDM1701.bin` (Baofeng DM-1701 /
|
`./build-firmware.sh DM1701` produces `OpenDM1701.bin` (Baofeng DM-1701 /
|
||||||
Retevis RT-84). Not officially tested yet.
|
Retevis RT-84). Not officially tested yet.
|
||||||
|
- **Release script** (`scripts/forgejo-release.sh`) now builds and attaches a
|
||||||
|
single platform or all of them, and reuses an existing release.
|
||||||
|
- README: added "What's different from OpenGD77" and a dedicated "Flashing"
|
||||||
|
section.
|
||||||
|
|
||||||
## 0.1.0
|
## 0.1.0
|
||||||
|
|
||||||
|
|
|
||||||
54
README.md
54
README.md
|
|
@ -15,6 +15,29 @@ icons, and more). See [`CHANGELOG.md`](CHANGELOG.md) for the full list.
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
|  |  |
|
|  |  |
|
||||||
|
|
||||||
|
## What's different from OpenGD77
|
||||||
|
|
||||||
|
FreeTRX keeps OpenGD77's core (DMR/FM, hotspot, CPS compatibility) and adds:
|
||||||
|
|
||||||
|
- **Audio mute — new SK2 short-tap.** A short tap of **SK2** on the VFO/Channel
|
||||||
|
screen toggles the speaker mute on and off. Turning the **volume knob fully
|
||||||
|
down** counts as muted too. While muted, a bold **"M"** appears in the status
|
||||||
|
bar (left of the battery) and the **red LED flashes** (0.5 s every 2 s). SK2's
|
||||||
|
existing roles are unchanged: held as a modifier, extra-long-press for
|
||||||
|
monitor/squelch-off, and — while a DMR QSO is on screen — a tap still sets the
|
||||||
|
TX talkgroup to the incoming one.
|
||||||
|
- **Segmented block S-meter** with one block per S-level (S1–S9 green, S9+ red)
|
||||||
|
and a scale label row (S1 S3 S5 S7 S9 / +20 +40 +60).
|
||||||
|
- **7-segment "LED" frequency font** with faintly-lit inactive segments, on the
|
||||||
|
VFO and the SK1-held frequency view.
|
||||||
|
- **Screen dimming** — optionally dim the backlight to 100 / 50 / 30 % after
|
||||||
|
inactivity (Auto backlight mode); new setting in Display Options.
|
||||||
|
- **Main-menu icons** next to each top-level entry.
|
||||||
|
- **DMR reliability fix** — resolves a hard-fault (freeze needing a battery pull)
|
||||||
|
on the DMR path that affected recent self-built OpenGD77 revisions.
|
||||||
|
|
||||||
|
See [`CHANGELOG.md`](CHANGELOG.md) for the complete list.
|
||||||
|
|
||||||
## Supported radios
|
## Supported radios
|
||||||
|
|
||||||
This first iteration is developed for and **tested only on the TYT MD-UV380 and
|
This first iteration is developed for and **tested only on the TYT MD-UV380 and
|
||||||
|
|
@ -40,10 +63,35 @@ As with OpenGD77, the source does **not** contain the AMBE codec required for DM
|
||||||
audio. It is merged in from an official manufacturer firmware (V26.45) at flash
|
audio. It is merged in from an official manufacturer firmware (V26.45) at flash
|
||||||
time by the firmware loader. See [`TOOLS.md`](TOOLS.md).
|
time by the firmware loader. See [`TOOLS.md`](TOOLS.md).
|
||||||
|
|
||||||
## Building, flashing & tools
|
## Flashing
|
||||||
|
|
||||||
See [`TOOLS.md`](TOOLS.md) for building (Docker + Arm GNU Toolchain 14), flashing
|
Pre-built firmware is attached to each
|
||||||
(`./flash.sh`), grabbing screenshots, and building language files.
|
[release](https://git.dk1da.de/DK1DA/FreeTRX/releases): `OpenMDUV380.bin` for the
|
||||||
|
MD-UV380 / RT-3S, `OpenDM1701.bin` for the DM-1701 / RT-84. (Or build your own —
|
||||||
|
see below.)
|
||||||
|
|
||||||
|
1. **Enter firmware-update (DFU) mode:** power the radio **off**, then power it
|
||||||
|
**on while holding PTT + SK1** (the button above PTT). The screen stays blank
|
||||||
|
and the top LED glows steadily. Connect the USB cable.
|
||||||
|
2. **Flash** with the helper (it applies the DMR codec donor and, optionally, a
|
||||||
|
secondary language):
|
||||||
|
```bash
|
||||||
|
./flash.sh -m MD-UV380 -f MDUV380_firmware/build/OpenMDUV380.bin
|
||||||
|
# DM-1701 / RT-84:
|
||||||
|
./flash.sh -m DM-1701 -f MDUV380_firmware/build/OpenDM1701.bin
|
||||||
|
```
|
||||||
|
|
||||||
|
**DMR note:** the firmware image is FM-only until the **AMBE codec donor** (the
|
||||||
|
official V26.45 manufacturer firmware) is merged in at flash time. Register it
|
||||||
|
once with `./flash.sh -s /path/to/official_V26.45.bin`; the path is then
|
||||||
|
remembered. Full options, the DFU device list and the underlying loader are
|
||||||
|
documented in [`TOOLS.md`](TOOLS.md).
|
||||||
|
|
||||||
|
## Building & tools
|
||||||
|
|
||||||
|
See [`TOOLS.md`](TOOLS.md) for building in Docker
|
||||||
|
(`./build-firmware.sh [MDUV380|DM1701]`, Arm GNU Toolchain 14), grabbing
|
||||||
|
screenshots, and building language files.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|
|
||||||
8
TOOLS.md
8
TOOLS.md
|
|
@ -26,11 +26,13 @@ the official OpenGD77 firmware uses. (Ubuntu's stock GCC 10 miscompiles the DMR
|
||||||
path; see the git history.)
|
path; see the git history.)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./build-firmware.sh
|
./build-firmware.sh # MD-UV380 / RT-3S -> build/OpenMDUV380.bin (default)
|
||||||
|
./build-firmware.sh DM1701 # DM-1701 / RT-84 -> build/OpenDM1701.bin
|
||||||
```
|
```
|
||||||
|
|
||||||
Output: `MDUV380_firmware/build/OpenMDUV380.bin` (the flashable, FM-only image; the DMR
|
Output: `MDUV380_firmware/build/Open<platform>.bin` (the flashable, FM-only image; the DMR
|
||||||
codec is merged in at flash time — see below). The build is always clean (`rm -rf build`).
|
codec is merged in at flash time — see below). The build is always clean (`rm -rf build`),
|
||||||
|
so building one platform overwrites the other's output.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,37 +1,74 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
#
|
#
|
||||||
# Create a Forgejo release for a tag and attach the built firmware binary.
|
# Build and publish a FreeTRX release on Forgejo, attaching the firmware binaries.
|
||||||
#
|
#
|
||||||
# Requires a Forgejo API token in the FORGEJO_TOKEN env var
|
# Requires a Forgejo API token in FORGEJO_TOKEN
|
||||||
# (Forgejo -> Settings -> Applications -> Generate New Token, scope: write:repository).
|
# (Forgejo -> Settings -> Applications -> Generate New Token, scope: write:repository).
|
||||||
# The release notes are taken from the matching "## <version>" section of CHANGELOG.md.
|
# Release notes are taken from the matching "## <version>" section of CHANGELOG.md.
|
||||||
|
# If the release already exists it is reused; assets of the same name are replaced.
|
||||||
#
|
#
|
||||||
# Usage: FORGEJO_TOKEN=xxxxx scripts/forgejo-release.sh v0.1.0
|
# Usage: FORGEJO_TOKEN=xxx scripts/forgejo-release.sh <tag> [platform ...]
|
||||||
|
# platform: MDUV380 | DM1701 | all (default: all)
|
||||||
|
# Examples:
|
||||||
|
# scripts/forgejo-release.sh v0.1.0 # build + attach both binaries
|
||||||
|
# scripts/forgejo-release.sh v0.1.0 MDUV380 # just the MD-UV380 binary
|
||||||
#
|
#
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
TAG="${1:?usage: FORGEJO_TOKEN=... $0 <tag, e.g. v0.1.0>}"
|
TAG="${1:?usage: FORGEJO_TOKEN=... $0 <tag> [MDUV380|DM1701|all]}"; shift || true
|
||||||
VER="${TAG#v}"
|
VER="${TAG#v}"
|
||||||
API="https://git.dk1da.de/api/v1/repos/DK1DA/FreeTRX"
|
API="https://git.dk1da.de/api/v1/repos/DK1DA/FreeTRX"
|
||||||
BIN="MDUV380_firmware/build/OpenMDUV380.bin"
|
|
||||||
: "${FORGEJO_TOKEN:?set FORGEJO_TOKEN (Forgejo -> Settings -> Applications, scope write:repository)}"
|
: "${FORGEJO_TOKEN:?set FORGEJO_TOKEN (Forgejo -> Settings -> Applications, scope write:repository)}"
|
||||||
|
|
||||||
cd "$(dirname "${BASH_SOURCE[0]}")/.."
|
cd "$(dirname "${BASH_SOURCE[0]}")/.."
|
||||||
[ -f "$BIN" ] || { echo "Missing $BIN - run ./build-firmware.sh first"; exit 1; }
|
|
||||||
|
|
||||||
# Release body = the CHANGELOG section for this version.
|
# Resolve requested platforms (default / "all" -> both).
|
||||||
|
PLATFORMS=("$@")
|
||||||
|
if [ ${#PLATFORMS[@]} -eq 0 ] || [ "${PLATFORMS[0]}" = "all" ]; then
|
||||||
|
PLATFORMS=(MDUV380 DM1701)
|
||||||
|
fi
|
||||||
|
bin_for() { case "$1" in MDUV380) echo OpenMDUV380 ;; DM1701) echo OpenDM1701 ;; *) return 1 ;; esac; }
|
||||||
|
|
||||||
|
# Sanity check: the on-screen version should match the tag.
|
||||||
|
FW_VER="$(grep -oE '"[0-9]+\.[0-9]+\.[0-9]+"' MDUV380_firmware/application/include/freetrxVersion.h | head -1 | tr -d '"')"
|
||||||
|
[ "$FW_VER" = "$VER" ] || echo "WARNING: freetrxVersion.h is $FW_VER but tag is $VER — bump it before releasing?"
|
||||||
|
|
||||||
|
# Build each platform and stage its binary (clean builds overwrite build/).
|
||||||
|
STAGE="$(mktemp -d)"; trap 'rm -rf "$STAGE"' EXIT
|
||||||
|
for P in "${PLATFORMS[@]}"; do
|
||||||
|
OUT="$(bin_for "$P")" || { echo "Unknown platform '$P' (use MDUV380, DM1701 or all)"; exit 1; }
|
||||||
|
echo "==> Building $P"
|
||||||
|
./build-firmware.sh "$P" >/dev/null
|
||||||
|
cp "MDUV380_firmware/build/${OUT}.bin" "$STAGE/${OUT}.bin"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Release notes = the CHANGELOG section for this version.
|
||||||
NOTES="$(awk -v v="## ${VER}" '$0==v{f=1} f&&/^## /&&$0!=v{exit} f{print}' CHANGELOG.md)"
|
NOTES="$(awk -v v="## ${VER}" '$0==v{f=1} f&&/^## /&&$0!=v{exit} f{print}' CHANGELOG.md)"
|
||||||
[ -n "$NOTES" ] || NOTES="FreeTRX ${TAG}"
|
[ -n "$NOTES" ] || NOTES="FreeTRX ${TAG}"
|
||||||
|
|
||||||
# Create the release (JSON body built safely via python).
|
# Create the release, or reuse it if it already exists.
|
||||||
BODY="$(python3 -c 'import json,sys; print(json.dumps({"tag_name":sys.argv[1],"name":"FreeTRX "+sys.argv[1],"body":sys.argv[2],"draft":False,"prerelease":False}))' "$TAG" "$NOTES")"
|
ID="$(curl -sS "$API/releases/tags/$TAG" -H "Authorization: token $FORGEJO_TOKEN" | python3 -c '
|
||||||
RESP="$(curl -fsS -X POST "$API/releases" -H "Authorization: token $FORGEJO_TOKEN" -H "Content-Type: application/json" -d "$BODY")"
|
import json,sys
|
||||||
ID="$(printf '%s' "$RESP" | python3 -c 'import json,sys; print(json.load(sys.stdin).get("id",""))')"
|
try:
|
||||||
[ -n "$ID" ] || { echo "Failed to create release:"; echo "$RESP"; exit 1; }
|
d=json.load(sys.stdin); print(d.get("id","") if isinstance(d,dict) else "")
|
||||||
echo "Created release $TAG (id=$ID)"
|
except Exception:
|
||||||
|
print("")')"
|
||||||
|
if [ -z "$ID" ]; then
|
||||||
|
BODY="$(python3 -c 'import json,sys; print(json.dumps({"tag_name":sys.argv[1],"name":"FreeTRX "+sys.argv[1],"body":sys.argv[2],"draft":False,"prerelease":False}))' "$TAG" "$NOTES")"
|
||||||
|
ID="$(curl -fsS -X POST "$API/releases" -H "Authorization: token $FORGEJO_TOKEN" -H "Content-Type: application/json" -d "$BODY" | python3 -c 'import json,sys;print(json.load(sys.stdin)["id"])')"
|
||||||
|
echo "==> Created release $TAG (id=$ID)"
|
||||||
|
else
|
||||||
|
echo "==> Reusing existing release $TAG (id=$ID)"
|
||||||
|
fi
|
||||||
|
|
||||||
# Attach the firmware binary.
|
# Attach each staged binary, replacing an existing asset of the same name.
|
||||||
curl -fsS -X POST "$API/releases/$ID/assets?name=OpenMDUV380.bin" \
|
ASSETS="$(curl -fsS "$API/releases/$ID/assets" -H "Authorization: token $FORGEJO_TOKEN")"
|
||||||
-H "Authorization: token $FORGEJO_TOKEN" -F "attachment=@$BIN" >/dev/null
|
for f in "$STAGE"/*.bin; do
|
||||||
echo "Attached $BIN"
|
name="$(basename "$f")"
|
||||||
echo "Done -> https://git.dk1da.de/DK1DA/FreeTRX/releases/tag/$TAG"
|
aid="$(printf '%s' "$ASSETS" | python3 -c 'import json,sys; n=sys.argv[1]; print(next((str(a["id"]) for a in json.load(sys.stdin) if a.get("name")==n),""))' "$name")"
|
||||||
|
[ -z "$aid" ] || curl -fsS -X DELETE "$API/releases/$ID/assets/$aid" -H "Authorization: token $FORGEJO_TOKEN" >/dev/null
|
||||||
|
curl -fsS -X POST "$API/releases/$ID/assets?name=$name" -H "Authorization: token $FORGEJO_TOKEN" -F "attachment=@$f" >/dev/null
|
||||||
|
echo "==> Attached $name"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "==> Done -> https://git.dk1da.de/DK1DA/FreeTRX/releases/tag/$TAG"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue