Skip to content

chore: use settings from radio JSON files instead of hal.h#7411

Open
philmoz wants to merge 4 commits into
mainfrom
philmoz/use-json-settings
Open

chore: use settings from radio JSON files instead of hal.h#7411
philmoz wants to merge 4 commits into
mainfrom
philmoz/use-json-settings

Conversation

@philmoz
Copy link
Copy Markdown
Collaborator

@philmoz philmoz commented May 30, 2026

Start to move away from hal.h files and use the radio JSON files for build settings.

Changes:

  • Clean up creation of files generated from radio JSON files, cleanup up dependencies
  • Add new generated file (hal_settings.h)
  • Move some more settings from hal.h to JSON

Known concerns:

  • V12 in main branch appears to be for a B&W radio instead of the color one so is probably wrong (not tested)
  • No build target or JSON file for stm32h7s78-dk dev board
  • horus/hal.h contains settings for X12S that are also dependant on PCBREV value which may be problematic for handling purely in JSON files

Summary by CodeRabbit

Release Notes

  • Chores
    • Restructured hardware configuration system to centralize board definitions through JSON hardware descriptors and automated code generation, improving consistency and maintainability across supported radio models.

@philmoz philmoz added this to the 3.0 milestone May 30, 2026
@philmoz philmoz requested review from 3djc and raphaelcoeffic May 30, 2026 01:04
@philmoz philmoz added compilation Related to compiling the firmware and firmware options house keeping 🧹 Cleanup of code and house keeping labels May 30, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 30, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b812a842-25e2-4800-8799-01fd5d4614a4

📥 Commits

Reviewing files that changed from the base of the PR and between d5f3b1d and e3f7b78.

📒 Files selected for processing (1)
  • tools/hwdef_schema.json
💤 Files with no reviewable changes (1)
  • tools/hwdef_schema.json

📝 Walkthrough

Walkthrough

Adds JSON schema/models and Jinja template to generate hal_settings.h from board JSON. Refactors CMake to centralize generation and dependencies. Migrates numerous board JSONs to new lcd/backlight/leds/timers schema. Updates companion parsing, headers, IRQ macro names, drivers, Lua/YAML/Simu wiring, and GUI gating.

Changes

Hardware definition generation and integration

