From e9aaff808ee4d55f9220c117d301eab6f4c26d05 Mon Sep 17 00:00:00 2001 From: Ben Hitchcock Date: Mon, 1 Dec 2014 22:43:17 +0800 Subject: [PATCH] Updates to the way that timers are forced to overflow in oneshot mode. Now the current count value is saved, and then passed to the listeners. This _should_ mean that CC3D PPM might work this time. --- src/main/drivers/pwm_output.c | 3 +-- src/main/drivers/timer.c | 26 +++++++++++++++++++++++++- src/main/drivers/timer.h | 2 ++ 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/main/drivers/pwm_output.c b/src/main/drivers/pwm_output.c index 098f76df3..9d4162cb3 100644 --- a/src/main/drivers/pwm_output.c +++ b/src/main/drivers/pwm_output.c @@ -154,8 +154,7 @@ void pwmFinishedWritingMotors(uint8_t numberMotors) if(motors[index]->tim != lastTimerPtr){ lastTimerPtr = motors[index]->tim; - // Force an overflow by setting the UG bit - motors[index]->tim->EGR |= 0x0001; + timerForceOverflow(motors[index]->tim); } } diff --git a/src/main/drivers/timer.c b/src/main/drivers/timer.c index 2178db42a..b7bfda521 100644 --- a/src/main/drivers/timer.c +++ b/src/main/drivers/timer.c @@ -216,6 +216,7 @@ typedef struct timerConfig_s { timerCCHandlerRec_t *edgeCallback[CC_CHANNELS_PER_TIMER]; timerOvrHandlerRec_t *overflowCallback[CC_CHANNELS_PER_TIMER]; timerOvrHandlerRec_t *overflowCallbackActive; // null-terminated linkded list of active overflow callbacks + uint32_t forcedOverflowTimerValue; } timerConfig_t; timerConfig_t timerConfig[USED_TIMER_COUNT]; @@ -612,7 +613,14 @@ static void timCCxHandler(TIM_TypeDef *tim, timerConfig_t *timerConfig) tim_status &= mask; switch(bit) { case __builtin_clz(TIM_IT_Update): - capture = tim->ARR; + + if(timerConfig->forcedOverflowTimerValue != 0){ + capture = timerConfig->forcedOverflowTimerValue - 1; + timerConfig->forcedOverflowTimerValue = 0; + } else { + capture = tim->ARR; + } + timerOvrHandlerRec_t *cb = timerConfig->overflowCallbackActive; while(cb) { cb->fn(cb, capture); @@ -789,3 +797,19 @@ void timerStart(void) } #endif } + +/** + * Force an overflow for a given timer. + * Saves the current value of the counter in the relevant timerConfig's forcedOverflowTimerValue variable. + * @param TIM_Typedef *tim The timer to overflow + * @return void + **/ +void timerForceOverflow(volatile TIM_TypeDef *tim) +{ + // Save the current count so that PPM reading will work on the same timer that was forced to overflow + uint8_t timerIndex = lookupTimerIndex((const TIM_TypeDef *)tim); + timerConfig[timerIndex].forcedOverflowTimerValue = tim->CNT + 1; + + // Force an overflow by setting the UG bit + tim->EGR |= 0x0001; +} \ No newline at end of file diff --git a/src/main/drivers/timer.h b/src/main/drivers/timer.h index 08fbab597..e0cd23a14 100644 --- a/src/main/drivers/timer.h +++ b/src/main/drivers/timer.h @@ -117,5 +117,7 @@ void timerChInit(const timerHardware_t *timHw, channelType_t type, int irqPriori void timerInit(void); void timerStart(void); +void timerForceOverflow(volatile TIM_TypeDef *tim); void configTimeBase(TIM_TypeDef *tim, uint16_t period, uint8_t mhz); // TODO - just for migration +