From caa51253db04cb6090ec3e5dc2cd318e9f433d8e Mon Sep 17 00:00:00 2001 From: Alessio Morale Date: Mon, 19 Jan 2015 21:55:40 +0100 Subject: [PATCH] OP-1682 - Workaround overflow issue with pwm receiver inputs on shared timers. --- flight/pios/inc/pios_pwm.h | 2 ++ flight/pios/stm32f10x/pios_pwm.c | 19 ++++++++++++------- flight/pios/stm32f10x/pios_tim.c | 24 +++++++++++------------- 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/flight/pios/inc/pios_pwm.h b/flight/pios/inc/pios_pwm.h index 3552319c9..da3de8409 100644 --- a/flight/pios/inc/pios_pwm.h +++ b/flight/pios/inc/pios_pwm.h @@ -30,4 +30,6 @@ #ifndef PIOS_PWM_H #define PIOS_PWM_H +#define PIOS_PWM_VALID_RANGE_MAX 2250 +#define PIOS_PWM_VALID_RANGE_MIN 750 #endif /* PIOS_PWM_H */ diff --git a/flight/pios/stm32f10x/pios_pwm.c b/flight/pios/stm32f10x/pios_pwm.c index a583414bd..f29204fed 100644 --- a/flight/pios/stm32f10x/pios_pwm.c +++ b/flight/pios/stm32f10x/pios_pwm.c @@ -209,8 +209,10 @@ static void PIOS_PWM_tim_overflow_cb(__attribute__((unused)) uint32_t tim_id, ui /* Channel out of range */ return; } - - pwm_dev->us_since_update[channel] += count; + if (!pwm_dev->CaptureState[channel]) { + return; + } + pwm_dev->us_since_update[channel] = +count; if (pwm_dev->us_since_update[channel] >= PWM_SUPERVISOR_TIMEOUT) { pwm_dev->CaptureState[channel] = 0; pwm_dev->RiseValue[channel] = 0; @@ -256,16 +258,19 @@ static void PIOS_PWM_tim_edge_cb(__attribute__((unused)) uint32_t tim_id, uint32 TIM_ICInitStructure.TIM_Channel = chan->timer_chan; TIM_ICInit(chan->timer, &TIM_ICInitStructure); } else { + uint32_t value = 0; /* Capture computation */ if (pwm_dev->FallValue[chan_idx] > pwm_dev->RiseValue[chan_idx]) { - pwm_dev->CaptureValue[chan_idx] = (pwm_dev->FallValue[chan_idx] - pwm_dev->RiseValue[chan_idx]); + value = pwm_dev->us_since_update[chan_idx] + (pwm_dev->FallValue[chan_idx] - pwm_dev->RiseValue[chan_idx]); } else { - pwm_dev->CaptureValue[chan_idx] = ((chan->timer->ARR - pwm_dev->RiseValue[chan_idx]) + pwm_dev->FallValue[chan_idx]); + value = pwm_dev->us_since_update[chan_idx] + (pwm_dev->FallValue[chan_idx] - pwm_dev->RiseValue[chan_idx]); + } + if (PIOS_PWM_VALID_RANGE_MAX > value && PIOS_PWM_VALID_RANGE_MIN < value) { + pwm_dev->CaptureValue[chan_idx] = value; } - /* Switch states */ - pwm_dev->CaptureState[chan_idx] = 0; - + pwm_dev->CaptureState[chan_idx] = 0; + pwm_dev->us_since_update[chan_idx] = 0; /* Increase supervisor counter */ pwm_dev->CapCounter[chan_idx]++; diff --git a/flight/pios/stm32f10x/pios_tim.c b/flight/pios/stm32f10x/pios_tim.c index d585c3fd7..ca9bd6254 100644 --- a/flight/pios/stm32f10x/pios_tim.c +++ b/flight/pios/stm32f10x/pios_tim.c @@ -159,6 +159,16 @@ out_fail: static void PIOS_TIM_generic_irq_handler(TIM_TypeDef *timer) { + /* Check for an overflow event on this timer */ + bool overflow_event = 0; + uint16_t overflow_count = false; + + if (TIM_GetITStatus(timer, TIM_IT_Update) == SET) { + TIM_ClearITPendingBit(timer, TIM_IT_Update); + overflow_count = timer->ARR; + overflow_event = true; + } + /* Iterate over all registered clients of the TIM layer to find channels on this timer */ for (uint8_t i = 0; i < pios_tim_num_devs; i++) { const struct pios_tim_dev *tim_dev = &pios_tim_devs[i]; @@ -168,18 +178,6 @@ static void PIOS_TIM_generic_irq_handler(TIM_TypeDef *timer) continue; } - /* Check for an overflow event on this timer */ - bool overflow_event; - uint16_t overflow_count; - if (TIM_GetITStatus(timer, TIM_IT_Update) == SET) { - TIM_ClearITPendingBit(timer, TIM_IT_Update); - overflow_count = timer->ARR; - overflow_event = true; - } else { - overflow_count = 0; - overflow_event = false; - } - for (uint8_t j = 0; j < tim_dev->num_channels; j++) { const struct pios_tim_channel *chan = &tim_dev->channels[j]; @@ -255,7 +253,7 @@ static void PIOS_TIM_generic_irq_handler(TIM_TypeDef *timer) * edge happened just after the overflow. */ - if (edge_count < 16) { + if (edge_count < 32) { /* Call the overflow callback first */ if (tim_dev->callbacks->overflow) { (*tim_dev->callbacks->overflow)((uint32_t)tim_dev,