diff --git a/src/main/drivers/at32/timer_at32bsp.c b/src/main/drivers/at32/timer_at32bsp.c index 8cd0109f62..dd665d6c5c 100644 --- a/src/main/drivers/at32/timer_at32bsp.c +++ b/src/main/drivers/at32/timer_at32bsp.c @@ -671,6 +671,10 @@ _TIM_IRQ_HANDLER(TMR20_CH_IRQnHandler, 20); #endif +void timerIOInit(void) +{ +} + void timerInit(void) { memset(timerConfig, 0, sizeof(timerConfig)); diff --git a/src/main/drivers/stm32/timer_hal.c b/src/main/drivers/stm32/timer_hal.c index 6f11c522e0..dd84b81575 100644 --- a/src/main/drivers/stm32/timer_hal.c +++ b/src/main/drivers/stm32/timer_hal.c @@ -1028,14 +1028,6 @@ void timerInit(void) RCC_ClockCmd(timerRCC(TIMER_HARDWARE[i].tim), ENABLE); } -#if defined(STM32F4) || defined(STM32F7) || defined(STM32H7) - for (unsigned timerIndex = 0; timerIndex < TIMER_CHANNEL_COUNT; timerIndex++) { - const timerHardware_t *timerHardwarePtr = &TIMER_HARDWARE[timerIndex]; - // XXX IOConfigGPIOAF in timerInit should eventually go away. - IOConfigGPIOAF(IOGetByTag(timerHardwarePtr->tag), IOCFG_AF_PP, timerHardwarePtr->alternateFunction); - } -#endif - /* enable the timer peripherals */ for (unsigned i = 0; i < TIMER_CHANNEL_COUNT; i++) { RCC_ClockCmd(timerRCC(TIMER_HARDWARE[i].tim), ENABLE); @@ -1051,6 +1043,17 @@ void timerInit(void) } } +void timerIOInit(void) +{ +#if defined(STM32F4) || defined(STM32F7) || defined(STM32H7) + for (unsigned timerIndex = 0; timerIndex < TIMER_CHANNEL_COUNT; timerIndex++) { + const timerHardware_t *timerHardwarePtr = &TIMER_HARDWARE[timerIndex]; + // XXX IOConfigGPIOAF in timerInit should eventually go away. + IOConfigGPIOAF(IOGetByTag(timerHardwarePtr->tag), IOCFG_AF_PP, timerHardwarePtr->alternateFunction); + } +#endif +} + // finish configuring timers after allocation phase // start timers // TODO - Work in progress - initialization routine must be modified/verified to start correctly without timers diff --git a/src/main/drivers/stm32/timer_stdperiph.c b/src/main/drivers/stm32/timer_stdperiph.c index ec0e008c2d..5361d74abd 100644 --- a/src/main/drivers/stm32/timer_stdperiph.c +++ b/src/main/drivers/stm32/timer_stdperiph.c @@ -851,6 +851,10 @@ void timerInit(void) } } +void timerIOInit(void) +{ + // No-op +} // finish configuring timers after allocation phase // start timers // TODO - Work in progress - initialization routine must be modified/verified to start correctly without timers diff --git a/src/main/drivers/timer.h b/src/main/drivers/timer.h index f5cff8254c..34c4803914 100644 --- a/src/main/drivers/timer.h +++ b/src/main/drivers/timer.h @@ -127,6 +127,7 @@ void timerConfigure(const timerHardware_t *timHw, uint16_t period, uint32_t hz); // Initialisation // void timerInit(void); +void timerIOInit(void); void timerStart(void); // diff --git a/src/main/fc/init.c b/src/main/fc/init.c index 88a3470abe..13f579f96d 100644 --- a/src/main/fc/init.c +++ b/src/main/fc/init.c @@ -271,6 +271,15 @@ void init(void) // initialize IO (needed for all IO operations) IOInitGlobal(); +#ifdef USE_TIMER + // timerIOInit blindly reconfigures GPIO AF for all pins in the fullTimerHardware array regardless + // of if the timer pin is used already by something else. + // If it is called AFTER the SPI initilisation, any AF settings for the SPI are overridden by timer + // AF, making the SPI hang when it's used. + // To work-around this issue init timer AF before other AF, such as SPI/QSPI/OSPI/etc. + timerIOInit(); +#endif + #ifdef USE_HARDWARE_REVISION_DETECTION detectHardwareRevision(); #endif diff --git a/src/main/target/SITL/sitl.c b/src/main/target/SITL/sitl.c index 4302bf20aa..808a412bfd 100644 --- a/src/main/target/SITL/sitl.c +++ b/src/main/target/SITL/sitl.c @@ -358,6 +358,10 @@ void timerInit(void) printf("[timer]Init...\n"); } +void timerIOInit(void) +{ +} + void timerStart(void) { }