From b9f6e35a43f123e293bba5b0e48d05d0bf2da555 Mon Sep 17 00:00:00 2001 From: Julian Oes Date: Fri, 6 Feb 2026 16:21:07 +1300 Subject: [PATCH] dshot: just publish at 200 Hz It's tricky to figure out when to publish especially if some outputs that should be reporting stop reporting. I had some edge cases where it would not publish due timers not fully configured, so I decided to just publish at 200 Hz no matter what data was there to publish. --- .../nuttx/src/px4/nxp/imxrt/dshot/dshot.c | 14 ------------- .../src/px4/stm/stm32_common/dshot/dshot.c | 20 +------------------ src/drivers/drv_dshot.h | 9 --------- src/drivers/dshot/DShot.cpp | 8 ++++++-- 4 files changed, 7 insertions(+), 44 deletions(-) diff --git a/platforms/nuttx/src/px4/nxp/imxrt/dshot/dshot.c b/platforms/nuttx/src/px4/nxp/imxrt/dshot/dshot.c index bb56d78675..902d71fc8f 100644 --- a/platforms/nuttx/src/px4/nxp/imxrt/dshot/dshot.c +++ b/platforms/nuttx/src/px4/nxp/imxrt/dshot/dshot.c @@ -499,20 +499,6 @@ void up_bdshot_erpm(void) } -int up_bdshot_num_channels_ready(void) -{ - int num_ready = 0; - - for (unsigned i = 0; i < DSHOT_TIMERS; ++i) { - // We only check that data has been received, rather than if it's valid. - // This ensures data is published even if one channel has bit errors. - if (bdshot_parsed_recv_mask & (1 << i)) { - ++num_ready; - } - } - - return num_ready; -} int up_bdshot_num_errors(uint8_t channel) { diff --git a/platforms/nuttx/src/px4/stm/stm32_common/dshot/dshot.c b/platforms/nuttx/src/px4/stm/stm32_common/dshot/dshot.c index fef33e8115..73d68d33b1 100644 --- a/platforms/nuttx/src/px4/stm/stm32_common/dshot/dshot.c +++ b/platforms/nuttx/src/px4/stm/stm32_common/dshot/dshot.c @@ -140,7 +140,6 @@ static bool _bdshot_cycle_complete[MAX_IO_TIMERS] = { [0 ...(MAX_IO_TIMERS - 1)] // Online flags, set if ESC is reponding with valid BDShot frames #define BDSHOT_OFFLINE_COUNT 200 static bool _bdshot_online[MAX_TIMER_IO_CHANNELS] = {}; -static bool _bdshot_processed[MAX_TIMER_IO_CHANNELS] = {}; static bool _bdshot_capture_supported[MAX_TIMER_IO_CHANNELS] = {}; static int _consecutive_failures[MAX_TIMER_IO_CHANNELS] = {}; static int _consecutive_successes[MAX_TIMER_IO_CHANNELS] = {}; @@ -368,8 +367,7 @@ int up_dshot_init(uint32_t channel_mask, uint32_t bdshot_channel_mask, unsigned _bdshot_capture_supported[output_channel] = true; } else { - // No DMA for capture on this channel - mark as processed so it doesn't block - _bdshot_processed[output_channel] = true; + // No DMA for capture on this channel PX4_WARN("BDShot capture not supported on output %u (no DMA)", output_channel); } } @@ -675,7 +673,6 @@ void process_capture_results(uint8_t timer_index, uint8_t channel_index) _bdshot_online[output_channel] = false; } - _bdshot_processed[output_channel] = true; return; } @@ -748,7 +745,6 @@ void process_capture_results(uint8_t timer_index, uint8_t channel_index) break; } - _bdshot_processed[output_channel] = true; } float calculate_rate_hz(uint64_t last_timestamp, float last_rate_hz, uint64_t timestamp) @@ -955,18 +951,6 @@ int up_dshot_arm(bool armed) return ret; } -int up_bdshot_num_channels_ready(void) -{ - int num_ready = 0; - - for (uint8_t i = 0; i < MAX_TIMER_IO_CHANNELS; ++i) { - if (_bdshot_processed[i]) { - ++num_ready; - } - } - - return num_ready; -} int up_bdshot_num_errors(uint8_t channel) { @@ -986,8 +970,6 @@ int up_bdshot_get_erpm(uint8_t channel, int *erpm) status = PX4_OK; } - // Mark sample read - _bdshot_processed[channel] = false; return status; } diff --git a/src/drivers/drv_dshot.h b/src/drivers/drv_dshot.h index 59e37d804e..c4347db5fa 100644 --- a/src/drivers/drv_dshot.h +++ b/src/drivers/drv_dshot.h @@ -138,15 +138,6 @@ __EXPORT extern int up_dshot_arm(bool armed); */ __EXPORT extern void up_bdshot_status(void); -/** - * Get how many bidirectional erpm channels are ready - * - * When we get the erpm round-robin style, we need to get - * and publish the erpms less often. - * - * @return <0 on error, OK on succes - */ -__EXPORT extern int up_bdshot_num_channels_ready(void); /** * Get the total number of errors for a channel diff --git a/src/drivers/dshot/DShot.cpp b/src/drivers/dshot/DShot.cpp index 2274034c64..2e8b2d246d 100644 --- a/src/drivers/dshot/DShot.cpp +++ b/src/drivers/dshot/DShot.cpp @@ -563,11 +563,15 @@ bool DShot::process_bdshot_telemetry() return false; } - // We wait until all BDShot channels are ready. - if (up_bdshot_num_channels_ready() < count_set_bits(_bdshot_output_mask)) { + // Rate-limit telemetry processing to 200Hz + static hrt_abstime last_processed = 0; + + if (now - last_processed < 5000) { // 5ms = 200Hz return false; } + last_processed = now; + for (uint8_t output_channel = 0; output_channel < DSHOT_MAXIMUM_CHANNELS; output_channel++) { bool is_motor = _mixing_output.isMotor(output_channel); bool is_bdshot = _bdshot_output_mask & (1 << output_channel);