mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2025-01-30 15:52:12 +01:00
OP-1682 - Workaround overflow issue with pwm receiver inputs on shared timers.
This commit is contained in:
parent
a35fc57b29
commit
caa51253db
@ -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 */
|
||||
|
@ -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]++;
|
||||
|
||||
|
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user