diff --git a/Makefile b/Makefile
index 61eb107b35..17850c1698 100644
--- a/Makefile
+++ b/Makefile
@@ -785,7 +785,6 @@ STM32F7xx_COMMON_SRC = \
drivers/pwm_output_stm32f7xx.c \
drivers/timer_hal.c \
drivers/timer_stm32f7xx.c \
- drivers/pwm_output_hal.c \
drivers/system_stm32f7xx.c \
drivers/serial_uart_stm32f7xx.c \
drivers/serial_uart_hal.c
@@ -793,7 +792,6 @@ STM32F7xx_COMMON_SRC = \
F7EXCLUDES = drivers/bus_spi.c \
drivers/bus_i2c.c \
drivers/timer.c \
- drivers/pwm_output.c \
drivers/serial_uart.c
# check if target.mk supplied
diff --git a/src/main/drivers/pwm_output.c b/src/main/drivers/pwm_output.c
index bb5f8d323a..2a123b8c9b 100644
--- a/src/main/drivers/pwm_output.c
+++ b/src/main/drivers/pwm_output.c
@@ -40,6 +40,27 @@ bool pwmMotorsEnabled = false;
static void pwmOCConfig(TIM_TypeDef *tim, uint8_t channel, uint16_t value, uint8_t output)
{
+#if defined(USE_HAL_DRIVER)
+ TIM_HandleTypeDef* Handle = timerFindTimerHandle(tim);
+ if(Handle == NULL) return;
+
+ TIM_OC_InitTypeDef TIM_OCInitStructure;
+
+ TIM_OCInitStructure.OCMode = TIM_OCMODE_PWM1;
+
+ if (output & TIMER_OUTPUT_N_CHANNEL) {
+ TIM_OCInitStructure.OCNIdleState = TIM_OCNIDLESTATE_RESET;
+ TIM_OCInitStructure.OCNPolarity = (output & TIMER_OUTPUT_INVERTED) ? TIM_OCNPOLARITY_HIGH : TIM_OCNPOLARITY_LOW;
+ } else {
+ TIM_OCInitStructure.OCIdleState = TIM_OCIDLESTATE_SET;
+ TIM_OCInitStructure.OCPolarity = (output & TIMER_OUTPUT_INVERTED) ? TIM_OCPOLARITY_LOW : TIM_OCPOLARITY_HIGH;
+ }
+
+ TIM_OCInitStructure.Pulse = value;
+ TIM_OCInitStructure.OCFastMode = TIM_OCFAST_DISABLE;
+
+ HAL_TIM_PWM_ConfigChannel(Handle, &TIM_OCInitStructure, channel);
+#else
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_OCStructInit(&TIM_OCInitStructure);
@@ -58,15 +79,26 @@ static void pwmOCConfig(TIM_TypeDef *tim, uint8_t channel, uint16_t value, uint8
timerOCInit(tim, channel, &TIM_OCInitStructure);
timerOCPreloadConfig(tim, channel, TIM_OCPreload_Enable);
+#endif
}
static void pwmOutConfig(pwmOutputPort_t *port, const timerHardware_t *timerHardware, uint8_t mhz, uint16_t period, uint16_t value)
{
+#if defined(USE_HAL_DRIVER)
+ TIM_HandleTypeDef* Handle = timerFindTimerHandle(timerHardware->tim);
+ if(Handle == NULL) return;
+#endif
+
configTimeBase(timerHardware->tim, period, mhz);
pwmOCConfig(timerHardware->tim, timerHardware->channel, value, timerHardware->output);
+#if defined(USE_HAL_DRIVER)
+ HAL_TIM_PWM_Start(Handle, timerHardware->channel);
+ HAL_TIM_Base_Start(Handle);
+#else
TIM_CtrlPWMOutputs(timerHardware->tim, ENABLE);
TIM_Cmd(timerHardware->tim, ENABLE);
+#endif
port->ccr = timerChCCR(timerHardware);
port->period = period;
@@ -230,7 +262,11 @@ void motorInit(const motorConfig_t *motorConfig, uint16_t idlePulse, uint8_t mot
#endif
IOInit(motors[motorIndex].io, OWNER_MOTOR, RESOURCE_INDEX(motorIndex));
+#if defined(USE_HAL_DRIVER)
+ IOConfigGPIOAF(motors[motorIndex].io, IOCFG_AF_PP, timerHardware->alternateFunction);
+#else
IOConfigGPIO(motors[motorIndex].io, IOCFG_AF_PP);
+#endif
if (useUnsyncedPwm) {
const uint32_t hz = timerMhzCounter * 1000000;
@@ -268,9 +304,13 @@ void servoInit(const servoConfig_t *servoConfig)
servos[servoIndex].io = IOGetByTag(tag);
IOInit(servos[servoIndex].io, OWNER_SERVO, RESOURCE_INDEX(servoIndex));
- IOConfigGPIO(servos[servoIndex].io, IOCFG_AF_PP);
const timerHardware_t *timer = timerGetByTag(tag, TIM_USE_ANY);
+#if defined(USE_HAL_DRIVER)
+ IOConfigGPIOAF(servos[servoIndex].io, IOCFG_AF_PP, timer->alternateFunction);
+#else
+ IOConfigGPIO(servos[servoIndex].io, IOCFG_AF_PP);
+#endif
if (timer == NULL) {
/* flag failure and disable ability to arm */
diff --git a/src/main/drivers/pwm_output_hal.c b/src/main/drivers/pwm_output_hal.c
deleted file mode 100644
index 4d530648be..0000000000
--- a/src/main/drivers/pwm_output_hal.c
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * This file is part of Cleanflight.
- *
- * Cleanflight is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Cleanflight is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Cleanflight. If not, see .
- */
-
-#include
-#include
-#include
-
-#include "platform.h"
-
-#include "io.h"
-#include "timer.h"
-#include "pwm_output.h"
-
-#define MULTISHOT_5US_PW (MULTISHOT_TIMER_MHZ * 5)
-#define MULTISHOT_20US_MULT (MULTISHOT_TIMER_MHZ * 20 / 1000.0f)
-
-static pwmWriteFuncPtr pwmWritePtr;
-static pwmOutputPort_t motors[MAX_SUPPORTED_MOTORS];
-static pwmCompleteWriteFuncPtr pwmCompleteWritePtr = NULL;
-
-#ifdef USE_SERVOS
-static pwmOutputPort_t servos[MAX_SUPPORTED_SERVOS];
-#endif
-
-bool pwmMotorsEnabled = false;
-
-static void pwmOCConfig(TIM_TypeDef *tim, uint8_t channel, uint16_t value, uint8_t output)
-{
- TIM_HandleTypeDef* Handle = timerFindTimerHandle(tim);
- if(Handle == NULL) return;
-
- TIM_OC_InitTypeDef TIM_OCInitStructure;
- TIM_OCInitStructure.OCMode = TIM_OCMODE_PWM2;
- TIM_OCInitStructure.Pulse = value;
- TIM_OCInitStructure.OCPolarity = (output & TIMER_OUTPUT_INVERTED) ? TIM_OCPOLARITY_HIGH : TIM_OCPOLARITY_LOW;
- TIM_OCInitStructure.OCNPolarity = (output & TIMER_OUTPUT_INVERTED) ? TIM_OCNPOLARITY_LOW : TIM_OCNPOLARITY_HIGH;
- TIM_OCInitStructure.OCIdleState = TIM_OCIDLESTATE_SET;
- TIM_OCInitStructure.OCNIdleState = TIM_OCNIDLESTATE_RESET;
- TIM_OCInitStructure.OCFastMode = TIM_OCFAST_DISABLE;
-
- HAL_TIM_PWM_ConfigChannel(Handle, &TIM_OCInitStructure, channel);
- //HAL_TIM_PWM_Start(Handle, channel);
-}
-
-static void pwmOutConfig(pwmOutputPort_t *port, const timerHardware_t *timerHardware, uint8_t mhz, uint16_t period, uint16_t value)
-{
- TIM_HandleTypeDef* Handle = timerFindTimerHandle(timerHardware->tim);
- if(Handle == NULL) return;
-
- configTimeBase(timerHardware->tim, period, mhz);
- pwmOCConfig(timerHardware->tim, timerHardware->channel, value, timerHardware->output);
-
- HAL_TIM_PWM_Start(Handle, timerHardware->channel);
- HAL_TIM_Base_Start(Handle);
-
- switch (timerHardware->channel) {
- case TIM_CHANNEL_1:
- port->ccr = &timerHardware->tim->CCR1;
- break;
- case TIM_CHANNEL_2:
- port->ccr = &timerHardware->tim->CCR2;
- break;
- case TIM_CHANNEL_3:
- port->ccr = &timerHardware->tim->CCR3;
- break;
- case TIM_CHANNEL_4:
- port->ccr = &timerHardware->tim->CCR4;
- break;
- }
- port->period = period;
- port->tim = timerHardware->tim;
-
- *port->ccr = 0;
-}
-
-static void pwmWriteBrushed(uint8_t index, uint16_t value)
-{
- *motors[index].ccr = (value - 1000) * motors[index].period / 1000;
-}
-
-static void pwmWriteStandard(uint8_t index, uint16_t value)
-{
- *motors[index].ccr = value;
-}
-
-static void pwmWriteOneShot125(uint8_t index, uint16_t value)
-{
- *motors[index].ccr = lrintf((float)(value * ONESHOT125_TIMER_MHZ/8.0f));
-}
-
-static void pwmWriteOneShot42(uint8_t index, uint16_t value)
-{
- *motors[index].ccr = lrintf((float)(value * ONESHOT42_TIMER_MHZ/24.0f));
-}
-
-static void pwmWriteMultiShot(uint8_t index, uint16_t value)
-{
- *motors[index].ccr = lrintf(((float)(value-1000) * MULTISHOT_20US_MULT) + MULTISHOT_5US_PW);
-}
-
-void pwmWriteMotor(uint8_t index, uint16_t value)
-{
- pwmWritePtr(index, value);
-}
-
-void pwmShutdownPulsesForAllMotors(uint8_t motorCount)
-{
- for (int index = 0; index < motorCount; index++) {
- // Set the compare register to 0, which stops the output pulsing if the timer overflows
- *motors[index].ccr = 0;
- }
-}
-
-void pwmDisableMotors(void)
-{
- pwmMotorsEnabled = false;
-}
-
-void pwmEnableMotors(void)
-{
- pwmMotorsEnabled = true;
-}
-
-bool pwmAreMotorsEnabled(void)
-{
- return pwmMotorsEnabled;
-}
-
-static void pwmCompleteOneshotMotorUpdate(uint8_t motorCount)
-{
- for (int index = 0; index < motorCount; index++) {
- bool overflowed = false;
- // If we have not already overflowed this timer
- for (int j = 0; j < index; j++) {
- if (motors[j].tim == motors[index].tim) {
- overflowed = true;
- break;
- }
- }
- if (!overflowed) {
- timerForceOverflow(motors[index].tim);
- }
- // Set the compare register to 0, which stops the output pulsing if the timer overflows before the main loop completes again.
- // This compare register will be set to the output value on the next main loop.
- *motors[index].ccr = 0;
- }
-}
-
-void pwmCompleteMotorUpdate(uint8_t motorCount)
-{
- if (pwmCompleteWritePtr) {
- pwmCompleteWritePtr(motorCount);
- }
-}
-
-void motorInit(const motorConfig_t *motorConfig, uint16_t idlePulse, uint8_t motorCount)
-{
- uint32_t timerMhzCounter;
- bool useUnsyncedPwm = motorConfig->useUnsyncedPwm;
- bool isDigital = false;
-
- switch (motorConfig->motorPwmProtocol) {
- default:
- case PWM_TYPE_ONESHOT125:
- timerMhzCounter = ONESHOT125_TIMER_MHZ;
- pwmWritePtr = pwmWriteOneShot125;
- break;
- case PWM_TYPE_ONESHOT42:
- timerMhzCounter = ONESHOT42_TIMER_MHZ;
- pwmWritePtr = pwmWriteOneShot42;
- break;
- case PWM_TYPE_MULTISHOT:
- timerMhzCounter = MULTISHOT_TIMER_MHZ;
- pwmWritePtr = pwmWriteMultiShot;
- break;
- case PWM_TYPE_BRUSHED:
- timerMhzCounter = PWM_BRUSHED_TIMER_MHZ;
- pwmWritePtr = pwmWriteBrushed;
- useUnsyncedPwm = true;
- idlePulse = 0;
- break;
- case PWM_TYPE_STANDARD:
- timerMhzCounter = PWM_TIMER_MHZ;
- pwmWritePtr = pwmWriteStandard;
- useUnsyncedPwm = true;
- idlePulse = 0;
- break;
-#ifdef USE_DSHOT
- case PWM_TYPE_DSHOT600:
- case PWM_TYPE_DSHOT300:
- case PWM_TYPE_DSHOT150:
- pwmWritePtr = pwmWriteDigital;
- pwmCompleteWritePtr = pwmCompleteDigitalMotorUpdate;
- isDigital = true;
- break;
-#endif
- }
-
- if (!useUnsyncedPwm && !isDigital) {
- pwmCompleteWritePtr = pwmCompleteOneshotMotorUpdate;
- }
-
- for (int motorIndex = 0; motorIndex < MAX_SUPPORTED_MOTORS && motorIndex < motorCount; motorIndex++) {
- const ioTag_t tag = motorConfig->ioTags[motorIndex];
-
- if (!tag) {
- break;
- }
-
- const timerHardware_t *timerHardware = timerGetByTag(tag, TIM_USE_ANY);
-
- if (timerHardware == NULL) {
- /* flag failure and disable ability to arm */
- break;
- }
-
-#ifdef USE_DSHOT
- if (isDigital) {
- pwmDigitalMotorHardwareConfig(timerHardware, motorIndex, motorConfig->motorPwmProtocol);
- motors[motorIndex].enabled = true;
- continue;
- }
-#endif
- motors[motorIndex].io = IOGetByTag(tag);
-
- IOInit(motors[motorIndex].io, OWNER_MOTOR, RESOURCE_INDEX(motorIndex));
- //IOConfigGPIO(motors[motorIndex].io, IOCFG_AF_PP);
- IOConfigGPIOAF(motors[motorIndex].io, IOCFG_AF_PP, timerHardware->alternateFunction);
-
- if (useUnsyncedPwm) {
- const uint32_t hz = timerMhzCounter * 1000000;
- pwmOutConfig(&motors[motorIndex], timerHardware, timerMhzCounter, hz / motorConfig->motorPwmProtocol, idlePulse);
- } else {
- pwmOutConfig(&motors[motorIndex], timerHardware, timerMhzCounter, 0xFFFF, 0);
- }
- motors[motorIndex].enabled = true;
- }
- pwmMotorsEnabled = true;
-}
-
-pwmOutputPort_t *pwmGetMotors(void)
-{
- return motors;
-}
-
-#ifdef USE_SERVOS
-void pwmWriteServo(uint8_t index, uint16_t value)
-{
- if (index < MAX_SUPPORTED_SERVOS && servos[index].ccr) {
- *servos[index].ccr = value;
- }
-}
-
-void servoInit(const servoConfig_t *servoConfig)
-{
- for (uint8_t servoIndex = 0; servoIndex < MAX_SUPPORTED_SERVOS; servoIndex++) {
- const ioTag_t tag = servoConfig->ioTags[servoIndex];
-
- if (!tag) {
- break;
- }
-
- servos[servoIndex].io = IOGetByTag(tag);
-
- IOInit(servos[servoIndex].io, OWNER_SERVO, RESOURCE_INDEX(servoIndex));
- //IOConfigGPIO(servos[servoIndex].io, IOCFG_AF_PP);
-
- const timerHardware_t *timer = timerGetByTag(tag, TIM_USE_ANY);
- IOConfigGPIOAF(servos[servoIndex].io, IOCFG_AF_PP, timer->alternateFunction);
-
- if (timer == NULL) {
- /* flag failure and disable ability to arm */
- break;
- }
-
- pwmOutConfig(&servos[servoIndex], timer, PWM_TIMER_MHZ, 1000000 / servoConfig->servoPwmRate, servoConfig->servoCenterPulse);
- servos[servoIndex].enabled = true;
- }
-}
-
-#endif