1
0
Fork 0
mirror of https://github.com/betaflight/betaflight.git synced 2025-07-15 12:25:20 +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);
FAST_CODE void pwmDshotSetDirectionOutput(
motorDmaOutput_t * const motor, bool output
motorDmaOutput_t * const motor
#ifndef USE_DSHOT_TELEMETRY
,TIM_OCInitTypeDef *pOcInit, DMA_InitTypeDef* pDmaInit
#endif
@ -91,60 +91,70 @@ FAST_CODE void pwmDshotSetDirectionOutput(
xDMA_DeInit(dmaRef);
#ifdef USE_DSHOT_TELEMETRY
if (!output) {
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;
motor->isInput = false;
#endif
} else
#else
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);
timerOCPreloadConfig(timer, timerHardware->channel, TIM_OCPreload_Disable);
timerOCInit(timer, timerHardware->channel, pOcInit);
timerOCPreloadConfig(timer, timerHardware->channel, TIM_OCPreload_Enable);
#ifdef USE_DSHOT_DMAR
if (useBurstDshot) {
if (useBurstDshot) {
#if defined(STM32F3)
pDmaInit->DMA_DIR = DMA_DIR_PeripheralDST;
pDmaInit->DMA_DIR = DMA_DIR_PeripheralDST;
#else
pDmaInit->DMA_DIR = DMA_DIR_MemoryToPeripheral;
pDmaInit->DMA_DIR = DMA_DIR_MemoryToPeripheral;
#endif
} else
} else
#endif
{
{
#if defined(STM32F3)
pDmaInit->DMA_DIR = DMA_DIR_PeripheralDST;
pDmaInit->DMA_M2M = DMA_M2M_Disable;
pDmaInit->DMA_DIR = DMA_DIR_PeripheralDST;
pDmaInit->DMA_M2M = DMA_M2M_Disable;
#elif defined(STM32F4)
pDmaInit->DMA_DIR = DMA_DIR_MemoryToPeripheral;
pDmaInit->DMA_DIR = DMA_DIR_MemoryToPeripheral;
#endif
}
}
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)
{
/* 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
if (useDshotTelemetry) {
pwmDshotSetDirectionOutput(motor, false);
pwmDshotSetDirectionInput(motor);
xDMA_SetCurrDataCounter(motor->dmaRef, GCR_TELEMETRY_INPUT_LEN);
xDMA_Cmd(motor->dmaRef, 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 *
(16 * MOTOR_BITLENGTH) / getDshotHz(pwmProtocolType);
motor->timer->outputPeriod = (pwmProtocolType == PWM_TYPE_PROSHOT1000 ? (MOTOR_NIBBLE_LENGTH_PROSHOT) : MOTOR_BITLENGTH) - 1;
pwmDshotSetDirectionOutput(motor, true);
pwmDshotSetDirectionOutput(motor);
#else
pwmDshotSetDirectionOutput(motor, true, &OCINIT, &DMAINIT);
pwmDshotSetDirectionOutput(motor, &OCINIT, &DMAINIT);
#endif
#ifdef USE_DSHOT_DMAR
if (useBurstDshot) {

View file

@ -69,7 +69,7 @@ void dshotEnableChannels(uint8_t motorCount)
static void motor_DMA_IRQHandler(dmaChannelDescriptor_t *descriptor);
void pwmDshotSetDirectionOutput(
motorDmaOutput_t * const motor, bool output
motorDmaOutput_t * const motor
#ifndef USE_DSHOT_TELEMETRY
, LL_TIM_OC_InitTypeDef* pOcInit, LL_DMA_InitTypeDef* pDmaInit
#endif
@ -86,35 +86,42 @@ void pwmDshotSetDirectionOutput(
xLL_EX_DMA_DeInit(motor->dmaRef);
#ifdef USE_DSHOT_TELEMETRY
if (!output) {
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);
motor->isInput = false;
#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);
LL_TIM_OC_DisablePreload(timer, motor->llChannel);
LL_TIM_OC_Init(timer, motor->llChannel, pOcInit);
LL_TIM_OC_EnablePreload(timer, motor->llChannel);
motor->dmaInitStruct.Direction = LL_DMA_DIRECTION_MEMORY_TO_PERIPH;
motor->dmaInitStruct.Direction = LL_DMA_DIRECTION_MEMORY_TO_PERIPH;
}
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)
{
@ -169,7 +176,7 @@ static void motor_DMA_IRQHandler(dmaChannelDescriptor_t* descriptor)
#ifdef USE_DSHOT_TELEMETRY
if (useDshotTelemetry) {
pwmDshotSetDirectionOutput(motor, false);
pwmDshotSetDirectionInput(motor);
xLL_EX_DMA_SetDataLength(motor->dmaRef, GCR_TELEMETRY_INPUT_LEN);
xLL_EX_DMA_EnableResource(motor->dmaRef);
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 *
( 16 * MOTOR_BITLENGTH) / getDshotHz(pwmProtocolType);
motor->timer->outputPeriod = (pwmProtocolType == PWM_TYPE_PROSHOT1000 ? (MOTOR_NIBBLE_LENGTH_PROSHOT) : MOTOR_BITLENGTH) - 1;
pwmDshotSetDirectionOutput(motor, true);
pwmDshotSetDirectionOutput(motor);
#else
pwmDshotSetDirectionOutput(motor, true, &OCINIT, &DMAINIT);
pwmDshotSetDirectionOutput(motor, &OCINIT, &DMAINIT);
#endif
#ifdef USE_DSHOT_DMAR
if (useBurstDshot) {

View file

@ -219,17 +219,6 @@ uint16_t getDshotTelemetry(uint8_t index)
#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_STATS
void updateDshotTelemetryQuality(dshotTelemetryQuality_t *qualityStats, bool packetValid, timeMs_t currentTimeMs)
@ -307,7 +296,7 @@ FAST_CODE_NOINLINE bool pwmStartDshotMotorUpdate(void)
}
#endif
}
pwmDshotSetDirectionOutput(&dmaMotors[i], true);
pwmDshotSetDirectionOutput(&dmaMotors[i]);
}
inputStampUs = 0;
dshotEnableChannels(dshotPwmDevice.count);

View file

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