Skip to content

test: 2.12.5 release candidate (backport-2.12.5 + #7415) - #28

Closed
pfeerick wants to merge 46 commits into
2.12from
pfeerick/backport-2.12.5-pr7415
Closed

pfeerick wants to merge 46 commits into
2.12from
pfeerick/backport-2.12.5-pr7415

Conversation

@pfeerick

@pfeerick pfeerick commented Oct 3, 2026

Copy link
Copy Markdown
Owner

Test build only, do not merge.

This is the 2.12.5 release candidate: the backport branch pfeerick/backport-2.12.5 (EdgeTX#7817) plus a squash of EdgeTX#7415 (stm32 flash hang/verify fixes) on top. CI builds what will effectively be the 2.12.5 release, minus the version/timestamp differences, so the firmware can be tested repeatably.

If EdgeTX#7415 or the backport branch changes, rebuild this branch to match.

🤖 Generated with Claude Code

pfeerick and others added 30 commits September 24, 2026 02:27
…sx to macos (EdgeTX#7754)

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
(cherry picked from commit 2e0506b)
Co-authored-by: Kilrah <kilrah@kilrah.xyz>
(cherry picked from commit 7f7d57e)
EdgeTX#7782)

Co-authored-by: 3djc <3djc@gh.com>
Co-authored-by: philmoz <phil.a.mitchell@gmail.com>
(cherry picked from commit 710e92d)
(cherry picked from commit d0d5805)

Hand-ported for 2.12: the colorlcd part of upstream changes a
DateNumberEdit class in radio_setup.cpp that only exists on main (it was
added by the main-only refactor EdgeTX#7032). On 2.12, DateTimeWindow still
creates six plain NumberEdit fields and refreshes them from the RTC
itself. The port adds an equivalent DateNumberEdit wrapper to 2.12's
radio_setup.cpp and uses it for those six fields. The wrapper has
upstream's editing logic: while a field is being edited it shows the
value being edited instead of the RTC value, and writes to the RTC only
when editing finishes. The rest of 2.12's DateTimeWindow is unchanged,
including its per-field display handlers. The numberedit.{h,cpp} and
128x64/212x64 hunks applied cleanly.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Not an upstream cherry-pick.

`tools/update-companion-translations.sh` (lupdate -no-obsolete) run on
2.12. The 2.12 .ts files hadn't been refreshed since strings from
features backported to 2.12 were added (e.g. new radios such as GX15
and Commando 14, key lock, charge while radio on), so they had no
entries for those strings. That meant translation updates cherry-picked
from main (such as EdgeTX#7772, next) had nowhere to land. main's equivalent
refresh (ae5ce49) can't be cherry-picked because it also covers
main-only strings. This refresh is generated from 2.12's own companion
sources, which are the same here as at the tip of this backport branch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 65bb97d)

Conflicts resolved by hand for 2.12:

- radio/src/translations/i18n/se.h: 2.12's English TR_KEYS_LOCKED_FMT
  is "Keys locked (%s+%s)" (no TR_BW_COL / "to unlock" variant), and
  TR_TOUCH_ENABLED/TR_TOUCH_DISABLED don't exist on 2.12. Translated the
  four key-lock strings using the 2.12 format and left out the two touch
  strings. The rest of the file applied cleanly.
- companion/src/translations/companion_sv.ts: main's .ts was refreshed
  by lupdate (ae5ce49, main-only), so line-based merging failed.
  Merged by message key (context + source + comment) instead, on top of
  the previous commit's 2.12 refresh: applied each translation this
  commit changed to the 2.12 message with the same key. 21 of the 75
  changed messages apply. The other 54 are strings that exist only on
  main (e.g. the LabelsStorageFormat/SdcardFormat storage messages and
  "Disable Keys").

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… are selected (EdgeTX#7756)

Co-authored-by: philmoz <philmoz@users.noreply.github.com>
(cherry picked from commit 60053f7)
(cherry picked from commit ad8822a)

Conflict resolved by hand for 2.12: 2.12's English TR_KEYS_LOCKED_FMT
is "Keys locked (%s+%s)" (no TR_BW_COL / "to unlock" variant), and
TR_TOUCH_ENABLED/TR_TOUCH_DISABLED don't exist on 2.12. Translated
TR_KEYS_LOCKED_FMT using the 2.12 format and left out the two touch
strings. The other four strings (TR_ONE_LOG_PER_DAY, TR_KEY_LOCK_FMT,
TR_KEYS_LOCKED, TR_KEYS_UNLOCKED) are as upstream.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ated UI (EdgeTX#7762)

Co-authored-by: philmoz <philmoz@users.noreply.github.com>
(cherry picked from commit e066572)

Conflicts resolved by hand for 2.12, which still uses the older bitmap
names and layout from before main's EdgeTX#6781 cleanup:

- radio_calibration.cpp: 2.12 includes alpha_stick_{pointer,background}.lbm,
  where main has bmp_radio_stick_*. Removed that include block, as
  upstream does.
- Upstream deletes bitmaps/<res>/bmp_radio_stick_*.png and
  img-src/bmp_radio_stick_*.svg. On 2.12 the same images are
  bitmaps/<res>/default_theme/alpha_stick_*.png and
  img-src/default_theme/alpha_stick_*.svg (picked up by the alpha_*.png
  glob in the bitmaps CMakeLists), so those are deleted instead.
- tools/convert-gfx-list.csv doesn't exist on 2.12 (added by EdgeTX#6781), so
  upstream's edit to it is dropped.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…geTX#7801)

(cherry picked from commit 6fe19b2)

Trivial conflict in menu.h: upstream removes the redundant `class Menu;`
forward declaration next to `class MaskBitmap;`, which 2.12 doesn't
have. Removed `class Menu;` as upstream does. menu.cpp and
menutoolbar.cpp applied cleanly.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 4d2e2a9)

Adapted for 2.12: upstream adds a `Messaging refreshMsg;` member to
ChannelFSCombo that is never used. Messaging is main's publish/subscribe
class (EdgeTX#7032, main-only) and doesn't exist on 2.12, so the member is
left out. Everything else applied as upstream.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
EdgeTX#7777)

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
(cherry picked from commit e794518)
Co-authored-by: philmoz <phil.a.mitchell@gmail.com>
(cherry picked from commit b0eb233)
…dgeTX#7689)

Co-authored-by: Peter Feerick <5500713+pfeerick@users.noreply.github.com>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
(cherry picked from commit e2968ac)
Not an upstream cherry-pick.

Partial port of 9326a20 (EdgeTX#7438, "refactor(cpn): introduce
BoundedString<N> for ModelData string fields", main-only), taking only
its "test harness restore" changes. None of the BoundedString refactor
is included:

- companion/src/tests/conversions.cpp is deleted, as upstream. It
  tested conversion of old binary EEPROM files, which Companion no
  longer supports (storage is YAML-only), and it hasn't compiled since
  EdgeTX#4406 removed GeneralSettings::switchName. That compile error has
  stopped 2.12's gtests-companion target building at all.
- gtests.cpp main() now creates gBoardFactories (identical to
  upstream's hunk). Without it, registering the firmwares dereferences a
  null pointer, which has been latent since EdgeTX#4406.
- The "Run companion unit tests" step (identical to upstream's) goes in
  .github/workflows/linux_cpn.yml after "Setup and Build", since on
  2.12 the Linux Companion job lives there instead of in companion.yml.
  The tests need the board JSON files that the Companion build
  generates, so they run in the same build/native directory.

Together with the next commit (EdgeTX#7744), this lets EdgeTX#7810's flex switch
test build and pass on 2.12.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…th empty hwdefnId (EdgeTX#7744)

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
(cherry picked from commit aa72609)

Brought into 2.12.5 as a prerequisite (milestoned 3.0, not labelled
backport/2.12): with it, every firmware registers its board from the
hw_defs JSON named after its flavour, which EdgeTX#7810's flex switch test
relies on. Clean cherry-pick. Checked locally that each of the 54
firmwares 2.12's Companion registers has a hw_defs JSON from the
Companion build, so this doesn't trigger a "Load Board Hardware
Definition" error at startup.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
(cherry picked from commit f5c13ab)

Conflict resolved by hand for 2.12: 2.12's flex switch count line
lacked HelloRadioSky V16 (main added it in EdgeTX#7501). Took upstream's line
as-is. On 2.12 FLEXSW is also set for TX16S, TX16S MK3, F16, V16 and
MT12, and all five IS_*() helpers exist in 2.12's boards.h, so the list
is correct for 2.12 too (and also fixes the missing V16 flex switches).
The new flex_switches_test.cpp applied cleanly. It relies on the previous
two commits (the companion test harness restore and EdgeTX#7744).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…dgeTX#7814)

Co-authored-by: Peter Feerick <5500713+pfeerick@users.noreply.github.com>
(cherry picked from commit 69d016f)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 61aa7a4)
…t pin (EdgeTX#7828)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit c361497)
… external bay (EdgeTX#7836)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 75e15a0)

Conflicts resolved by hand for 2.12:

- companion/src/firmwares/moduledata.cpp: 2.12 has a different
  surrounding structure and indentation in isAvailable() and
  isProtocolAvailable(), so the hunks didn't merge. Applied upstream's
  three one-line removals directly: PULSES_FLYSKY_AFHDS2A from the
  external-bay protocol list, and MODULE_TYPE_FLYSKY_AFHDS2A from the
  EXTMODSIZE_BOTH and EXTMODSIZE_STD module lists.
- radio/src/gui/gui_common.cpp: 2.12's isExternalModuleAvailable() has
  the same AFHDS3 check twice. As upstream does, the second copy is
  removed along with the AFHDS2 guard, so the function ends exactly as on
  main (one AFHDS3 check, then the unconditional AFHDS2A rejection).

- radio/src/gui/colorlcd/radio/radio_version.cpp: applied cleanly but
  uses Window::setWindowFlag(NO_SCROLL), and NO_SCROLL only exists on
  main (added by EdgeTX#6989). Replaced it with what that flag does on main:
  lv_obj_clear_flag(infoBox->getLvObj(), LV_OBJ_FLAG_SCROLLABLE).

modules_helpers.h and the new tests/modules_helpers.cpp applied
cleanly.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Not an upstream cherry-pick.

Partial port of ed71a38 (EdgeTX#7562, "feat(firmware): add 'user data'
section to model yaml for Lua scripts", milestone 3.0, main-only),
taking only its yaml_tree_walker.{h,cpp} and yaml_parser.cpp hunks,
unchanged:

- yaml_output_string() is no longer static, and is declared in
  yaml_tree_walker.h with a new 'exact' flag (default false, the old
  behaviour; true writes max_len bytes even past a NUL, for
  std::string contents).
- '\' is now written as \x5C, like '"' already is as \x22. 2.12's
  parser already decodes \xNN inside quoted strings, but otherwise drops
  a lone backslash, so a literal '\' didn't survive a round trip.
- The radio parser now accepts lowercase hex in \xNN, and \b \t \n \f
  \r, inside quoted strings. That's what Companion's yaml-cpp writes.
  Without it, a lowercase escape stops the parser and the rest of the
  file isn't loaded.

This is a prerequisite for the next commit (EdgeTX#7831), which writes widget
names, widget option strings and analog labels with
yaml_output_string(). That function escapes bytes >= 0x80 (e.g. UTF-8
text) as \xNN. Companion reads those back as separate characters and
may save C1 code points as lowercase escapes. The parser change makes
2.12 read such files completely, as main does. The garbled UTF-8 text in
Companion itself also happens on main and isn't addressed here. The
rest of EdgeTX#7562 (the Lua user data feature) is not included.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
philmoz and others added 16 commits October 2, 2026 11:24
…option string, switch name, contains certain characters (EdgeTX#7831)

Co-authored-by: Peter Feerick <5500713+pfeerick@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 0b2e470)

Adapted for 2.12 (depends on the previous commit, which exports
yaml_output_string() as on main):

- yaml_datastructs_funcs.cpp: the widget name, widget option string and
  analog label hunks applied as upstream. The w_keyShortcut() /
  w_qmFavorite() hunks are dropped: on 2.12 key shortcuts and quick menu
  favourites are a plain QMPage enum with no app/tool name, so there are
  no user strings to quote and those functions don't exist.
- tests/yaml_strings.cpp: removed the KeyShortcutToolName,
  FavoriteToolName and NonAppShortcutsUnquoted tests, the shortcut part
  of ReadsLegacyUnquotedValues, and the tool-name resets in
  resetStorage(), which all need main's key shortcut API. The widget
  option, screen and topbar widget name, analog label and legacy-model
  tests are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
EdgeTX#7822)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit ebde54c)

Conflict resolved by hand for 2.12: on main, FreeRTOSConfig.h wraps its
declarations in an extern "C" block (added with the main-only FreeRTOS
V11.3.1 update, EdgeTX#6549), and upstream puts the new
timersGetRunTimeCounter() declaration inside it. 2.12's
FreeRTOSConfig.h has no such block, so the declaration has its own
extern "C" guard here. Without it, C++ files using
portGET_RUN_TIME_COUNTER_VALUE() would see a C++-linkage declaration
that conflicts with the extern "C" definition in timers_driver.cpp.
The rest of the header change and the other eight files applied as
upstream. 2.12's FreeRTOS (V11.1.0) provides ulTaskGetIdleRunTimeCounter()
under the same configGENERATE_RUN_TIME_STATS / INCLUDE_xTaskGetIdleTaskHandle
settings.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ieldInfo() switches (EdgeTX#7826)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit c70fb34)

Conflicts resolved by hand for 2.12:

- lua/api_model.cpp: both hunks change main-only code (luadoc and the
  return value of model.setSwitchWarning(), and the model user data
  luadoc from EdgeTX#7562), neither of which exists on 2.12. Dropped.
- tests/lua.cpp: on main the new tests sit next to the insertMix() /
  insertInput() round-trip tests, which aren't on 2.12. Added only the
  four tests from this commit (getSwitchInfo, getFieldInfoSwitches,
  getFieldInfoSensorBeforeSwitch, getSwitchInfoOutOfRange), in the
  same place before testFloatIntegerEquality.
- tests/strhelpers.cpp: on main this file was created by EdgeTX#7711 (a
  main-only refactor) and its existing tests cover strReplaceAll(),
  which 2.12 doesn't have. Created it here with main's header and only
  the tests this commit adds.

curves.cpp, draw_functions.cpp, model_curves.cpp, api_general.cpp,
strhelpers.cpp, switches.cpp and tests/switches.cpp applied cleanly.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 3c5c463)

Trivial conflict resolved for 2.12: upstream adds setValueText() just
before ValueWidget::foreground(). On 2.12 that method is still called
checkEvents() (main renamed it), so the new function goes before
checkEvents() instead. The +/- lines are otherwise identical to
upstream.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: philmoz <phil.a.mitchell@gmail.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Peter Feerick <5500713+pfeerick@users.noreply.github.com>
(cherry picked from commit cc677bd)

Conflicts resolved by hand for 2.12:

- gui/colorlcd/libui/file_browser.{h,cpp}: 2.12's onSelected() /
  onPress() / onPressLong() call getCurrentPath() inline instead of
  through a local 'path' variable, so the hunks didn't merge. The code
  is otherwise the same, so upstream's versions are taken as-is. On
  2.12, getCurrentPath()/getFullPath() are FileBrowser member functions
  rather than the static helpers upstream deletes; they are removed
  here too (upstream's reason applies: they rely on f_getcwd(), which
  is broken on exFAT), along with their declarations. Nothing else
  used them.
- gui/colorlcd/radio/radio_tools.cpp: the surrounding Lua tools code is
  laid out differently on 2.12. Applied upstream's one-line change
  (f_chdir(toolPath) -> etxChdir(toolPath) in run_lua_tool()) directly.

The other 17 files, including the new tests/fs_path.cpp and the Lua
lauxlib.c/liolib.c changes, applied cleanly with the same +/- lines as
upstream.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…dgeTX#7784)

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
(cherry picked from commit d1b2826)
…en setup (EdgeTX#7795)

(cherry picked from commit 5da9f92)

Conflicts resolved by hand for 2.12: on 2.12, SetupTopBarWidgetsPage
and SetupWidgetsPage override deleteLater(bool detach, bool trash) and
handle keys in onEvent(); main overrides deleteLater() and uses the
onPress*() key methods. Applied upstream's change to 2.12's code:

- topbar.{h,cpp}, widgets_setup.{h,cpp}: the deleteLater() overrides
  are removed. Their clean-up (reopening the quick menu page, restoring
  the main view) moves into onCancel() without the storageDirty() call,
  as upstream. 2.12's onEvent() key handling is unchanged.
- storageDirty(EE_MODEL) is now called only when a widget is removed
  (TopBar::removeWidget() and the slot menu's "Remove widget") or added
  (addNewWidget()), as upstream.

screen_setup.cpp (SET_DIRTY() after a layout change) applied cleanly.
The added lines are identical to upstream's; the removed lines differ
only by 2.12's deleteLater() signature.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Peter Feerick <5500713+pfeerick@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit abc2be6)

Conflicts resolved by hand for 2.12:

- translations/i18n/he.h: 2.12's he.h differs from main's in many
  places, so the hunks didn't merge. Merged per #define instead: each
  string this commit changes was applied where 2.12 still had the old
  value (422 strings). Nine changed strings don't exist on 2.12 (their
  English versions aren't in 2.12's en.h either) and are left out:
  TR_BTAUDIO, TR_CONTROL, TR_LAST_CHANNEL, TR_PAIRING, TR_PWM_OUTPUT,
  TR_SF_DISABLE_KEYS, TR_SF_OVERRIDDEN, TR_TOUCH_DISABLED,
  TR_TOUCH_ENABLED. 2.12's English TR_KEYS_LOCKED_FMT is
  "Keys locked (%s+%s)" (no TR_BW_COL / "to unlock" variant), so it's
  translated in that form. Every string's printf placeholders match
  2.12's en.h, and the set of defines is unchanged.
- cfn_sort.cpp: the Hebrew sort table takes upstream's new ordering by
  the Hebrew names, minus FUNC_DISABLE_KEYS (which doesn't exist on
  2.12), and with 2.12's #if defined(OLED_SCREEN) style. It lists the
  same 29 functions as 2.12's previous table, on 30 lines
  (FUNC_BACKLIGHT appears under both the OLED and non-OLED guards).
Squash of the 11 commits on EdgeTX#7415 (still open; head
202172f), for release testing:

* fix(stm32): disable interrupts during flash erase/program to prevent hangs on F4
* fix(stm32): replace broken HAL timeouts with DWT cycle counter during flash erase/program
* fix(stm32f4): clear stale FLASH error flags before erase/program
* fix(boot): report firmware write failures instead of showing success
* fix(senduwing-h750): update flashWrite() declaration to return bool
* fix(bootloader): treat SD read errors as a flash failure
* fix(stm32f4): disable data cache during flash erase/program (ES0206 2.2.15)
* fix(stm32): verify each page after writing it in flashWrite()
* chore(stm32): shorten flash operation timeout to twice the datasheet maximum
* fix(stm32h7): keep interrupts enabled during HAL flash erase/program
* chore(stm32f4): correct reason given for clearing stale FLASH error flags

Port notes for 2.12: the simulator stub change is applied to
simpgmspace.cpp instead of simulib.cpp.

Co-authored-by: 3djc <3djc@gh.com>
Co-authored-by: Peter Feerick <5500713+pfeerick@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@pfeerick pfeerick closed this Oct 4, 2026
@pfeerick pfeerick mentioned this pull request Oct 4, 2026
47 of 49 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants