1
0
Fork 0
mirror of https://github.com/betaflight/betaflight.git synced 2025-07-17 21:35:44 +03:00

avoid dshot telemetry collisions

actually use calculated deadtime

fix whitespace and return value

fix ws

Address review feedback

fix ws
This commit is contained in:
Thorsten Laux 2019-03-19 13:02:44 +01:00 committed by mikeller
parent 8984a7195f
commit 5a759c56ef
7 changed files with 82 additions and 51 deletions

View file

@ -224,9 +224,10 @@ bool pwmAreMotorsEnabled(void)
}
#ifdef USE_DSHOT_TELEMETRY
static void pwmStartWriteUnused(uint8_t motorCount)
static bool pwmStartWriteUnused(uint8_t motorCount)
{
UNUSED(motorCount);
return true;
}
#endif
@ -253,9 +254,9 @@ void pwmCompleteMotorUpdate(uint8_t motorCount)
}
#ifdef USE_DSHOT_TELEMETRY
void pwmStartMotorUpdate(uint8_t motorCount)
bool pwmStartMotorUpdate(uint8_t motorCount)
{
pwmStartWrite(motorCount);
return pwmStartWrite(motorCount);
}
#endif
@ -521,7 +522,9 @@ void pwmWriteDshotCommand(uint8_t index, uint8_t motorCount, uint8_t command, bo
delayMicroseconds(DSHOT_COMMAND_DELAY_US);
#ifdef USE_DSHOT_TELEMETRY
pwmStartDshotMotorUpdate(motorCount);
timeUs_t currentTimeUs = micros();
while (!pwmStartDshotMotorUpdate(motorCount) &&
cmpTimeUs(micros(), currentTimeUs) < 1000);
#endif
for (uint8_t i = 0; i < motorCount; i++) {
if ((i == index) || (index == ALL_MOTORS)) {

View file

@ -22,6 +22,8 @@
#include "platform.h"
#include "common/time.h"
#include "drivers/io_types.h"
#include "drivers/pwm_output_counts.h"
#include "drivers/timer.h"
@ -112,6 +114,8 @@ typedef enum {
#define PROSHOT_BASE_SYMBOL 24 // 1uS
#define PROSHOT_BIT_WIDTH 3
#define MOTOR_NIBBLE_LENGTH_PROSHOT 96 // 4uS
#define DSHOT_TELEMETRY_DEADTIME_US (2 * 30 + 10) // 2 * 30uS to switch lines plus 10us grace period
#endif
@ -128,6 +132,7 @@ typedef struct {
#endif
uint16_t dmaBurstLength;
uint32_t dmaBurstBuffer[DSHOT_DMA_BUFFER_SIZE * 4];
timeUs_t inputDirectionStampUs;
#endif
uint16_t timerDmaSources;
} motorDmaTimer_t;
@ -146,6 +151,7 @@ typedef struct {
volatile bool isInput;
volatile bool hasTelemetry;
uint16_t dshotTelemetryValue;
timeDelta_t dshotTelemetryDeadtimeUs;
bool dshotTelemetryActive;
#ifdef USE_HAL_DRIVER
LL_TIM_OC_InitTypeDef ocInitStruct;
@ -183,7 +189,7 @@ motorDmaOutput_t *getMotorDmaOutput(uint8_t index);
struct timerHardware_s;
typedef void pwmWriteFn(uint8_t index, float value); // function pointer used to write motors
typedef void pwmCompleteWriteFn(uint8_t motorCount); // function pointer used after motors are written
typedef void pwmStartWriteFn(uint8_t motorCount); // function pointer used before motors are written
typedef bool pwmStartWriteFn(uint8_t motorCount); // function pointer used before motors are written
typedef struct {
volatile timCCR_t *ccr;
@ -244,7 +250,7 @@ void pwmWriteDshotCommand(uint8_t index, uint8_t motorCount, uint8_t command, bo
void pwmWriteDshotInt(uint8_t index, uint16_t value);
void pwmDshotMotorHardwareConfig(const timerHardware_t *timerHardware, uint8_t motorIndex, motorPwmProtocolTypes_e pwmProtocolType, uint8_t output);
#ifdef USE_DSHOT_TELEMETRY
void pwmStartDshotMotorUpdate(uint8_t motorCount);
bool pwmStartDshotMotorUpdate(uint8_t motorCount);
#endif
void pwmCompleteDshotMotorUpdate(uint8_t motorCount);
@ -268,7 +274,7 @@ void pwmOutConfig(timerChannel_t *channel, const timerHardware_t *timerHardware,
void pwmWriteMotor(uint8_t index, float value);
void pwmShutdownPulsesForAllMotors(uint8_t motorCount);
void pwmCompleteMotorUpdate(uint8_t motorCount);
void pwmStartMotorUpdate(uint8_t motorCount);
bool pwmStartMotorUpdate(uint8_t motorCount);
void pwmWriteServo(uint8_t index, float value);

View file

@ -96,8 +96,9 @@ FAST_CODE void pwmDshotSetDirectionOutput(
DMA_DeInit(dmaRef);
#ifdef USE_DSHOT_TELEMETRY
motor->isInput = !output;
if (!output) {
motor->isInput = true;
motor->timer->inputDirectionStampUs = micros();
TIM_ICInit(timer, &motor->icInitStruct);
#if defined(STM32F3)
@ -111,6 +112,9 @@ FAST_CODE void pwmDshotSetDirectionOutput(
UNUSED(output);
#endif
{
#ifdef USE_DSHOT_TELEMETRY
motor->isInput = false;
#endif
timerOCPreloadConfig(timer, timerHardware->channel, TIM_OCPreload_Disable);
timerOCInit(timer, timerHardware->channel, pOcInit);
timerOCPreloadConfig(timer, timerHardware->channel, TIM_OCPreload_Enable);
@ -388,6 +392,9 @@ void pwmDshotMotorHardwareConfig(const timerHardware_t *timerHardware, uint8_t m
#ifdef USE_DSHOT_TELEMETRY
motor->dmaInputLen = motor->useProshot ? PROSHOT_TELEMETRY_INPUT_LEN : DSHOT_TELEMETRY_INPUT_LEN;
motor->dshotTelemetryDeadtimeUs = DSHOT_TELEMETRY_DEADTIME_US + 1000000 *
( 2 + (motor->useProshot ? 4 * MOTOR_NIBBLE_LENGTH_PROSHOT : 16 * MOTOR_BITLENGTH))
/ getDshotHz(pwmProtocolType);
pwmDshotSetDirectionOutput(motor, true);
#else
pwmDshotSetDirectionOutput(motor, true, &OCINIT, &DMAINIT);

View file

@ -98,8 +98,9 @@ void pwmDshotSetDirectionOutput(
LL_EX_DMA_DeInit(motor->dmaRef);
#ifdef USE_DSHOT_TELEMETRY
motor->isInput = !output;
if (!output) {
motor->isInput = true;
motor->timer->inputDirectionStampUs = micros();
LL_TIM_IC_Init(timer, motor->llChannel, &motor->icInitStruct);
motor->dmaInitStruct.Direction = LL_DMA_DIRECTION_PERIPH_TO_MEMORY;
} else
@ -107,6 +108,9 @@ void pwmDshotSetDirectionOutput(
UNUSED(output);
#endif
{
#ifdef USE_DSHOT_TELEMETRY
motor->isInput = false;
#endif
LL_TIM_OC_DisablePreload(timer, motor->llChannel);
LL_TIM_OC_Init(timer, motor->llChannel, pOcInit);
LL_TIM_OC_EnablePreload(timer, motor->llChannel);
@ -351,6 +355,9 @@ void pwmDshotMotorHardwareConfig(const timerHardware_t *timerHardware, uint8_t m
#ifdef USE_DSHOT_TELEMETRY
motor->dmaInputLen = motor->useProshot ? PROSHOT_TELEMETRY_INPUT_LEN : DSHOT_TELEMETRY_INPUT_LEN;
motor->dshotTelemetryDeadtimeUs = DSHOT_TELEMETRY_DEADTIME_US + 1000000 *
( 2 + (motor->useProshot ? 4 * MOTOR_NIBBLE_LENGTH_PROSHOT : 16 * MOTOR_BITLENGTH))
/ getDshotHz(pwmProtocolType);
pwmDshotSetDirectionOutput(motor, true);
#else
pwmDshotSetDirectionOutput(motor, true, &OCINIT, &DMAINIT);

View file

@ -203,9 +203,11 @@ FAST_CODE void pwmDshotSetDirectionOutput(
#ifdef USE_DSHOT_TELEMETRY
void pwmStartDshotMotorUpdate(uint8_t motorCount)
bool pwmStartDshotMotorUpdate(uint8_t motorCount)
{
if (useDshotTelemetry) {
if (!useDshotTelemetry) {
return true;
}
for (int i = 0; i < motorCount; i++) {
if (dmaMotors[i].hasTelemetry) {
#ifdef STM32F7
@ -235,6 +237,10 @@ void pwmStartDshotMotorUpdate(uint8_t motorCount)
}
dmaMotors[i].hasTelemetry = false;
} else {
timeDelta_t usSinceInput = cmpTimeUs(micros(), dmaMotors[i].timer->inputDirectionStampUs);
if (usSinceInput >= 0 && usSinceInput < dmaMotors[i].dshotTelemetryDeadtimeUs) {
return false;
}
#ifdef STM32F7
LL_EX_TIM_DisableIT(dmaMotors[i].timerHardware->tim, dmaMotors[i].timerDmaSource);
#else
@ -244,7 +250,7 @@ void pwmStartDshotMotorUpdate(uint8_t motorCount)
pwmDshotSetDirectionOutput(&dmaMotors[i], true);
}
dshotEnableChannels(motorCount);
}
return true;
}
bool isDshotMotorTelemetryActive(uint8_t motorIndex)

View file

@ -66,7 +66,7 @@ FAST_CODE void pwmDshotSetDirectionOutput(
#endif
);
void pwmStartDshotMotorUpdate(uint8_t motorCount);
bool pwmStartDshotMotorUpdate(uint8_t motorCount);
#endif
#endif

View file

@ -518,7 +518,9 @@ void writeMotors(void)
{
if (pwmAreMotorsEnabled()) {
#if defined(USE_DSHOT) && defined(USE_DSHOT_TELEMETRY)
pwmStartMotorUpdate(motorCount);
if (!pwmStartMotorUpdate(motorCount)) {
return;
}
#endif
for (int i = 0; i < motorCount; i++) {
pwmWriteMotor(i, motor[i]);