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:
commit
5f3ea43f63
4 changed files with 93 additions and 83 deletions
|
@ -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) {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue