Add bidirectional DShot ESC telemetry - #11605
Conversation
Ports bidirectional DShot (GCR) telemetry from Betaflight, enabling RPM-based gyro filtering without a dedicated ESC telemetry UART. After each DShot output frame the motor pin is switched to timer input capture mode via per-channel DMA to receive the ESC's GCR-encoded eRPM response. The decoded eRPM feeds the existing RPM filter infrastructure. New settings: - dshot_bidir_enabled: enable bidirectional DShot telemetry - dshot_edt_enabled: enable Extended DShot Telemetry (temperature, voltage, current in addition to eRPM) Changes: - drivers/dshot.c/.h: GCR decode, EDT frame parsing, eRPM-to-RPM conversion, motor frequency LPF (ported from Betaflight, GPLv3) - drivers/pwm_output.c: per-channel DMA direction switching between DShot output and GCR input capture on STM32 (StdPeriph/HAL) and AT32 - sensors/esc_sensor.c/.h: DShot bidir data path into ESC sensor framework (escSensorSetDshotData, escSensorIsActive) - flight/rpm_filter.c: DShot telemetry as frequency source alongside serial ESC sensor path - target/common_post.h: USE_RPM_FILTER enabled for any USE_DSHOT target - fc/fc_init.c: call initDshotTelemetry() at startup; fix RPM filter init condition to accept DShot bidir as a valid source - blackbox/blackbox.c: fix NULL dereference when escSensorGetData() returns NULL; fix uninitialized blackboxSlowState_t comparison - telemetry/srxl.c: replace Betaflight-specific USE_DSHOT_TELEMETRY guards with INAV's USE_DSHOT/USE_ESC_SENSOR; use escSensorGetData() Tested on SPEEDYBEEF405V4 (STM32F405, StdPeriph) with Bluejay ESC firmware. eRPM telemetry confirmed in blackbox; RPM gyro filter updating notch frequencies with motor speed. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Qodo reviews are paused for this user.Troubleshooting steps vary by plan Learn more → On a Teams plan? Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center? |
Branch Targeting SuggestionYou've targeted the
If This is an automated suggestion to help route contributions to the appropriate branch. |
|
Have you had a chance to look at log data. To compare the latency improvement bdshot dynamic notch has over the matrix filter ? Or even over ESC telemetry RPM, to be sure it's working correctly. |
|
@halfmanbear INAV is about to enter the 9.1 release phase. Once that is finished I will conduct some testing. |
|
Thanks for your work in this. Getting it to work is one thing, the impact on performance with everything else on a hexcopter running on a less-capable chip another issue. |
For testing you can flash Bluejay, it is the recommended firmware with all new features for old BLHELI_S |
|
Thanks again for all of your work on this. Sorry it took so long for me to review. Going through your excellent PR, it looks like it mostly matches the plan I had put together but didn't actually implement in full. Since we independently came up with the same design, that might be a hint that it's a good design. :) I could go over various points that look good, but suffice to say - nice work! It is my understanding that on the H7, the D-cache means DMA-written data isn't automatically visible to the CPU without `SCB_InvalidateDCache_by_Addr() being called, so we may need to call that? F7 has the same D-cache, but it's disabled in INAV. I currently see the build fails with: There may be a need to gate this on #if (MCU_FLASH_SIZE > 512), for F722. It's my understanding this won't work in CH1N-CH4N, which is probably okay because it looks no targets use that on the first four outputs (quad motors). But we'd need to keep the unidirectional DShot for hexacopters and octocopters. ┌─────────────────── |
|
A note re F722 for future reference: this feature would add 2,972 bytes of flash. |
…ht#11605 # Conflicts: # src/main/target/common_post.h
|
Current build errors: ggdb3 -DNDEBUG -std=gnu99 -flto=auto -fno-fat-lto-objects -ffunction-sections -fdata-sections -fno-common -mthumb -mcpu=cortex-m4 -march=armv7e-m -mfloat-abi=hard -mfpu=fpv4-sp-d16 -fsingle-precision-constant -Wdouble-promotion -Werror -O2 -Wall -Wextra -Wunsafe-loop-optimizations -Wstrict-prototypes -Werror=switch -MD -MT src/main/target/FF_F35_LIGHTNING/CMakeFiles/WINGFC.elf.dir///drivers/pwm_output.c.obj -MF src/main/target/FF_F35_LIGHTNING/CMakeFiles/WINGFC.elf.dir///drivers/pwm_output.c.obj.d -o src/main/target/FF_F35_LIGHTNING/CMakeFiles/WINGFC.elf.dir///drivers/pwm_output.c.obj -c /home/runner/work/inav/inav/src/main/drivers/pwm_output.c Also: |
|
Just an FYI for contributors: The tentative schedule for INAV 10 is to have a full release in mid December. That means RC2 needs to be in early to mid November, which places INAV 10.0RC1 at September 1. Please plan to have any new features for INAV 10.0 ready for RC1 no later than September 1. After that, 10.1 will follow about six to seven months later. |
dshotDmaStream() is only called from the USE_HAL_DRIVER code paths, but was defined unconditionally with a dead fallback stub, so non-HAL F4 targets (e.g. FF_F35_LIGHTNING) built it with -Werror=unused-function. Scope the definition to USE_HAL_DRIVER to match its call sites.
|
If someone is able, I would appreciate it if someone could run a CPU load check, just to confirm: For a pilot with a bench setup: FC + bidir-capable ESC (BLHeli32, AM32, or Safety
What you need
Steps1. Confirm the ESC is actually reporting telemetry. 2. Run A — bidirectional DShot ON (already the default in this build). 3. Run B — bidirectional DShot OFF (comparison baseline). 4. Restore the setting so the board is back the way it started: What to send back
That's enough for us to compare the |
pwm_output.c called LL_TIM_EnableDMAReq_CCx/LL_TIM_DisableDMAReq_CCx, which don't exist in ST's LL timer driver (only per-channel CC1..CC4 variants are provided). Add local static inline wrappers that set/clear the DIER CCxDE bits directly by mask, matching the equivalent helpers already used internally by timer_impl_hal.c.
…metry settings dshot_bidir_enabled and dshot_edt_enabled were added to settings.yaml but docs/Settings.md was never regenerated, failing CI's update_cli_docs.py check. Ran the generator; purely additive diff, no other drift.
loadDmaBufferDshot() was only defined when USE_DSHOT_DMAR was unset, but pwmCompleteMotorUpdate() also calls it as the per-channel DMA fallback on DMAR targets whenever bidir telemetry is enabled (burst DMA can't drive per-channel direction switching). Define it unconditionally; keep loadDmaBufferDshotStride() gated behind USE_DSHOT_DMAR since it's only used by the DMAR-specific burst path.
|
I have made four commits fixing four different kinds of compile failures on this. I would love to be able to include this in INAV 10, but worry about the correctness and quality when there are multiple different types of errors caught just by trying to build it. |
|
The current compile failures on all the F722 targets are because this will not fit in ITCM on F722 and it's single-caller within the scheduler() FAST_CODE call chain. |
|
Memory issue is resolved with this PR: halfmanbear#1 Probably auto transition + this one merged together into base branch will need more memory optimisations. |
fix: keep DShot telemetry decode out of ITCM
|
RAM / Flash usage vs. base branch — commit
|
|
Test firmware build ready — commit Download firmware for PR #11605 244 targets built. Find your board's
|
|
Hi, I'm trying to test this but I'm not sure how. I had to enable
My FC does support bidirectional dshot when it runs Ardupilot so it's not a hardware issue |
|
bidirectional DShot + EDT telemetry is a great addition. I pointed another tool at it and I ran into a few things I wasn't sure about and wanted to check with you rather than assume they're bugs, since I may be missing context.
|
|
I tested it on my plane. FC: MATEKH743-WLITE Motor will not start at all. Motors beep after connecting battery but will not start, same for both configuratuion Connecting from https://esc-configurator.com/ works and it's possible to load ESC configuration
Tested on T1, VTOL configuration. BTW: I don't have prepared test FC for ESC testing, I have to prepare first. |
|
Here is some suggestion what could be fixed in dshot bidir. There are three fixes (mainly for H7)
My is probably only for DMA version of dshot, I did not tested DMAR on F4 CPU. It's in 95% code generated by AI. But I tried to understand what is happening there. But for me how bidir-dshot works is something between magic and miracle. |








Ports bidirectional DShot (GCR) telemetry from Betaflight, enabling RPM-based gyro filtering without a dedicated ESC telemetry UART.
After each DShot output frame the motor pin is switched to timer input capture mode via per-channel DMA to receive the ESC's GCR-encoded eRPM response. The decoded eRPM feeds the existing RPM filter infrastructure.
New settings:
Changes:
Tested on SPEEDYBEEF405V4 (STM32F405, StdPeriph) with Bluejay ESC firmware. eRPM telemetry confirmed in blackbox;