Skip to content

feat(radio): add gyro support for HelloRadio V16#7232

Merged
pfeerick merged 8 commits into
EdgeTX:mainfrom
gismo2004:v16_gyro
Jun 23, 2026
Merged

feat(radio): add gyro support for HelloRadio V16#7232
pfeerick merged 8 commits into
EdgeTX:mainfrom
gismo2004:v16_gyro

Conversation

@gismo2004

@gismo2004 gismo2004 commented Mar 29, 2026

Copy link
Copy Markdown
Contributor

Summary of changes:

This adds gyro support for HelloRadio V16. Since I was not able to find documentation about the used chip, I took the code used by @helloradiosky as the basis.

The gyro is working as expected:
PXL_20260329_133347540

Let me know if this needs to be done differently or if it is even wanted.

Summary by CodeRabbit

New Features

  • Added ICM42627 inertial measurement unit (IMU) driver with gyroscope and accelerometer support for motion sensing
  • Implemented hardware-version-aware IMU driver selection for improved device compatibility
  • Enhanced sensor initialization with automatic device detection and validation

@richardclli

Copy link
Copy Markdown
Member

Nice, you start contributing. 👏

@pfeerick pfeerick self-requested a review May 5, 2026 05:05
@pfeerick pfeerick added hardware support enhancement ✨ New feature or request labels Jun 22, 2026
@pfeerick pfeerick added this to the 2.12.3 milestone Jun 22, 2026
@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a new ICM42627 IMU driver (icm42627.h/.cpp) with I2C register helpers, an initialization sequence (WHO_AM_I verification, reset, multi-register configuration, bank switching), and a burst-read routine with axis remapping. The Horus board target is updated to select ICM42627 vs LSM6DS at compile time via RADIO_V16, with matching HAL I2C bus/address macros and CMakeLists build registration.

Changes

ICM42627 IMU Driver for Horus/RADIO_V16

Layer / File(s) Summary
Register map header and I2C helpers
radio/src/drivers/icm42627.h, radio/src/drivers/icm42627.cpp
New header defines ICM42627 register/value constants and exports imu_icm42627_driver. Driver source adds shared I2C state, timing constants, and static writeReg/readReg/waitReady helpers.
Init and read implementation
radio/src/drivers/icm42627.cpp
gyro42627Init performs WHO_AM_I probe, reset, sequenced register writes with delays, bank switching, and a post-reset re-check. gyro42627Read does a burst read, parses big-endian accel/gyro fields, applies axis remapping, and fills etx_imu_data_t. imu_icm42627_driver constant is exported.
Horus target wiring and build
radio/src/targets/horus/hal.h, radio/src/targets/horus/board.cpp, radio/src/targets/horus/CMakeLists.txt
Adds #elif defined(RADIO_V16) HAL branch setting IMU_I2C_BUS/IMU_I2C_ADDRESS. gyroInit() selects imu_icm42627_driver or imu_lsm6ds_driver at compile time. icm42627.cpp added to the board object library.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: adding gyro support for HelloRadio V16, which aligns with the changeset's primary objective.
Description check ✅ Passed The description includes a summary of changes but lacks structure; it is missing the 'Fixes #' section from the template and uses informal tone ('Let me know if this needs to be done differently').
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@pfeerick

Copy link
Copy Markdown
Member

@gismo2004 Sorry for the delay on this one. Can you double check with the firmware built by github @ https://github.com/EdgeTX/edgetx/actions/runs/27930666702 once it is done. I've not made any changes, only rebased the code on main and there weren't any conflicts. It is just that my V16 doesn't show the IMU, so either it doesn't have one, isn't working, or a different part was used (entirely possible, due to gyro supply chain shortages) - the later option would mean it needs to be able to check for more than just the ICM42627.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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 `@radio/src/drivers/icm42627.cpp`:
- Around line 95-97: The reset command write failure in the ICM42627
initialization is only being logged via TRACE but the init continues execution,
leaving the device in an undefined state. Instead of continuing after a failed
write_cmd call with ICM42627_DEVICE_CONFIG_REG and ICM42627_RESET, the
initialization should fail fast by returning an error code (similar to how
subsequent config writes are handled), ensuring the device is only considered
successfully initialized when the reset command actually succeeds.
🪄 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: 658f24f3-6939-44ad-b9bf-771ebd98e5a4

📥 Commits

Reviewing files that changed from the base of the PR and between 94f5d50 and 5abaeab.

📒 Files selected for processing (5)
  • radio/src/drivers/icm42627.cpp
  • radio/src/drivers/icm42627.h
  • radio/src/targets/horus/CMakeLists.txt
  • radio/src/targets/horus/board.cpp
  • radio/src/targets/horus/hal.h

Comment on lines +95 to +97
if (write_cmd(ICM42627_DEVICE_CONFIG_REG, ICM42627_RESET) < 0) {
TRACE("ICM42627: failed to write reset command");
}

Copy link
Copy Markdown

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

Fail init when the reset command write is rejected.

At Line 95, a failed reset write is logged but init continues. This can report successful init with an undefined device state; it should fail fast like the subsequent config writes.

Suggested fix
   if (write_cmd(ICM42627_DEVICE_CONFIG_REG, ICM42627_RESET) < 0) {
     TRACE("ICM42627: failed to write reset command");
+    return -1;
   }
📝 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
if (write_cmd(ICM42627_DEVICE_CONFIG_REG, ICM42627_RESET) < 0) {
TRACE("ICM42627: failed to write reset command");
}
if (write_cmd(ICM42627_DEVICE_CONFIG_REG, ICM42627_RESET) < 0) {
TRACE("ICM42627: failed to write reset command");
return -1;
}
🤖 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/drivers/icm42627.cpp` around lines 95 - 97, The reset command write
failure in the ICM42627 initialization is only being logged via TRACE but the
init continues execution, leaving the device in an undefined state. Instead of
continuing after a failed write_cmd call with ICM42627_DEVICE_CONFIG_REG and
ICM42627_RESET, the initialization should fail fast by returning an error code
(similar to how subsequent config writes are handled), ensuring the device is
only considered successfully initialized when the reset command actually
succeeds.

@gismo2004

Copy link
Copy Markdown
Contributor Author

Yep, I will give it a go when I am back home from work!

@gismo2004

Copy link
Copy Markdown
Contributor Author

PXL_20260622_162623221.jpg

PXL_20260622_162547054.jpg

Also works for me... Can you check your gyro chip if there is something written on it?

@gismo2004

Copy link
Copy Markdown
Contributor Author

@helloradiosky can you confirm that there are different gyro chip types for the V16?

@helloradiosky

Copy link
Copy Markdown
Contributor

@helloradiosky can you confirm that there are different gyro chip types for the V16?

@gismo2004 The gyroscope in V16 has always used the ICM42627 chip, but in the future, it may be changed due to unstable chip supply.

@helloradiosky

Copy link
Copy Markdown
Contributor

@gismo2004 Sorry for the delay on this one. Can you double check with the firmware built by github @ https://github.com/EdgeTX/edgetx/actions/runs/27930666702 once it is done. I've not made any changes, only rebased the code on main and there weren't any conflicts. It is just that my V16 doesn't show the IMU, so either it doesn't have one, isn't working, or a different part was used (entirely possible, due to gyro supply chain shortages) - the later option would mean it needs to be able to check for more than just the ICM42627.

@pfeerick Thank you very much, V16 uses ICM42627, and it has not changed so far. I will test it later.

@philmoz

philmoz commented Jun 22, 2026

Copy link
Copy Markdown
Collaborator

Did some V16's ship without it?

Neither of the V16 radios I have show the gyro with this build.

@helloradiosky

Copy link
Copy Markdown
Contributor

Did some V16's ship without it?

Neither of the V16 radios I have show the gyro with this build.

The earliest prototypes might not have had the gyroscope firmware installed since the firmware did not yet support the IMU, although the hardware was supported

@philmoz

philmoz commented Jun 23, 2026

Copy link
Copy Markdown
Collaborator

Did some V16's ship without it?
Neither of the V16 radios I have show the gyro with this build.

The earliest prototypes might not have had the gyroscope firmware installed since the firmware did not yet support the IMU, although the hardware was supported

I installed the firmware from this PR - no IMU showing in the debug page for either radio.

@helloradiosky

Copy link
Copy Markdown
Contributor

Did some V16's ship without it?
Neither of the V16 radios I have show the gyro with this build.

The earliest prototypes might not have had the gyroscope firmware installed since the firmware did not yet support the IMU, although the hardware was supported

I installed the firmware from this PR - no IMU showing in the debug page for either radio.

I'm very sorry, I will come later to test and see what's going on.

@helloradiosky

Copy link
Copy Markdown
Contributor

I tested it and confirmed that the edgetx main branch does not have a gyroscope, likely because the code has not been added.
https://github.com/gismo2004/edgetx/tree/v16_gyro This PR is fine, the testing results are great, and I will also test and improve these features as soon as possible recently. Thank you for your support

@helloradiosky

helloradiosky commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

@gismo2004
Thank you very much for sending support, I tested it and it works very well. Later, I changed it to multi-device support mode. Here, I need to thank @3djc for their good method, which made multi-device support possible.

static const etx_imu_t _imu_candidates[] = {
#if defined(IMU_ICM4207C)
  { &imu_icm42607_driver, IMU_I2C_BUS, ICM426xx_I2C_BASE_ADDR },
  { &imu_icm42607_driver, IMU_I2C_BUS, ICM426xx_I2C_BASE_ADDR + 1 },
#endif
#if defined(IMU_SC7U22)
  { &imu_sc7u22_driver, IMU_I2C_BUS, SC7U22_I2C_BASE_ADDR },
  { &imu_sc7u22_driver, IMU_I2C_BUS, SC7U22_I2C_BASE_ADDR + 1 },
#endif
};

@pfeerick

Copy link
Copy Markdown
Member

Ok, that is weird... I checked both my production V16 and early development board, and they both seem to have the ICM42627 populated. So I dug into the gyro code a little more again to make it show diagnostic info and allow me to reset it via cli, and I then realised it was working (as in, giving values, working in the mixer) but not showing on the hardware debug screen. So I restarted the hardset after that, and it has worked perfectly since (debug screen also) with the PR firmware. So I am none the wiser, other than to think maybe something was stuck in the gyro registers/detection (or it could be the first start after a DFU flash causing issues again), but now it is working as expected.

So, since we know @gismo2004 has it working, and ICM42627 is the only gyro used at present, this will do for now. I think later down the track we need to tweak how the IMUs are done generally for horus targets, as it is a bit all over the place atm.

IMG_0328 (Medium) IMG_0329 (Medium)

@pfeerick pfeerick merged commit 66463ec into EdgeTX:main Jun 23, 2026
40 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants