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.
This commit is contained in:
Julian Oes 2026-02-06 16:21:07 +13:00
parent f6a0ed57a4
commit b9f6e35a43
No known key found for this signature in database
GPG Key ID: F0ED380FEA56DE41
4 changed files with 7 additions and 44 deletions

View File

@ -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)
{

View File

@ -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;
}

View File

@ -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

View File

@ -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);