Layer / File(s) Summary
Generation, schema, build, parser, targets, drivers, UI
radio/util/hw_defs/*, tools/hwdef_schema.json, cmake/Macros.cmake, radio/src/CMakeLists.txt, radio/src/**/CMakeLists.txt, radio/src/boards/hw_defs/*.json, companion/src/firmwares/boardjson.cpp, radio/src/targets/**/*, radio/src/boards/generic_stm32/rgb_leds.cpp, radio/src/targets/common/arm/stm32/*, radio/src/gui/*, radio/src/lua/*
Generate hal_settings.h from board JSON; validate via new schema/models; rewire CMake targets/dependencies; migrate board JSONs to lcd/backlight/leds/timers; update parsing, headers, IRQ macro/handler names; adjust drivers, Lua/YAML/simulator wiring; GUI backlight color gated by HAS_BACKLIGHT_COLOR.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Dev as Developer/CMake
  participant Schema as hwdef_schema.json
  participant Gen as generator.py
  participant Tmpl as hal_settings.jinja
  participant Build as Targets (board, stm32_drivers)
  participant Code as Firmware/Headers

  Dev->>Build: Configure AddHWGenTarget(${FLAVOUR}.json → hal_settings.h)
  Dev->>Schema: Validate board JSON
  Build->>Gen: Run generator with validated JSON
  Gen->>Tmpl: Render with display/leds/backlight/timers
  Tmpl-->>Build: hal_settings.h generated
  Build->>Build: add_dependencies(... hal_settings)
  Build->>Code: Compile with new macros/IRQ names
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch philmoz/use-json-settings

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

🧹 Nitpick comments (1)
radio/util/hw_defs/hal_settings.jinja (1)

10-45: 🏗️ Heavy lift

Boolean HAL feature macros expand to True/False, but current usage is defined(...)-gated
hal_settings.jinja emits #define OLED_SCREEN True/False-style values for boolean HAL fields, and the current codebase references OLED_SCREEN, HAS_BACKLIGHT_COLOR, STATUS_LEDS, LCD_HORIZONTAL_INVERT, and LCD_VERTICAL_INVERT via #if defined(...) / #if !defined(...) (so the True/False numeric-expression risk doesn’t show up in current consumers).
For extra robustness/future-proofing, consider switching to value-less #define for true (skip false) or emit 1/0 instead of Python True/False.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@radio/util/hw_defs/hal_settings.jinja` around lines 10 - 45, The template
currently emits Python True/False text for boolean HAL fields which can break
consumers using `#if` defined(...) checks; update the hal_settings.jinja
generation so booleans are robust: either (preferred) emit value-less defines
only when true (e.g., if val is True then output "`#define` OLED_SCREEN" and skip
when False) or consistently emit "1"/"0" integers (e.g., "`#define` OLED_SCREEN 1"
or "0"); apply this change to the boolean symbols referenced in the codebase
such as OLED_SCREEN, HAS_BACKLIGHT_COLOR, STATUS_LEDS, LCD_HORIZONTAL_INVERT,
and LCD_VERTICAL_INVERT by testing val's truthiness and emitting the appropriate
form.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@companion/src/firmwares/boardjson.cpp`:
- Around line 1229-1235: The loader currently populates display fields but omits
the new lcd_vertical_invert flag; add parsing for
o.value("lcd_vertical_invert").toBool() and assign it to the display struct
(e.g. set display.vertical_invert or display.lcd_vertical_invert depending on
the existing field name in the Display struct) alongside the other assignments
(display.w, display.h, display.phys_w, display.phys_h, display.depth,
display.color, display.oled) so the companion stays in sync with the migrated
board schema.
- Around line 1247-1250: The assignment to cfs_led_strip_length is wrong: it's
storing a boolean (toInt() > 0) instead of the actual length, causing cfs.groups
to be computed as 0; change the line that defines cfs_led_strip_length to
capture the integer length (int cfs_led_strip_length =
o.value("cfs_led_strip_length").toInt();) and keep the existing logic that
computes cfs.groups using cfs_led_strip_length and cfs_leds_per_switch, ensuring
cfs.rgb_led is set from cfs.groups as before.

In `@radio/src/boards/hw_defs/pa01.json`:
- Line 306: The led_strip_gpio value uses an octal-style integer literal; change
the pin argument in the JSON from "GPIO_PIN(GPIOF, 06)" to use a decimal literal
(e.g., "GPIO_PIN(GPIOF, 6)") so GPIO_PIN/ GPIOF evaluation is consistent with
other entries and avoids octal parsing issues; update the entry named
led_strip_gpio accordingly.

In `@radio/src/boards/hw_defs/tx15.json`:
- Around line 337-340: The backlight timer is TIM1 so the backlight_timer_freq
must use the APB2 timer domain instead of the APB1 expression; update the value
of backlight_timer_freq (currently "(PERI1_FREQUENCY * TIMER_MULT_APB1)") to use
the APB2 clock symbols (e.g. "PERI2_FREQUENCY * TIMER_MULT_APB2") so TIM1
references the correct APB2 timer frequency.

In `@radio/src/boards/hw_defs/tx16smk3.json`:
- Around line 451-454: The backlight timer TIM1 is an APB2 peripheral but the
JSON uses the APB1 clock expression; update the backlight_timer_freq value to
use the APB2 timer clock expression instead of "(PERI1_FREQUENCY *
TIMER_MULT_APB1)". Replace that string with the equivalent APB2 expression (e.g.
use PERI2_FREQUENCY and TIMER_MULT_APB2) so backlight_timer = "TIM1" has
backlight_timer_freq matching APB2.

In `@radio/src/boards/hw_defs/x9d.json`:
- Around line 353-358: The hardware definition for X9D is missing the
has_int_module_support flag which causes generated settings to omit built-in RF
module support; add "has_int_module_support": true to the "hardware" object in
x9d.json (alongside has_ext_module_support, sport_max_baudrate, cpu, cpu_type)
so the target correctly recognizes internal-module support.

In `@radio/src/boards/hw_defs/x9d`+.json:
- Around line 367-372: The hardware block for X9D+ removed the internal-module
flag which alters generated capabilities; restore the internal module support by
adding "has_int_module_support": true back into the same "hardware" object (next
to "has_ext_module_support") so X9D+ retains its built-in RF/internal module
paths.

In `@radio/src/boards/hw_defs/x9d`+2019.json:
- Around line 361-366: The hardware definition for the X9D+ 2019 JSON removed
the internal module flag; restore the "has_int_module_support" property in the
"hardware" object of x9d+2019.json (add "has_int_module_support": true) so the
generated capabilities include internal RF support for the X9D+ 2019 target.

In `@radio/src/boards/hw_defs/x9e.json`:
- Around line 559-564: The hardware block for X9E omitted the internal-module
flag, which breaks generated capabilities; update the "hardware" object in
x9e.json (where "has_ext_module_support", "sport_max_baudrate", "cpu", and
"cpu_type" are defined) to include "has_int_module_support": true so the target
correctly advertises its built-in RF hardware and internal-module functionality
is preserved.

---

Nitpick comments:
In `@radio/util/hw_defs/hal_settings.jinja`:
- Around line 10-45: The template currently emits Python True/False text for
boolean HAL fields which can break consumers using `#if` defined(...) checks;
update the hal_settings.jinja generation so booleans are robust: either
(preferred) emit value-less defines only when true (e.g., if val is True then
output "`#define` OLED_SCREEN" and skip when False) or consistently emit "1"/"0"
integers (e.g., "`#define` OLED_SCREEN 1" or "0"); apply this change to the
boolean symbols referenced in the codebase such as OLED_SCREEN,
HAS_BACKLIGHT_COLOR, STATUS_LEDS, LCD_HORIZONTAL_INVERT, and LCD_VERTICAL_INVERT
by testing val's truthiness and emitting the appropriate form.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: f8c01218-433e-443b-a2e7-e38db07e594c

📥 Commits

Reviewing files that changed from the base of the PR and between 00d7544 and 623c434.

📒 Files selected for processing (82)
  • cmake/Macros.cmake
  • companion/src/firmwares/boardjson.cpp
  • radio/src/CMakeLists.txt
  • radio/src/boards/generic_stm32/CMakeLists.txt
  • radio/src/boards/generic_stm32/rgb_leds.cpp
  • radio/src/boards/hw_defs/boxer.json
  • radio/src/boards/hw_defs/bumblebee.json
  • radio/src/boards/hw_defs/commando8.json
  • radio/src/boards/hw_defs/el18.json
  • radio/src/boards/hw_defs/f16.json
  • radio/src/boards/hw_defs/gx12.json
  • radio/src/boards/hw_defs/lr3pro.json
  • radio/src/boards/hw_defs/mt12.json
  • radio/src/boards/hw_defs/nb4p.json
  • radio/src/boards/hw_defs/nv14.json
  • radio/src/boards/hw_defs/pa01.json
  • radio/src/boards/hw_defs/pl18.json
  • radio/src/boards/hw_defs/pl18ev.json
  • radio/src/boards/hw_defs/pl18u.json
  • radio/src/boards/hw_defs/pocket.json
  • radio/src/boards/hw_defs/st16.json
  • radio/src/boards/hw_defs/t12.json
  • radio/src/boards/hw_defs/t12max.json
  • radio/src/boards/hw_defs/t14.json
  • radio/src/boards/hw_defs/t15.json
  • radio/src/boards/hw_defs/t15pro.json
  • radio/src/boards/hw_defs/t16.json
  • radio/src/boards/hw_defs/t18.json
  • radio/src/boards/hw_defs/t20.json
  • radio/src/boards/hw_defs/t20v2.json
  • radio/src/boards/hw_defs/t8.json
  • radio/src/boards/hw_defs/tlite.json
  • radio/src/boards/hw_defs/tpro.json
  • radio/src/boards/hw_defs/tpros.json
  • radio/src/boards/hw_defs/tprov2.json
  • radio/src/boards/hw_defs/tx12.json
  • radio/src/boards/hw_defs/tx12mk2.json
  • radio/src/boards/hw_defs/tx15.json
  • radio/src/boards/hw_defs/tx16s.json
  • radio/src/boards/hw_defs/tx16smk3.json
  • radio/src/boards/hw_defs/v12.json
  • radio/src/boards/hw_defs/v14.json
  • radio/src/boards/hw_defs/v16.json
  • radio/src/boards/hw_defs/x10.json
  • radio/src/boards/hw_defs/x10express.json
  • radio/src/boards/hw_defs/x12s.json
  • radio/src/boards/hw_defs/x7.json
  • radio/src/boards/hw_defs/x7access.json
  • radio/src/boards/hw_defs/x9d+.json
  • radio/src/boards/hw_defs/x9d+2019.json
  • radio/src/boards/hw_defs/x9d.json
  • radio/src/boards/hw_defs/x9e.json
  • radio/src/boards/hw_defs/x9lite.json
  • radio/src/boards/hw_defs/x9lites.json
  • radio/src/boards/hw_defs/xlite.json
  • radio/src/boards/hw_defs/xlites.json
  • radio/src/boards/hw_defs/zorro.json
  • radio/src/bootloader/CMakeLists.txt
  • radio/src/gui/212x64/radio_setup.cpp
  • radio/src/gui/common/stdlcd/feature_control.h
  • radio/src/hal/CMakeLists.txt
  • radio/src/lua/CMakeLists.txt
  • radio/src/lua/api_general.cpp
  • radio/src/storage/yaml/CMakeLists.txt
  • radio/src/targets/common/arm/stm32/CMakeLists.txt
  • radio/src/targets/common/arm/stm32/mixer_scheduler_driver.cpp
  • radio/src/targets/common/arm/stm32/timers_driver.cpp
  • radio/src/targets/horus/hal.h
  • radio/src/targets/pa01/hal.h
  • radio/src/targets/pl18/CMakeLists.txt
  • radio/src/targets/pl18/hal.h
  • radio/src/targets/simu/CMakeLists.txt
  • radio/src/targets/st16/hal.h
  • radio/src/targets/stm32h7s78-dk/hal.h
  • radio/src/targets/t15pro/hal.h
  • radio/src/targets/taranis/CMakeLists.txt
  • radio/src/targets/taranis/hal.h
  • radio/src/targets/tx15/hal.h
  • radio/src/targets/tx16smk3/hal.h
  • radio/util/hw_defs/generator.py
  • radio/util/hw_defs/hal_settings.jinja
  • radio/util/hw_defs/models.py
💤 Files with no reviewable changes (7)
  • radio/src/hal/CMakeLists.txt
  • radio/src/targets/pl18/CMakeLists.txt
  • radio/src/gui/common/stdlcd/feature_control.h
  • radio/src/targets/taranis/CMakeLists.txt
  • radio/src/lua/CMakeLists.txt
  • radio/src/storage/yaml/CMakeLists.txt
  • radio/src/bootloader/CMakeLists.txt

Comment on lines +1229 to +1235
display.w = o.value("lcd_w").toInt();
display.h = o.value("lcd_h").toInt();
display.phys_w = o.value("lcd_phys_w").toInt();
display.phys_h = o.value("lcd_phys_h").toInt();
display.depth = o.value("lcd_depth").toInt();
display.color = display.depth == 16 ? 1 : 0;
display.oled = o.value("oled_screen").toBool();
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot May 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Parse lcd_vertical_invert with the rest of the display schema.

zorro.json now defines this flag, but this loader still drops it. That leaves companion out of sync with the migrated board schema for vertically inverted LCDs.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@companion/src/firmwares/boardjson.cpp` around lines 1229 - 1235, The loader
currently populates display fields but omits the new lcd_vertical_invert flag;
add parsing for o.value("lcd_vertical_invert").toBool() and assign it to the
display struct (e.g. set display.vertical_invert or display.lcd_vertical_invert
depending on the existing field name in the Display struct) alongside the other
assignments (display.w, display.h, display.phys_w, display.phys_h,
display.depth, display.color, display.oled) so the companion stays in sync with
the migrated board schema.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Irrelevant. Not used by companion.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@philmoz, understood — since lcd_vertical_invert has no use in the companion, there's no need to parse it. Thanks for the clarification.

Comment thread companion/src/firmwares/boardjson.cpp Outdated
Comment thread radio/src/boards/hw_defs/pa01.json Outdated
Comment on lines +337 to +340
"backlight_timer": "TIM1",
"backlight_timer_channel": "LL_TIM_CHANNEL_CH3",
"backlight_gpio_af": "GPIO_AF1",
"backlight_timer_freq": "(PERI1_FREQUENCY * TIMER_MULT_APB1)"
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot May 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use the APB2 clock expression for the TIM1 backlight timer.

backlight_timer is TIM1, so backlight_timer_freq should follow the APB2 timer domain, not APB1. This happens to work today because both domains are equal here, but it bakes in the wrong dependency.

Proposed fix
   "backlight": {
     "backlight_gpio": "GPIO_PIN(GPIOA, 10)",
     "backlight_timer": "TIM1",
     "backlight_timer_channel": "LL_TIM_CHANNEL_CH3",
     "backlight_gpio_af": "GPIO_AF1",
-    "backlight_timer_freq": "(PERI1_FREQUENCY * TIMER_MULT_APB1)"
+    "backlight_timer_freq": "(PERI2_FREQUENCY * TIMER_MULT_APB2)"
   },
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@radio/src/boards/hw_defs/tx15.json` around lines 337 - 340, The backlight
timer is TIM1 so the backlight_timer_freq must use the APB2 timer domain instead
of the APB1 expression; update the value of backlight_timer_freq (currently
"(PERI1_FREQUENCY * TIMER_MULT_APB1)") to use the APB2 clock symbols (e.g.
"PERI2_FREQUENCY * TIMER_MULT_APB2") so TIM1 references the correct APB2 timer
frequency.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will not change. Copied existing value from hal.h.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understood — preserving the value from hal.h is reasonable for this migration. Noted that on this board both APB1 and APB2 run at the same frequency, so there's no functional difference.

Comment on lines +451 to +454
"backlight_timer": "TIM1",
"backlight_timer_channel": "LL_TIM_CHANNEL_CH3",
"backlight_gpio_af": "GPIO_AF1",
"backlight_timer_freq": "(PERI1_FREQUENCY * TIMER_MULT_APB1)"
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot May 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use the APB2 clock expression for the TIM1 backlight timer.

TIM1 should be driven from the APB2 timer clock. Keeping the APB1 expression here makes this board definition drift-prone if those clock settings ever stop matching.

Proposed fix
   "backlight": {
     "backlight_gpio": "GPIO_PIN(GPIOA, 10)",
     "backlight_timer": "TIM1",
     "backlight_timer_channel": "LL_TIM_CHANNEL_CH3",
     "backlight_gpio_af": "GPIO_AF1",
-    "backlight_timer_freq": "(PERI1_FREQUENCY * TIMER_MULT_APB1)"
+    "backlight_timer_freq": "(PERI2_FREQUENCY * TIMER_MULT_APB2)"
   },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"backlight_timer": "TIM1",
"backlight_timer_channel": "LL_TIM_CHANNEL_CH3",
"backlight_gpio_af": "GPIO_AF1",
"backlight_timer_freq": "(PERI1_FREQUENCY * TIMER_MULT_APB1)"
"backlight_timer": "TIM1",
"backlight_timer_channel": "LL_TIM_CHANNEL_CH3",
"backlight_gpio_af": "GPIO_AF1",
"backlight_timer_freq": "(PERI2_FREQUENCY * TIMER_MULT_APB2)"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@radio/src/boards/hw_defs/tx16smk3.json` around lines 451 - 454, The backlight
timer TIM1 is an APB2 peripheral but the JSON uses the APB1 clock expression;
update the backlight_timer_freq value to use the APB2 timer clock expression
instead of "(PERI1_FREQUENCY * TIMER_MULT_APB1)". Replace that string with the
equivalent APB2 expression (e.g. use PERI2_FREQUENCY and TIMER_MULT_APB2) so
backlight_timer = "TIM1" has backlight_timer_freq matching APB2.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will not change. Copied existing value from hal.h.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@philmoz, understood — preserving the existing hal.h value is reasonable. On this board PERI1_FREQUENCY * TIMER_MULT_APB1 and PERI2_FREQUENCY * TIMER_MULT_APB2 evaluate identically (both 240 MHz), so there is no functional difference. I'll drop the suggestion.

Comment on lines 353 to +358
"hardware": {
"has_audio_mute": 0,
"has_bling_leds": 0,
"has_ext_module_support": 1,
"has_int_module_support": 0,
"has_ext_module_support": true,
"sport_max_baudrate": 400000,
"surface": 0,
"cpu": "STM32F205xE",
"cpu_type": "STM32F2"
},
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot May 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add back has_int_module_support for X9D.

X9D is also an internal-module radio. Leaving this flag out changes the generated settings for the target and can disable built-in RF module support.

Suggested fix
   "hardware": {
     "has_ext_module_support": true,
+    "has_int_module_support": true,
     "sport_max_baudrate": 400000,
     "cpu": "STM32F205xE",
     "cpu_type": "STM32F2"
   },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"hardware": {
"has_audio_mute": 0,
"has_bling_leds": 0,
"has_ext_module_support": 1,
"has_int_module_support": 0,
"has_ext_module_support": true,
"sport_max_baudrate": 400000,
"surface": 0,
"cpu": "STM32F205xE",
"cpu_type": "STM32F2"
},
"hardware": {
"has_ext_module_support": true,
"has_int_module_support": true,
"sport_max_baudrate": 400000,
"cpu": "STM32F205xE",
"cpu_type": "STM32F2"
},
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@radio/src/boards/hw_defs/x9d.json` around lines 353 - 358, The hardware
definition for X9D is missing the has_int_module_support flag which causes
generated settings to omit built-in RF module support; add
"has_int_module_support": true to the "hardware" object in x9d.json (alongside
has_ext_module_support, sport_max_baudrate, cpu, cpu_type) so the target
correctly recognizes internal-module support.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incorrect. Only used in companion to control UI.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@philmoz, understood — has_int_module_support is a companion UI control flag and has no effect on firmware RF module support. My concern was incorrect.


✏️ Learnings added
Learnt from: philmoz
Repo: EdgeTX/edgetx PR: 7411
File: radio/src/boards/hw_defs/x9d.json:353-358
Timestamp: 2026-05-30T01:34:50.840Z
Learning: In EdgeTX (repository: EdgeTX/edgetx), the `has_int_module_support` flag in board JSON hardware definitions (e.g., `radio/src/boards/hw_defs/x9d.json`) is only used by the companion application to control UI display. It does not affect firmware behavior or built-in RF module support. Omitting it from a board's JSON is valid and does not disable any firmware functionality.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

Comment on lines 367 to +372
"hardware": {
"has_audio_mute": 0,
"has_bling_leds": 0,
"has_ext_module_support": 1,
"has_int_module_support": 0,
"has_ext_module_support": true,
"sport_max_baudrate": 400000,
"surface": 0,
"cpu": "STM32F205xE",
"cpu_type": "STM32F2"
},
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot May 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Keep has_int_module_support for X9D+.

This target has built-in RF hardware. Dropping has_int_module_support from the migrated hardware block changes the generated capability set and can disable internal module paths for this radio.

Suggested fix
   "hardware": {
     "has_ext_module_support": true,
+    "has_int_module_support": true,
     "sport_max_baudrate": 400000,
     "cpu": "STM32F205xE",
     "cpu_type": "STM32F2"
   },
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@radio/src/boards/hw_defs/x9d`+.json around lines 367 - 372, The hardware
block for X9D+ removed the internal-module flag which alters generated
capabilities; restore the internal module support by adding
"has_int_module_support": true back into the same "hardware" object (next to
"has_ext_module_support") so X9D+ retains its built-in RF/internal module paths.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incorrect. Only used in companion to control UI.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understood, thanks for the correction — has_int_module_support only drives companion UI and has no impact on firmware capability generation. My concern was invalid.


✏️ Learnings added
Learnt from: philmoz
Repo: EdgeTX/edgetx PR: 7411
File: radio/src/boards/hw_defs/x9d+.json:367-372
Timestamp: 2026-05-30T01:34:56.654Z
Learning: In the EdgeTX codebase (`radio/src/boards/hw_defs/*.json`), the `has_int_module_support` field in the `hardware` object of board JSON definitions is only used by the companion application to control UI display. It does not affect firmware build-time capability generation or internal module paths in the firmware itself.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

Comment on lines 361 to +366
"hardware": {
"has_audio_mute": 0,
"has_bling_leds": 0,
"has_ext_module_support": 1,
"has_int_module_support": 0,
"has_ext_module_support": true,
"sport_max_baudrate": 400000,
"surface": 0,
"cpu": "STM32F407xE",
"cpu_type": "STM32F4"
},
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot May 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Restore has_int_module_support for X9D+ 2019.

This board has a built-in internal module. Omitting has_int_module_support here changes the generated hardware capabilities and can break internal RF support on the 2019 target.

Suggested fix
   "hardware": {
     "has_ext_module_support": true,
+    "has_int_module_support": true,
     "sport_max_baudrate": 400000,
     "cpu": "STM32F407xE",
     "cpu_type": "STM32F4"
   },
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@radio/src/boards/hw_defs/x9d`+2019.json around lines 361 - 366, The hardware
definition for the X9D+ 2019 JSON removed the internal module flag; restore the
"has_int_module_support" property in the "hardware" object of x9d+2019.json (add
"has_int_module_support": true) so the generated capabilities include internal
RF support for the X9D+ 2019 target.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incorrect. Only used in companion to control UI.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@philmoz, understood — has_int_module_support is only consumed by companion for UI purposes, not by the firmware build. My concern was incorrect. Thanks for the clarification.


✏️ Learnings added
Learnt from: philmoz
Repo: EdgeTX/edgetx PR: 7411
File: radio/src/boards/hw_defs/x9d+2019.json:361-366
Timestamp: 2026-05-30T01:35:03.736Z
Learning: In the EdgeTX codebase (radio/src/boards/hw_defs/*.json), the `has_int_module_support` field in the `hardware` section of board JSON files is only used by the companion application to control UI display. It does not affect firmware build capabilities or internal RF module support at the firmware level.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

Comment on lines 559 to +564
"hardware": {
"has_audio_mute": 0,
"has_bling_leds": 0,
"has_ext_module_support": 1,
"has_int_module_support": 0,
"has_ext_module_support": true,
"sport_max_baudrate": 400000,
"surface": 0,
"cpu": "STM32F407xE",
"cpu_type": "STM32F4"
},
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot May 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Preserve has_int_module_support on X9E.

X9E has built-in RF hardware as well. Omitting the internal-module flag here changes the generated capability set and can break internal module functionality for this target.

Suggested fix
   "hardware": {
     "has_ext_module_support": true,
+    "has_int_module_support": true,
     "sport_max_baudrate": 400000,
     "cpu": "STM32F407xE",
     "cpu_type": "STM32F4"
   },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"hardware": {
"has_audio_mute": 0,
"has_bling_leds": 0,
"has_ext_module_support": 1,
"has_int_module_support": 0,
"has_ext_module_support": true,
"sport_max_baudrate": 400000,
"surface": 0,
"cpu": "STM32F407xE",
"cpu_type": "STM32F4"
},
"hardware": {
"has_ext_module_support": true,
"has_int_module_support": true,
"sport_max_baudrate": 400000,
"cpu": "STM32F407xE",
"cpu_type": "STM32F4"
},
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@radio/src/boards/hw_defs/x9e.json` around lines 559 - 564, The hardware block
for X9E omitted the internal-module flag, which breaks generated capabilities;
update the "hardware" object in x9e.json (where "has_ext_module_support",
"sport_max_baudrate", "cpu", and "cpu_type" are defined) to include
"has_int_module_support": true so the target correctly advertises its built-in
RF hardware and internal-module functionality is preserved.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incorrect. Only used in companion to control UI.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@philmoz, understood — has_int_module_support is companion-side only and doesn't affect firmware behavior. My comment was incorrect. I already have this recorded in my knowledge base from an earlier note on this PR, so I won't flag it again.


🧠 Learnings used
Learnt from: philmoz
Repo: EdgeTX/edgetx PR: 7411
File: radio/src/boards/hw_defs/x9d.json:353-358
Timestamp: 2026-05-30T01:34:50.840Z
Learning: In this repo’s EdgeTX board hardware JSON definitions (e.g., files under radio/src/boards/hw_defs/), the `has_int_module_support` flag is used only by the companion application to decide UI display. It does not change firmware behavior or whether any built-in RF module support is available. During code review, it’s valid for a board JSON to omit `has_int_module_support`; do not treat its absence as disabling firmware functionality.

3djc
3djc previously approved these changes May 30, 2026
Copy link
Copy Markdown
Collaborator

@3djc 3djc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall I'm for it. The only drawback is that it starts to make the addition of new radio very complex, since we have no heleprs or validation of those .json. Before I could add it to 2.12, and use the generated json as a reference point, few additions where needed. This starts to make the task very complex

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

Labels

compilation Related to compiling the firmware and firmware options house keeping 🧹 Cleanup of code and house keeping

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants