Skip to content

fix(cpn): derive serial ports, Bluetooth and GPS from firmware via hw_defs JSON - #7881

Draft
pfeerick wants to merge 6 commits into
mainfrom
fix/cpn-aux-serial-caps
Draft

pfeerick wants to merge 6 commits into
mainfrom
fix/cpn-aux-serial-caps

Conversation

@pfeerick

@pfeerick pfeerick commented Oct 7, 2026 •

Copy link
Copy Markdown
Member

Summary

Companion decided which serial ports, Bluetooth and internal GPS a radio has using hand-written board-family rules and hand-maintained build-option lists. These have drifted a long way from the firmware. This PR takes those facts from the firmware itself, records them in the hw_defs JSON, and combines them with the build options selected in the radio profile.

Commits

1. AUX serial ports and port power from hw_defs JSON

New has_aux_serial, has_aux_serial_pwr, has_aux2_serial, has_aux2_serial_pwr flags, taken from the default build of every target (AUX_SERIAL_USART, AUX2_SERIAL_USART, AUX_SERIAL_PWR_GPIO, AUX2_SERIAL_PWR_GPIO). Compared with the old rules:

Boards
AUX2 shown but not in firmware V12, T15, T15H7, F16, V16
AUX2 in firmware but not shown X12S
AUX1 in firmware but not shown NV14, EL18, PL18, PL18EV, PL18U, NB4P, Boxer, Bumblebee, Pocket, GX12, V14, V14 LCD
AUX1 shown but not in firmware T15 Pro, X10 Express
Port power only offered on TX16S (GX15, H17, TX15, TX16S MK3, F16, V16, T15H7 and T16's AUX2 also have it)

The TX16S-only HasSoftwareSerialPower becomes per-port HasAuxSerialPower / HasAux2SerialPower.

2. chore(h17): drop the BLUETOOTH build option

H17's hal.h has no Bluetooth UART or pins, so the option only turned AUX2 off. It can come back if the hardware turns out to have a module.

3. Apply profile build options to the current firmware variant (3.0 regression)

Since #7623 the profile stores build options in fwOptions, separately from fwType, but the current firmware variant was still looked up from fwType alone. Every option-dependent capability in OpenTxFirmware::getCapability() was therefore always off: nogvars, haptic, internalelrs/crsf/multi, afhds2a/3, flyskygimbals, danger, and so on. The variant is now looked up with the options, and it is refreshed when only the options change in the profile settings.

The standalone simulator (simulator.cpp, simulatorstartupdialog.cpp) still uses fwType alone. Its id also selects the simulator library, so it is left for a follow-up.

4. Bluetooth and GPS availability from firmware

hw_defs JSON now also records, from the default build and a BLUETOOTH=ON build of every target:

  • bluetooth: builtin or optional
  • bluetooth_aux_port: 1/2, the AUX port an optional Bluetooth build gives up (T16/T18/TX16S/TX16S MK3: AUX2; T15/V16/V14/V14 LCD/GX12/Pocket/Boxer/Zorro/TX12 MK2: AUX1)
  • has_internal_gps: INTERNAL_GPS is in the default build

Profile build options:

  • bluetooth is now offered on every board where firmware supports it as an option. It's removed from GX15 and ST16, which have no Bluetooth, and added to around 25 boards that were missing it. A test checks that the offered options match the JSON.
  • internalgps is replaced by nogps ("Disable internal GPS support"). INTERNAL_GPS is only a build option on the targets that declare it (gx15, h17, tx15, tx16smk3, and horus boards with an AUX port), and there it defaults to ON. So nogps is offered on exactly those 12 boards. Boards that don't provide the option get no GPS option in Companion, and GPS is reported unavailable, matching their builds. This follows the noheli/nogvars/noras convention for options that are on unless turned off. (The opt-in internalgps came from the old radio/util/build-firmware.py, which sets INTERNAL_GPS=NO unless requested; that script only accepts opentx-… firmware names.) Old profiles carrying internalgps meant "GPS on", which is the default where the option exists; the name is ignored and drops out the next time the profile is saved. Renaming "internal GPS" (e.g. to "TX GPS", matching MIXSRC_TX_GPS / getTxGPS()) is left for a future PR.
  • Bluetooth no longer excludes GPS. GPS is a serial mode on an AUX port, so it is only unavailable when Bluetooth takes the last remaining AUX port (V16, T15).

New firmware-variant capabilities BluetoothEnabled, AuxSerialAvailable, Aux2SerialAvailable and InternalGPSAvailable combine the board data with the selected options. The Hardware panel (Bluetooth section, AUX1/AUX2) and the default top bar "Internal GPS" widget use them. The board-family HasBluetooth / HasInternalGPS rules are removed.

5. fix(build): hardware_defs dump misses definitions added after it

The define dump was taken at radio/src/CMakeLists.txt:193, before definitions such as add_definitions(-DBLUETOOTH) (line 318), so BLUETOOTH and anything depending on it (BT_USART) never appeared. The call is now deferred to the end of the directory with cmake_language(DEFER CALL ...), which also covers native builds that return() early.

6. chore: remove GPS settings from targets without the INTERNAL_GPS option

c14, pl18 and st16 had if(INTERNAL_GPS) blocks, and t15pro, pa01, t15h7, t22 and v12 unconditionally added -DGPS_USART_BAUDRATE=${INTERNAL_GPS_BAUDRATE}, although none of them declare the option. With INTERNAL_GPS_BAUDRATE never set, the latter gave an empty -DGPS_USART_BAUDRATE=. GPS_USART_BAUDRATE is only used inside #if defined(INTERNAL_GPS) (serial.cpp), so all of these were dead. They are removed, so a target either declares the option or has no GPS configuration at all.

How the data was produced

The values come from preprocessor define dumps of all 58 targets, made with tools/generate-hw-defs.sh: once with default options and once with EXTRA_OPTIONS=-DBLUETOOTH=ON. This needs #7880 and commit 5. A script then checked every JSON flag against the dumps. With commit 5, the committed tooling reproduces the Bluetooth data exactly (all 58 boards compared).

Testing

  • gtests-companion: 40 tests pass. New BoardSerialPorts tests cover:
    • AUX/power spot checks;
    • registered bluetooth/nogps options match the JSON for every firmware;
    • variant results for tx16s, tx16s-bluetooth, tx16s-nogps, v16-bluetooth, x12s, v12.
  • The full Companion app builds.
  • hw_defs checks: json_validator.py, check-jsonschema with hwdef_schema.json, and test_templates.py (58 boards × 16 templates) all pass.
  • H17 firmware builds without the BLUETOOTH option, with AUX2 present.
  • Companion UI not yet checked by hand.

Notes

  • Main / 3.0 only. 2.12's Companion doesn't read hardware flags from JSON.
  • "Optional Bluetooth" means the firmware builds with it. For several Taranis-family boards the shared hal.h defines Bluetooth pins generically, so whether the hardware has a module is not something the firmware data can confirm.

🤖 Generated with Claude Code

@pfeerick pfeerick added this to the 3.0 milestone Oct 7, 2026
@pfeerick pfeerick added bug 🪲 Something isn't working companion (cpn) Related to the companion software labels Oct 7, 2026
@elecpower

Copy link
Copy Markdown
Collaborator

Yeah fewer dodgy IS_ rules for me to convert to Companion board json keys:values in the boards refactor.
I'm getting closer to a draft refactor PR so hopefully some more can be moved to hwdefs and Companion is left with very minimal or preferably none of its own.

@pfeerick pfeerick changed the title fix(cpn): derive AUX serial ports and port power from hw_defs JSON fix(cpn): derive serial ports, Bluetooth and GPS from firmware via hw_defs JSON Oct 7, 2026
pfeerick and others added 5 commits October 7, 2026 03:52
Companion guessed which AUX serial ports a radio has from its board
family, which no longer matches the firmware for many radios: e.g. V12,
T15, T15H7, F16 and V16 were shown an AUX2 port they don't have, X12S
was missing its AUX2, NV14/EL18/PL18/NB4P/Boxer/Pocket/GX12/V14 were
missing AUX1, and T15 Pro / X10 Express were shown an AUX1 they don't
have. Port power was only offered on TX16S.

Add has_aux_serial, has_aux2_serial and per-port has_aux*_serial_pwr
flags to the hw_defs "hardware" block, filled from the default firmware
build of every target (AUX_SERIAL_USART, AUX2_SERIAL_USART,
AUX_SERIAL_PWR_GPIO, AUX2_SERIAL_PWR_GPIO in the preprocessor dump), and
answer HasAuxSerialMode / HasAux2SerialMode from them. The single
TX16S-only HasSoftwareSerialPower becomes HasAuxSerialPower and
HasAux2SerialPower, so the power toggle shows on each port that really
has power control (e.g. only AUX2 on Jumper T16).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The H17 target offered a BLUETOOTH option, but its hal.h defines no
Bluetooth UART or pins, so enabling it only turned off AUX2 without
giving a working Bluetooth port. Remove it; it can come back if the
hardware turns out to have a Bluetooth module.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Since #7623 the radio profile stores its build options in fwOptions,
separately from fwType, but the current firmware variant was still
looked up from fwType alone. Every capability that depends on a build
option (nogvars, haptic, internalelrs/crsf/multi, afhds2a/3,
flyskygimbals, danger, ...) was therefore always off.

Look the variant up from fwType plus the selected options, and refresh
it when only the options are changed in the profile settings, not just
when the radio type changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bluetooth and internal GPS were board-family guesses in Companion, and
the "bluetooth"/"internalgps" profile options were registered by hand
and had drifted from the firmware (e.g. offered on GX15 and ST16, which
have no Bluetooth, and missing on boards that do support it).

hw_defs JSON now records, from the firmware's default and BLUETOOTH=ON
builds of every target:
- "bluetooth": "builtin" or "optional"
- "bluetooth_aux_port": the AUX port an optional Bluetooth build gives up
- "has_internal_gps": INTERNAL_GPS is in the default build

The profile's build options are matched to that data (a test keeps them
in sync): "bluetooth" where Bluetooth is optional, and "internalgps" is
replaced by "nogps", since INTERNAL_GPS is on by default in firmware.
The two are no longer mutually exclusive.

New firmware-variant capabilities combine the board data with the
selected options: Bluetooth enabled, AUX1/AUX2 available (minus the port
Bluetooth takes) and internal GPS available (needs a remaining AUX port,
as GPS is a serial mode). The hardware settings and the default top bar
GPS widget use them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
AddHardwareDefTarget() snapshots the directory's compile definitions
when it is called, but it was called part way through
radio/src/CMakeLists.txt, before definitions such as BLUETOOTH are
added. The define dump therefore never contained BLUETOOTH or anything
that depends on it (e.g. BT_USART). Defer the call to the end of the
directory, which also covers native builds that return() early.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@pfeerick
pfeerick force-pushed the fix/cpn-aux-serial-caps branch 3 times, most recently from 7ff071b to 21c9604 Compare October 7, 2026 04:19
INTERNAL_GPS is only a build option on the targets that declare it
(gx15, h17, tx15, tx16smk3, and horus boards with an AUX port). c14,
pl18 and st16 still had if(INTERNAL_GPS) blocks, and t15pro, pa01,
t15h7, t22 and v12 unconditionally added
-DGPS_USART_BAUDRATE=${INTERNAL_GPS_BAUDRATE}, which expanded to an
empty define since INTERNAL_GPS_BAUDRATE is never set there.
GPS_USART_BAUDRATE is only used inside #if defined(INTERNAL_GPS), so all
of these were dead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug 🪲 Something isn't working companion (cpn) Related to the companion software

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants