mirror of
https://github.com/PX4/PX4-Autopilot.git
synced 2026-07-26 16:28:06 +08:00
fix(dshot): pick bit width per timer clock for accurate rate (#27402)
Auto-selects DSHOT_MOTOR_PWM_BIT_WIDTH per timer clock at compile time
so ARK FPV emits DSHOT at the same bit period as the rest of the fleet.
The hardcoded WIDTH=20 truncates the prescaler on ARK FPV's 160 MHz APB1
(PLL1N=40, floor(160e6/600e3)=266 not divisible by 20), giving a 1.706us
bit period and 66.7%/33.3% duty cycles (vs DSHOT600 spec 75%/37.5%).
The new ladder tries WIDTH in {20, 19, 18} and picks the first that
divides cleanly. ARK FPV lands on W=19, matching the 1.75us bit period
of the 240 MHz boards. Duty cycles improve to 70%/35%. 240/96/108/84 MHz
boards keep W=20 (unchanged). 200 MHz boards (CubeOrange/Orange+,
h7extreme) fall through to W=20 (unchanged, fix needs W=22 with scaled
BIT_1/BIT_0 -- out of scope).
A #pragma message (not #warning, which -Werror=cpp would treat as an
error) flags boards where APB1 and APB2 timer clocks would emit DSHOT
at different rates -- currently only fmu-v4pro (APB1=90, APB2=180 MHz).
The whole block is guarded on STM32_APB2_TIM8_CLKIN so STM32F1 IO
co-processor boards (no TIM8, header still pulled in by io_timer.c)
keep W=20 silently.
Supersedes #27401.
This commit is contained in:
@@ -36,8 +36,32 @@
|
||||
|
||||
#include <drivers/drv_pwm_output.h>
|
||||
#include <stm32_dma.h>
|
||||
#include <arch/board/board.h>
|
||||
|
||||
#define DSHOT_MOTOR_PWM_BIT_WIDTH 20u
|
||||
// Pick WIDTH so floor(TIM_CLK / 600000) divides cleanly into it, keeping the
|
||||
// prescaler integer. Guard skips F1 IO co-processors (no TIM8, no DSHOT).
|
||||
#if defined(STM32_APB1_TIM5_CLKIN) && defined(STM32_APB2_TIM8_CLKIN)
|
||||
|
||||
#define _DSHOT600_TICKS_APB1 (STM32_APB1_TIM5_CLKIN / 600000U)
|
||||
#define _DSHOT600_TICKS_APB2 (STM32_APB2_TIM8_CLKIN / 600000U)
|
||||
|
||||
#if (_DSHOT600_TICKS_APB1 % 20U == 0U)
|
||||
# define DSHOT_MOTOR_PWM_BIT_WIDTH 20u
|
||||
#elif (_DSHOT600_TICKS_APB1 % 19U == 0U)
|
||||
# define DSHOT_MOTOR_PWM_BIT_WIDTH 19u
|
||||
#elif (_DSHOT600_TICKS_APB1 % 18U == 0U)
|
||||
# define DSHOT_MOTOR_PWM_BIT_WIDTH 18u
|
||||
#else
|
||||
# define DSHOT_MOTOR_PWM_BIT_WIDTH 20u
|
||||
#endif
|
||||
|
||||
#if (_DSHOT600_TICKS_APB1 % DSHOT_MOTOR_PWM_BIT_WIDTH) != (_DSHOT600_TICKS_APB2 % DSHOT_MOTOR_PWM_BIT_WIDTH)
|
||||
# pragma message "DSHOT bit width: APB1 and APB2 timer clocks emit DSHOT at different rates on this board"
|
||||
#endif
|
||||
|
||||
#else
|
||||
# define DSHOT_MOTOR_PWM_BIT_WIDTH 20u
|
||||
#endif
|
||||
|
||||
/* Configuration for each timer to setup DShot. Some timers have only one while others have two choices for the stream.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user