1
0
Fork 0
mirror of https://github.com/betaflight/betaflight.git synced 2025-07-15 20:35:33 +03:00

Merge pull request #8763 from hydra/bf-refactor-dshot-1

Refactor DSHOT 1
This commit is contained in:
Michael Keller 2019-08-30 01:32:16 +12:00 committed by GitHub
commit 5f3ea43f63
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 93 additions and 83 deletions

View file

@ -66,7 +66,7 @@ void dshotEnableChannels(uint8_t motorCount)
static void motor_DMA_IRQHandler(dmaChannelDescriptor_t *descriptor); static void motor_DMA_IRQHandler(dmaChannelDescriptor_t *descriptor);
FAST_CODE void pwmDshotSetDirectionOutput( FAST_CODE void pwmDshotSetDirectionOutput(
motorDmaOutput_t * const motor, bool output motorDmaOutput_t * const motor
#ifndef USE_DSHOT_TELEMETRY #ifndef USE_DSHOT_TELEMETRY
,TIM_OCInitTypeDef *pOcInit, DMA_InitTypeDef* pDmaInit ,TIM_OCInitTypeDef *pOcInit, DMA_InitTypeDef* pDmaInit
#endif #endif
@ -91,60 +91,70 @@ FAST_CODE void pwmDshotSetDirectionOutput(
xDMA_DeInit(dmaRef); xDMA_DeInit(dmaRef);
#ifdef USE_DSHOT_TELEMETRY #ifdef USE_DSHOT_TELEMETRY
if (!output) { motor->isInput = false;
motor->isInput = true;
if (!inputStampUs) {
inputStampUs = micros();
}
TIM_ARRPreloadConfig(timer, ENABLE);
timer->ARR = 0xffffffff;
TIM_ICInit(timer, &motor->icInitStruct);
#if defined(STM32F3)
motor->dmaInitStruct.DMA_DIR = DMA_DIR_PeripheralSRC;
motor->dmaInitStruct.DMA_M2M = DMA_M2M_Disable;
#elif defined(STM32F4)
motor->dmaInitStruct.DMA_DIR = DMA_DIR_PeripheralToMemory;
#endif #endif
} else timerOCPreloadConfig(timer, timerHardware->channel, TIM_OCPreload_Disable);
#else timerOCInit(timer, timerHardware->channel, pOcInit);
UNUSED(output); timerOCPreloadConfig(timer, timerHardware->channel, TIM_OCPreload_Enable);
#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);
#ifdef USE_DSHOT_DMAR #ifdef USE_DSHOT_DMAR
if (useBurstDshot) { if (useBurstDshot) {
#if defined(STM32F3) #if defined(STM32F3)
pDmaInit->DMA_DIR = DMA_DIR_PeripheralDST; pDmaInit->DMA_DIR = DMA_DIR_PeripheralDST;
#else #else
pDmaInit->DMA_DIR = DMA_DIR_MemoryToPeripheral; pDmaInit->DMA_DIR = DMA_DIR_MemoryToPeripheral;
#endif #endif
} else } else
#endif #endif
{ {
#if defined(STM32F3) #if defined(STM32F3)
pDmaInit->DMA_DIR = DMA_DIR_PeripheralDST; pDmaInit->DMA_DIR = DMA_DIR_PeripheralDST;
pDmaInit->DMA_M2M = DMA_M2M_Disable; pDmaInit->DMA_M2M = DMA_M2M_Disable;
#elif defined(STM32F4) #elif defined(STM32F4)
pDmaInit->DMA_DIR = DMA_DIR_MemoryToPeripheral; pDmaInit->DMA_DIR = DMA_DIR_MemoryToPeripheral;
#endif #endif
}
} }
xDMA_Init(dmaRef, pDmaInit); xDMA_Init(dmaRef, pDmaInit);
if (output) { xDMA_ITConfig(dmaRef, DMA_IT_TC, ENABLE);
xDMA_ITConfig(dmaRef, DMA_IT_TC, ENABLE);
}
} }
#ifdef USE_DSHOT_TELEMETRY
FAST_CODE void pwmDshotSetDirectionInput(
motorDmaOutput_t * const motor
)
{
DMA_InitTypeDef* pDmaInit = &motor->dmaInitStruct;
const timerHardware_t * const timerHardware = motor->timerHardware;
TIM_TypeDef *timer = timerHardware->tim;
dmaResource_t *dmaRef = motor->dmaRef;
xDMA_DeInit(dmaRef);
motor->isInput = true;
if (!inputStampUs) {
inputStampUs = micros();
}
TIM_ARRPreloadConfig(timer, ENABLE);
timer->ARR = 0xffffffff;
TIM_ICInit(timer, &motor->icInitStruct);
#if defined(STM32F3)
motor->dmaInitStruct.DMA_DIR = DMA_DIR_PeripheralSRC;
motor->dmaInitStruct.DMA_M2M = DMA_M2M_Disable;
#elif defined(STM32F4)
motor->dmaInitStruct.DMA_DIR = DMA_DIR_PeripheralToMemory;
#endif
xDMA_Init(dmaRef, pDmaInit);
}
#endif
void pwmCompleteDshotMotorUpdate(void) void pwmCompleteDshotMotorUpdate(void)
{ {
/* If there is a dshot command loaded up, time it correctly with motor update*/ /* If there is a dshot command loaded up, time it correctly with motor update*/
@ -194,7 +204,7 @@ static void motor_DMA_IRQHandler(dmaChannelDescriptor_t *descriptor)
#ifdef USE_DSHOT_TELEMETRY #ifdef USE_DSHOT_TELEMETRY
if (useDshotTelemetry) { if (useDshotTelemetry) {
pwmDshotSetDirectionOutput(motor, false); pwmDshotSetDirectionInput(motor);
xDMA_SetCurrDataCounter(motor->dmaRef, GCR_TELEMETRY_INPUT_LEN); xDMA_SetCurrDataCounter(motor->dmaRef, GCR_TELEMETRY_INPUT_LEN);
xDMA_Cmd(motor->dmaRef, ENABLE); xDMA_Cmd(motor->dmaRef, ENABLE);
TIM_DMACmd(motor->timerHardware->tim, motor->timerDmaSource, ENABLE); TIM_DMACmd(motor->timerHardware->tim, motor->timerDmaSource, ENABLE);
@ -392,9 +402,9 @@ bool pwmDshotMotorHardwareConfig(const timerHardware_t *timerHardware, uint8_t m
motor->dshotTelemetryDeadtimeUs = DSHOT_TELEMETRY_DEADTIME_US + 1000000 * motor->dshotTelemetryDeadtimeUs = DSHOT_TELEMETRY_DEADTIME_US + 1000000 *
(16 * MOTOR_BITLENGTH) / getDshotHz(pwmProtocolType); (16 * MOTOR_BITLENGTH) / getDshotHz(pwmProtocolType);
motor->timer->outputPeriod = (pwmProtocolType == PWM_TYPE_PROSHOT1000 ? (MOTOR_NIBBLE_LENGTH_PROSHOT) : MOTOR_BITLENGTH) - 1; motor->timer->outputPeriod = (pwmProtocolType == PWM_TYPE_PROSHOT1000 ? (MOTOR_NIBBLE_LENGTH_PROSHOT) : MOTOR_BITLENGTH) - 1;
pwmDshotSetDirectionOutput(motor, true); pwmDshotSetDirectionOutput(motor);
#else #else
pwmDshotSetDirectionOutput(motor, true, &OCINIT, &DMAINIT); pwmDshotSetDirectionOutput(motor, &OCINIT, &DMAINIT);
#endif #endif
#ifdef USE_DSHOT_DMAR #ifdef USE_DSHOT_DMAR
if (useBurstDshot) { if (useBurstDshot) {

View file

@ -69,7 +69,7 @@ void dshotEnableChannels(uint8_t motorCount)
static void motor_DMA_IRQHandler(dmaChannelDescriptor_t *descriptor); static void motor_DMA_IRQHandler(dmaChannelDescriptor_t *descriptor);
void pwmDshotSetDirectionOutput( void pwmDshotSetDirectionOutput(
motorDmaOutput_t * const motor, bool output motorDmaOutput_t * const motor
#ifndef USE_DSHOT_TELEMETRY #ifndef USE_DSHOT_TELEMETRY
, LL_TIM_OC_InitTypeDef* pOcInit, LL_DMA_InitTypeDef* pDmaInit , LL_TIM_OC_InitTypeDef* pOcInit, LL_DMA_InitTypeDef* pDmaInit
#endif #endif
@ -86,35 +86,42 @@ void pwmDshotSetDirectionOutput(
xLL_EX_DMA_DeInit(motor->dmaRef); xLL_EX_DMA_DeInit(motor->dmaRef);
#ifdef USE_DSHOT_TELEMETRY #ifdef USE_DSHOT_TELEMETRY
if (!output) { motor->isInput = false;
motor->isInput = true;
if (!inputStampUs) {
inputStampUs = micros();
}
LL_TIM_EnableARRPreload(timer); // Only update the period once all channels are done
timer->ARR = 0xffffffff;
LL_TIM_IC_Init(timer, motor->llChannel, &motor->icInitStruct);
motor->dmaInitStruct.Direction = LL_DMA_DIRECTION_PERIPH_TO_MEMORY;
} else
#else
UNUSED(output);
#endif #endif
{ LL_TIM_OC_DisablePreload(timer, motor->llChannel);
#ifdef USE_DSHOT_TELEMETRY LL_TIM_OC_Init(timer, motor->llChannel, pOcInit);
motor->isInput = false; LL_TIM_OC_EnablePreload(timer, motor->llChannel);
#endif
LL_TIM_OC_DisablePreload(timer, motor->llChannel); motor->dmaInitStruct.Direction = LL_DMA_DIRECTION_MEMORY_TO_PERIPH;
LL_TIM_OC_Init(timer, motor->llChannel, pOcInit);
LL_TIM_OC_EnablePreload(timer, motor->llChannel);
motor->dmaInitStruct.Direction = LL_DMA_DIRECTION_MEMORY_TO_PERIPH;
}
xLL_EX_DMA_Init(motor->dmaRef, pDmaInit); xLL_EX_DMA_Init(motor->dmaRef, pDmaInit);
if (output) { xLL_EX_DMA_EnableIT_TC(motor->dmaRef);
xLL_EX_DMA_EnableIT_TC(motor->dmaRef);
}
} }
#ifdef USE_DSHOT_TELEMETRY
void pwmDshotSetDirectionInput(
motorDmaOutput_t * const motor
)
{
LL_DMA_InitTypeDef* pDmaInit = &motor->dmaInitStruct;
const timerHardware_t * const timerHardware = motor->timerHardware;
TIM_TypeDef *timer = timerHardware->tim;
xLL_EX_DMA_DeInit(motor->dmaRef);
motor->isInput = true;
if (!inputStampUs) {
inputStampUs = micros();
}
LL_TIM_EnableARRPreload(timer); // Only update the period once all channels are done
timer->ARR = 0xffffffff;
LL_TIM_IC_Init(timer, motor->llChannel, &motor->icInitStruct);
motor->dmaInitStruct.Direction = LL_DMA_DIRECTION_PERIPH_TO_MEMORY;
xLL_EX_DMA_Init(motor->dmaRef, pDmaInit);
}
#endif
FAST_CODE void pwmCompleteDshotMotorUpdate(void) FAST_CODE void pwmCompleteDshotMotorUpdate(void)
{ {
@ -169,7 +176,7 @@ static void motor_DMA_IRQHandler(dmaChannelDescriptor_t* descriptor)
#ifdef USE_DSHOT_TELEMETRY #ifdef USE_DSHOT_TELEMETRY
if (useDshotTelemetry) { if (useDshotTelemetry) {
pwmDshotSetDirectionOutput(motor, false); pwmDshotSetDirectionInput(motor);
xLL_EX_DMA_SetDataLength(motor->dmaRef, GCR_TELEMETRY_INPUT_LEN); xLL_EX_DMA_SetDataLength(motor->dmaRef, GCR_TELEMETRY_INPUT_LEN);
xLL_EX_DMA_EnableResource(motor->dmaRef); xLL_EX_DMA_EnableResource(motor->dmaRef);
LL_EX_TIM_EnableIT(motor->timerHardware->tim, motor->timerDmaSource); LL_EX_TIM_EnableIT(motor->timerHardware->tim, motor->timerDmaSource);
@ -353,9 +360,9 @@ bool pwmDshotMotorHardwareConfig(const timerHardware_t *timerHardware, uint8_t m
motor->dshotTelemetryDeadtimeUs = DSHOT_TELEMETRY_DEADTIME_US + 1000000 * motor->dshotTelemetryDeadtimeUs = DSHOT_TELEMETRY_DEADTIME_US + 1000000 *
( 16 * MOTOR_BITLENGTH) / getDshotHz(pwmProtocolType); ( 16 * MOTOR_BITLENGTH) / getDshotHz(pwmProtocolType);
motor->timer->outputPeriod = (pwmProtocolType == PWM_TYPE_PROSHOT1000 ? (MOTOR_NIBBLE_LENGTH_PROSHOT) : MOTOR_BITLENGTH) - 1; motor->timer->outputPeriod = (pwmProtocolType == PWM_TYPE_PROSHOT1000 ? (MOTOR_NIBBLE_LENGTH_PROSHOT) : MOTOR_BITLENGTH) - 1;
pwmDshotSetDirectionOutput(motor, true); pwmDshotSetDirectionOutput(motor);
#else #else
pwmDshotSetDirectionOutput(motor, true, &OCINIT, &DMAINIT); pwmDshotSetDirectionOutput(motor, &OCINIT, &DMAINIT);
#endif #endif
#ifdef USE_DSHOT_DMAR #ifdef USE_DSHOT_DMAR
if (useBurstDshot) { if (useBurstDshot) {

View file

@ -219,17 +219,6 @@ uint16_t getDshotTelemetry(uint8_t index)
#endif #endif
FAST_CODE void pwmDshotSetDirectionOutput(
motorDmaOutput_t * const motor, bool output
#ifndef USE_DSHOT_TELEMETRY
#ifdef USE_FULL_LL_DRIVER
, LL_TIM_OC_InitTypeDef* pOcInit, LL_DMA_InitTypeDef* pDmaInit
#else
, TIM_OCInitTypeDef *pOcInit, DMA_InitTypeDef* pDmaInit
#endif
#endif
);
#ifdef USE_DSHOT_TELEMETRY #ifdef USE_DSHOT_TELEMETRY
#ifdef USE_DSHOT_TELEMETRY_STATS #ifdef USE_DSHOT_TELEMETRY_STATS
void updateDshotTelemetryQuality(dshotTelemetryQuality_t *qualityStats, bool packetValid, timeMs_t currentTimeMs) void updateDshotTelemetryQuality(dshotTelemetryQuality_t *qualityStats, bool packetValid, timeMs_t currentTimeMs)
@ -307,7 +296,7 @@ FAST_CODE_NOINLINE bool pwmStartDshotMotorUpdate(void)
} }
#endif #endif
} }
pwmDshotSetDirectionOutput(&dmaMotors[i], true); pwmDshotSetDirectionOutput(&dmaMotors[i]);
} }
inputStampUs = 0; inputStampUs = 0;
dshotEnableChannels(dshotPwmDevice.count); dshotEnableChannels(dshotPwmDevice.count);

View file

@ -57,7 +57,7 @@ void dshotEnableChannels(uint8_t motorCount);
#ifdef USE_DSHOT_TELEMETRY #ifdef USE_DSHOT_TELEMETRY
FAST_CODE void pwmDshotSetDirectionOutput( FAST_CODE void pwmDshotSetDirectionOutput(
motorDmaOutput_t * const motor, bool output motorDmaOutput_t * const motor
#ifndef USE_DSHOT_TELEMETRY #ifndef USE_DSHOT_TELEMETRY
#if defined(STM32F7) || defined(STM32H7) #if defined(STM32F7) || defined(STM32H7)
, LL_TIM_OC_InitTypeDef* pOcInit, LL_DMA_InitTypeDef* pDmaInit , LL_TIM_OC_InitTypeDef* pOcInit, LL_DMA_InitTypeDef* pDmaInit
@ -67,6 +67,10 @@ FAST_CODE void pwmDshotSetDirectionOutput(
#endif #endif
); );
#ifdef USE_DSHOT_TELEMETRY
FAST_CODE void pwmDshotSetDirectionInput(motorDmaOutput_t * const motor);
#endif
bool pwmStartDshotMotorUpdate(void); bool pwmStartDshotMotorUpdate(void);
#endif #endif