diff --git a/src/config.c b/src/config.c index 5780f47432..de584d06ad 100755 --- a/src/config.c +++ b/src/config.c @@ -449,3 +449,10 @@ uint32_t featureMask(void) return masterConfig.enabledFeatures; } +bool canSoftwareSerialBeUsed(void) +{ + // FIXME this is not ideal because it means you can't disable parallel PWM input even when using spektrum/sbus etc. + // really we want to say 'return !feature(FEATURE_PARALLEL_PWM);' + return feature(FEATURE_SOFTSERIAL) && feature(FEATURE_PPM); // Software serial can only be used in PPM mode because parallel PWM uses the same hardware pins/timers +} + diff --git a/src/config.h b/src/config.h index b3267562bf..8e8b968a8d 100644 --- a/src/config.h +++ b/src/config.h @@ -32,3 +32,5 @@ void readEEPROMAndNotify(void); void writeEEPROM(); void ensureEEPROMContainsValidData(void); void saveAndReloadCurrentProfileToCurrentProfileSlot(void); + +bool canSoftwareSerialBeUsed(void); diff --git a/src/drivers/gpio_common.h b/src/drivers/gpio_common.h index ad219c2147..054ee689f4 100644 --- a/src/drivers/gpio_common.h +++ b/src/drivers/gpio_common.h @@ -48,7 +48,9 @@ typedef enum Mode_Out_OD = (GPIO_OType_OD << 4) | GPIO_Mode_OUT, Mode_Out_PP = (GPIO_OType_PP << 4) | GPIO_Mode_OUT, Mode_AF_OD = (GPIO_OType_OD << 4) | GPIO_Mode_AF, - Mode_AF_PP = (GPIO_OType_PP << 4) | GPIO_Mode_AF + Mode_AF_PP = (GPIO_OType_PP << 4) | GPIO_Mode_AF, + Mode_AF_PP_PD = (GPIO_OType_PP << 4) | (GPIO_PuPd_DOWN << 2) | GPIO_Mode_AF, + Mode_AF_PP_PU = (GPIO_OType_PP << 4) | (GPIO_PuPd_UP << 2) | GPIO_Mode_AF } GPIO_Mode; #endif diff --git a/src/drivers/gpio_stm32f30x.c b/src/drivers/gpio_stm32f30x.c index a25fb88f1e..4cbca0339c 100644 --- a/src/drivers/gpio_stm32f30x.c +++ b/src/drivers/gpio_stm32f30x.c @@ -13,20 +13,6 @@ #define MODE_MASK ((1|2) << MODE_OFFSET) #define PUPD_MASK ((1|2) << PUPD_OFFSET) #define OUTPUT_MASK ((1|2) << OUTPUT_OFFSET) -/* -typedef enum -{ - Mode_AIN = (GPIO_PuPd_NOPULL << 2) | GPIO_Mode_AN, - Mode_IN_FLOATING = (GPIO_PuPd_NOPULL << 2) | GPIO_Mode_IN, - Mode_IPD = (GPIO_PuPd_DOWN << 2) | GPIO_Mode_IN, - Mode_IPU = (GPIO_PuPd_UP << 2) | GPIO_Mode_IN, - Mode_Out_OD = (GPIO_OType_OD << 4) | GPIO_Mode_OUT, - Mode_Out_PP = (GPIO_OType_PP << 4) | GPIO_Mode_OUT, - Mode_AF_OD = (GPIO_OType_OD << 4) | GPIO_Mode_AF, - Mode_AF_PP = (GPIO_OType_PP << 4) | GPIO_Mode_AF -} GPIO_Mode; - -*/ //#define GPIO_Speed_10MHz GPIO_Speed_Level_1 Fast Speed:10MHz //#define GPIO_Speed_2MHz GPIO_Speed_Level_2 Medium Speed:2MHz diff --git a/src/drivers/pwm_common.c b/src/drivers/pwm_common.c index 338a4a131f..7c5b8054b3 100755 --- a/src/drivers/pwm_common.c +++ b/src/drivers/pwm_common.c @@ -59,9 +59,9 @@ typedef struct { // for input only uint8_t channel; uint8_t state; - uint16_t rise; - uint16_t fall; - uint16_t capture; + captureCompare_t rise; + captureCompare_t fall; + captureCompare_t capture; } pwmPortData_t; enum { @@ -261,11 +261,12 @@ static pwmPortData_t *pwmInConfig(uint8_t port, timerCCCallbackPtr callback, uin return p; } -static void ppmCallback(uint8_t port, uint16_t capture) +static void ppmCallback(uint8_t port, captureCompare_t capture) { - uint16_t diff; - static uint16_t now; - static uint16_t last = 0; + captureCompare_t diff; + static captureCompare_t now; + static captureCompare_t last = 0; + static uint8_t chan = 0; static uint8_t GoodPulses; @@ -290,7 +291,7 @@ static void ppmCallback(uint8_t port, uint16_t capture) } } -static void pwmCallback(uint8_t port, uint16_t capture) +static void pwmCallback(uint8_t port, captureCompare_t capture) { if (pwmPorts[port].state == 0) { pwmPorts[port].rise = capture; @@ -380,11 +381,16 @@ void pwmInit(drv_pwm_config_t *init, failsafe_t *initialFailsafe) mask = TYPE_S; #endif #ifdef STM32F303xC - // remap PWM5+6 as servos - if (port == PWM5 || port == PWM6) - mask = TYPE_S; -#endif + // remap PWM 5+6 or 9+10 as servos - softserial pin pairs timer ports that use the same timer + if (init->useSoftSerial) { + if (port == PWM5 || port == PWM6) + mask = TYPE_S; + } else { + if (port == PWM9 || port == PWM10) + mask = TYPE_S; } +#endif + } if (init->extraServos && !init->airplane) { // remap PWM5..8 as servos when used in extended servo mode diff --git a/src/drivers/serial_softserial.c b/src/drivers/serial_softserial.c index cf5604f74a..6c4ac8ddb0 100644 --- a/src/drivers/serial_softserial.c +++ b/src/drivers/serial_softserial.c @@ -32,8 +32,8 @@ softSerial_t softSerialPorts[MAX_SOFTSERIAL_PORTS]; -void onSerialTimer(uint8_t portIndex, uint16_t capture); -void onSerialRxPinChange(uint8_t portIndex, uint16_t capture); +void onSerialTimer(uint8_t portIndex, captureCompare_t capture); +void onSerialRxPinChange(uint8_t portIndex, captureCompare_t capture); void setTxSignal(softSerial_t *softSerial, uint8_t state) { @@ -335,7 +335,7 @@ void processRxState(softSerial_t *softSerial) } } -void onSerialTimer(uint8_t portIndex, uint16_t capture) +void onSerialTimer(uint8_t portIndex, captureCompare_t capture) { softSerial_t *softSerial = &(softSerialPorts[portIndex]); @@ -343,7 +343,7 @@ void onSerialTimer(uint8_t portIndex, uint16_t capture) processRxState(softSerial); } -void onSerialRxPinChange(uint8_t portIndex, uint16_t capture) +void onSerialRxPinChange(uint8_t portIndex, captureCompare_t capture) { softSerial_t *softSerial = &(softSerialPorts[portIndex]); diff --git a/src/drivers/timer_common.c b/src/drivers/timer_common.c index e08764e1a8..8804d5935d 100644 --- a/src/drivers/timer_common.c +++ b/src/drivers/timer_common.c @@ -1,6 +1,8 @@ #include #include +#include +#include #include "platform.h" @@ -75,48 +77,25 @@ static const TIM_TypeDef *timers[MAX_TIMERS] = { #endif - -// Parallel PWM Inputs -// RX1 TIM1_CH1 PA8 -// RX2 TIM16_CH1 PB8 -// RX3 TIM17_CH1 PB9 -// RX4 TIM8_CH1 PC6 -// RX5 TIM8_CH2 PC7 -// RX6 TIM8_CH3 PC8 -// RX7 TIM15_CH1 PF9 -// RX8 TIM15_CH2 PF10 - -// Servo PWM1 TIM3_CH3 PB0 -// Servo PWM2 TIM3_CH4 PB1 -// Servo PWM3 TIM3_CH2 PA4 - -// ESC PWM1 TIM4_CH1 PD12 -// ESC PWM2 TIM4_CH2 PD13 -// ESC PWM3 TIM4_CH3 PD14 -// ESC PWM4 TIM4_CH4 PD15 -// ESC PWM5 TIM2_CH2 PA1 -// ESC PWM6 TIM2_CH3 PA2 - - #if defined(STM32F303xC) || defined(STM32F3DISCOVERY) const timerHardware_t timerHardware[USABLE_TIMER_CHANNEL_COUNT] = { - { TIM1, GPIOA, Pin_8, TIM_Channel_1, TIM1_CC_IRQn, 1, Mode_AF_PP}, // PWM1 - { TIM16, GPIOB, Pin_8, TIM_Channel_1, TIM1_UP_TIM16_IRQn, 0, Mode_AF_PP}, // PWM2 - { TIM17, GPIOB, Pin_9, TIM_Channel_1, TIM1_TRG_COM_TIM17_IRQn, 0, Mode_AF_PP}, // PWM3 - { TIM8, GPIOC, Pin_6, TIM_Channel_1, TIM8_CC_IRQn, 1, Mode_AF_PP}, // PWM4 - { TIM8, GPIOC, Pin_7, TIM_Channel_2, TIM8_CC_IRQn, 1, Mode_AF_PP}, // PWM5 - { TIM8, GPIOC, Pin_8, TIM_Channel_3, TIM8_CC_IRQn, 1, Mode_AF_PP}, // PWM6 - //{ TIM15, GPIOF, Pin_9, TIM_Channel_1, TIM1_BRK_TIM15_IRQn, 0, }, // PWM1 - Potential alternate, untested - //{ TIM15, GPIOF, Pin_10, TIM_Channel_2, TIM1_BRK_TIM15_IRQn, 0, }, // PWM1 - Potential alternate, untested - { TIM3, GPIOB, Pin_1, TIM_Channel_4, TIM3_IRQn, 0, Mode_AF_PP}, // PWM7 - { TIM3, GPIOA, Pin_4, TIM_Channel_2, TIM3_IRQn, 0, Mode_AF_PP}, // PWM8 - { TIM4, GPIOD, Pin_12, TIM_Channel_1, TIM4_IRQn, 0, Mode_AF_PP}, // PWM9 - { TIM4, GPIOD, Pin_13, TIM_Channel_2, TIM4_IRQn, 0, Mode_AF_PP}, // PWM10 - { TIM4, GPIOD, Pin_14, TIM_Channel_3, TIM4_IRQn, 0, Mode_AF_PP}, // PWM11 - { TIM4, GPIOD, Pin_15, TIM_Channel_4, TIM4_IRQn, 0, Mode_AF_PP}, // PWM12 - { TIM2, GPIOA, Pin_1, TIM_Channel_2, TIM2_IRQn, 0, Mode_AF_PP}, // PWM13 - { TIM2, GPIOA, Pin_2, TIM_Channel_3, TIM2_IRQn, 0, Mode_AF_PP}, // PWM14 + { TIM1, GPIOA, Pin_8, TIM_Channel_1, TIM1_CC_IRQn, 1, Mode_AF_PP_PD}, // PWM1 - PA8 + { TIM16, GPIOB, Pin_8, TIM_Channel_1, TIM1_UP_TIM16_IRQn, 0, Mode_AF_PP_PD}, // PWM2 - PB8 + { TIM17, GPIOB, Pin_9, TIM_Channel_1, TIM1_TRG_COM_TIM17_IRQn, 0, Mode_AF_PP_PD}, // PWM3 - PB9 + { TIM8, GPIOC, Pin_6, TIM_Channel_1, TIM8_CC_IRQn, 1, Mode_AF_PP_PD}, // PWM4 - PC6 + { TIM8, GPIOC, Pin_7, TIM_Channel_2, TIM8_CC_IRQn, 1, Mode_AF_PP_PD}, // PWM5 - PC7 + { TIM8, GPIOC, Pin_8, TIM_Channel_3, TIM8_CC_IRQn, 1, Mode_AF_PP_PD}, // PWM6 - PC8 + { TIM3, GPIOB, Pin_1, TIM_Channel_4, TIM3_IRQn, 0, Mode_AF_PP_PD}, // PWM7 - PB1 + { TIM3, GPIOA, Pin_4, TIM_Channel_2, TIM3_IRQn, 0, Mode_AF_PP_PD}, // PWM8 - PA2 + //{ TIM15, GPIOF, Pin_9, TIM_Channel_1, TIM1_BRK_TIM15_IRQn, 0, }, // PWMx - PF9 Potential alternate, untested + //{ TIM15, GPIOF, Pin_10, TIM_Channel_2, TIM1_BRK_TIM15_IRQn, 0, }, // PWMx - PF10 Potential alternate, untested + { TIM4, GPIOD, Pin_12, TIM_Channel_1, TIM4_IRQn, 0, Mode_AF_PP}, // PWM9 - PD12 + { TIM4, GPIOD, Pin_13, TIM_Channel_2, TIM4_IRQn, 0, Mode_AF_PP}, // PWM10 - PD13 + { TIM4, GPIOD, Pin_14, TIM_Channel_3, TIM4_IRQn, 0, Mode_AF_PP}, // PWM11 - PD14 + { TIM4, GPIOD, Pin_15, TIM_Channel_4, TIM4_IRQn, 0, Mode_AF_PP}, // PWM12 - PD15 + { TIM2, GPIOA, Pin_1, TIM_Channel_2, TIM2_IRQn, 0, Mode_AF_PP}, // PWM13 - PA1 + { TIM2, GPIOA, Pin_2, TIM_Channel_3, TIM2_IRQn, 0, Mode_AF_PP}, // PWM14 - PA2 }; #define MAX_TIMERS 7 @@ -127,7 +106,7 @@ static const TIM_TypeDef *timers[MAX_TIMERS] = { #endif #define CC_CHANNELS_PER_TIMER 4 // TIM_Channel_1..4 -static const uint8_t channels[CC_CHANNELS_PER_TIMER] = { +static const uint16_t channels[CC_CHANNELS_PER_TIMER] = { TIM_Channel_1, TIM_Channel_2, TIM_Channel_3, TIM_Channel_4 }; @@ -149,7 +128,7 @@ static uint8_t lookupTimerIndex(const TIM_TypeDef *tim) return timerIndex; } -static uint8_t lookupChannelIndex(const uint8_t channel) +static uint8_t lookupChannelIndex(const uint16_t channel) { uint8_t channelIndex = 0; while (channels[channelIndex] != channel) { @@ -158,11 +137,16 @@ static uint8_t lookupChannelIndex(const uint8_t channel) return channelIndex; } +static uint8_t lookupTimerConfigIndex(TIM_TypeDef *tim, const uint16_t channel) +{ + return lookupTimerIndex(tim) + (MAX_TIMERS * lookupChannelIndex(channel)); +} + void configureTimerChannelCallback(TIM_TypeDef *tim, uint8_t channel, uint8_t reference, timerCCCallbackPtr *callback) { assert_param(IS_TIM_CHANNEL(channel)); - uint8_t timerConfigIndex = (lookupTimerIndex(tim) * MAX_TIMERS) + lookupChannelIndex(channel); + uint8_t timerConfigIndex = lookupTimerConfigIndex(tim, channel); if (timerConfigIndex >= MAX_TIMERS * CC_CHANNELS_PER_TIMER) { return; @@ -232,16 +216,15 @@ void timerConfigure(const timerHardware_t *timerHardwarePtr, uint16_t period, ui timerNVICConfigure(timerHardwarePtr->irq); } - -timerConfig_t *findTimerConfig(TIM_TypeDef *tim, uint8_t channel) +timerConfig_t *findTimerConfig(TIM_TypeDef *tim, uint16_t channel) { - uint8_t timerConfigIndex = (lookupTimerIndex(tim) * MAX_TIMERS) + lookupChannelIndex(channel); + uint8_t timerConfigIndex = lookupTimerConfigIndex(tim, channel); return &(timerConfig[timerConfigIndex]); } static void timCCxHandler(TIM_TypeDef *tim) { - uint16_t capture; + captureCompare_t capture; timerConfig_t *timerConfig; uint8_t channelIndex = 0; @@ -300,7 +283,7 @@ void TIM4_IRQHandler(void) } #if defined(STM32F303xC) || defined(STM32F3DISCOVERY) -void TIM8_IRQHandler(void) +void TIM8_CC_IRQHandler(void) { timCCxHandler(TIM8); } @@ -322,3 +305,8 @@ void TIM1_TRG_COM_TIM17_IRQHandler(void) timCCxHandler(TIM17); } #endif + +void timerInit(void) +{ + memset(timerConfig, 0, sizeof (timerConfig)); +} diff --git a/src/drivers/timer_common.h b/src/drivers/timer_common.h index 385f7c6a1f..320c072984 100644 --- a/src/drivers/timer_common.h +++ b/src/drivers/timer_common.h @@ -2,7 +2,14 @@ #define USABLE_TIMER_CHANNEL_COUNT 14 -typedef void timerCCCallbackPtr(uint8_t port, uint16_t capture); +#ifdef STM32F303xC +typedef uint32_t captureCompare_t; +#endif +#ifdef STM32F10X_MD +typedef uint32_t captureCompare_t; +#endif + +typedef void timerCCCallbackPtr(uint8_t port, captureCompare_t capture); typedef struct { TIM_TypeDef *tim; diff --git a/src/main.c b/src/main.c index df86882a3d..f81718f01a 100755 --- a/src/main.c +++ b/src/main.c @@ -49,6 +49,7 @@ extern uint32_t previousTime; failsafe_t *failsafe; +void timerInit(void); void initTelemetry(serialPorts_t *serialPorts); void serialInit(serialConfig_t *initialSerialConfig); failsafe_t* failsafeInit(rxConfig_t *intialRxConfig); @@ -97,7 +98,7 @@ int main(void) else pwm_params.airplane = false; pwm_params.useUART = feature(FEATURE_GPS) || feature(FEATURE_SERIALRX); // serial rx support uses UART too - pwm_params.useSoftSerial = feature(FEATURE_SOFTSERIAL); + pwm_params.useSoftSerial = canSoftwareSerialBeUsed(); pwm_params.usePPM = feature(FEATURE_PPM); pwm_params.enableInput = !feature(FEATURE_SERIALRX); // disable inputs if using spektrum pwm_params.useServos = isMixerUsingServos(); @@ -126,6 +127,7 @@ int main(void) failsafe = failsafeInit(&masterConfig.rxConfig); buzzerInit(failsafe); + timerInit(); pwmInit(&pwm_params, failsafe); rxInit(&masterConfig.rxConfig, failsafe); @@ -171,7 +173,7 @@ int main(void) serialInit(&masterConfig.serialConfig); #ifndef FY90Q - if (feature(FEATURE_SOFTSERIAL)) { + if (canSoftwareSerialBeUsed()) { //mcfg.softserial_baudrate = 19200; // Uncomment to override config value setupSoftSerialPrimary(masterConfig.serialConfig.softserial_baudrate, masterConfig.serialConfig.softserial_1_inverted); diff --git a/src/telemetry_common.c b/src/telemetry_common.c index 63e7ee3605..432b6a5e66 100644 --- a/src/telemetry_common.c +++ b/src/telemetry_common.c @@ -62,7 +62,7 @@ bool canUseTelemetryWithCurrentConfiguration(void) void initTelemetry(serialPorts_t *serialPorts) { // Force telemetry to uart when softserial disabled - if (!feature(FEATURE_SOFTSERIAL)) + if (canSoftwareSerialBeUsed()) telemetryConfig->telemetry_port = TELEMETRY_PORT_UART; #ifdef FY90Q