mirror of
https://github.com/PX4/PX4-Autopilot.git
synced 2026-05-31 10:26:52 +08:00
Fixe the STM32 repetition counter. Setting of the repitition count was out of phase by 1
git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@4304 7fd9a85b-ad96-42d3-883c-3090e2eb8679
This commit is contained in:
@@ -141,7 +141,8 @@ struct stm32_pwmtimer_s
|
|||||||
uint8_t timtype; /* See the TIMTYPE_* definitions */
|
uint8_t timtype; /* See the TIMTYPE_* definitions */
|
||||||
#ifdef CONFIG_PWM_PULSECOUNT
|
#ifdef CONFIG_PWM_PULSECOUNT
|
||||||
uint8_t irq; /* Timer update IRQ */
|
uint8_t irq; /* Timer update IRQ */
|
||||||
uint8_t rcr; /* Previous pulse count */
|
uint8_t prev; /* The previous value of the RCR (pre-loaded) */
|
||||||
|
uint8_t curr; /* The current value of the RCR (pre-loaded) */
|
||||||
uint32_t count; /* Remaining pluse count */
|
uint32_t count; /* Remaining pluse count */
|
||||||
#endif
|
#endif
|
||||||
uint32_t base; /* The base address of the timer */
|
uint32_t base; /* The base address of the timer */
|
||||||
@@ -694,8 +695,31 @@ static int pwm_timer(FAR struct stm32_pwmtimer_s *priv,
|
|||||||
#ifdef CONFIG_PWM_PULSECOUNT
|
#ifdef CONFIG_PWM_PULSECOUNT
|
||||||
if (info->count > 0)
|
if (info->count > 0)
|
||||||
{
|
{
|
||||||
uint16_t count = (uint16_t)pwm_pulsecount(info->count) - 1;
|
/* Save the remining count and the number of counts that will have
|
||||||
pwm_putreg(priv, STM32_ATIM_RCR_OFFSET, count);
|
* elapsed on the first interrupt.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* If the first interrupt occurs at the end end of the first
|
||||||
|
* repition count, then the count will be the same as the RCR
|
||||||
|
* value.
|
||||||
|
*/
|
||||||
|
|
||||||
|
priv->prev = pwm_pulsecount(info->count);
|
||||||
|
pwm_putreg(priv, STM32_ATIM_RCR_OFFSET, (uint16_t)priv->prev - 1);
|
||||||
|
|
||||||
|
/* Generate an update event to reload the prescaler. This should
|
||||||
|
* preload the RCR into active repetition counter.
|
||||||
|
*/
|
||||||
|
|
||||||
|
pwm_putreg(priv, STM32_GTIM_EGR_OFFSET, ATIM_EGR_UG);
|
||||||
|
|
||||||
|
/* Now set the value of the RCR that will be loaded on the next
|
||||||
|
* update event.
|
||||||
|
*/
|
||||||
|
|
||||||
|
priv->count = info->count;
|
||||||
|
priv->curr = pwm_pulsecount(info->count - priv->prev);
|
||||||
|
pwm_putreg(priv, STM32_ATIM_RCR_OFFSET, (uint16_t)priv->curr - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Otherwise, just clear the repitition counter */
|
/* Otherwise, just clear the repitition counter */
|
||||||
@@ -703,14 +727,22 @@ static int pwm_timer(FAR struct stm32_pwmtimer_s *priv,
|
|||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
/* Set the repeition counter to zero */
|
||||||
|
|
||||||
pwm_putreg(priv, STM32_ATIM_RCR_OFFSET, 0);
|
pwm_putreg(priv, STM32_ATIM_RCR_OFFSET, 0);
|
||||||
|
|
||||||
|
/* Generate an update event to reload the prescaler */
|
||||||
|
|
||||||
|
pwm_putreg(priv, STM32_GTIM_EGR_OFFSET, ATIM_EGR_UG);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
#endif
|
#endif
|
||||||
|
{
|
||||||
|
/* Generate an update event to reload the prescaler (all timers) */
|
||||||
|
|
||||||
/* Generate an update event to reload the prescaler (all timers) */
|
pwm_putreg(priv, STM32_GTIM_EGR_OFFSET, ATIM_EGR_UG);
|
||||||
|
}
|
||||||
pwm_putreg(priv, STM32_GTIM_EGR_OFFSET, ATIM_EGR_UG);
|
|
||||||
|
|
||||||
/* Handle channel specific setup */
|
/* Handle channel specific setup */
|
||||||
|
|
||||||
@@ -894,14 +926,6 @@ static int pwm_timer(FAR struct stm32_pwmtimer_s *priv,
|
|||||||
pwm_putreg(priv, STM32_GTIM_SR_OFFSET, 0);
|
pwm_putreg(priv, STM32_GTIM_SR_OFFSET, 0);
|
||||||
pwm_putreg(priv, STM32_GTIM_DIER_OFFSET, ATIM_DIER_UIE);
|
pwm_putreg(priv, STM32_GTIM_DIER_OFFSET, ATIM_DIER_UIE);
|
||||||
|
|
||||||
/* Save the remining count and the number of counts that will have
|
|
||||||
* elapsed on the first interrupt. Since the first interrupt will
|
|
||||||
* occur immediately, that count will be zero.
|
|
||||||
*/
|
|
||||||
|
|
||||||
priv->rcr = 0;
|
|
||||||
priv->count =info->count;
|
|
||||||
|
|
||||||
/* Enable the timer */
|
/* Enable the timer */
|
||||||
|
|
||||||
cr1 |= GTIM_CR1_CEN;
|
cr1 |= GTIM_CR1_CEN;
|
||||||
@@ -956,7 +980,7 @@ static int pwm_interrupt(struct stm32_pwmtimer_s *priv)
|
|||||||
* since the last interrupt.
|
* since the last interrupt.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (priv->count <= priv->rcr)
|
if (priv->count <= priv->prev)
|
||||||
{
|
{
|
||||||
/* We are finished. Turn off the mast output to stop the output as
|
/* We are finished. Turn off the mast output to stop the output as
|
||||||
* quickly as possible.
|
* quickly as possible.
|
||||||
@@ -976,27 +1000,32 @@ static int pwm_interrupt(struct stm32_pwmtimer_s *priv)
|
|||||||
|
|
||||||
priv->handle = NULL;
|
priv->handle = NULL;
|
||||||
priv->count = 0;
|
priv->count = 0;
|
||||||
priv->rcr = 0;
|
priv->prev = 0;
|
||||||
|
priv->curr = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Decrement the count of pulses remaining using the number of
|
/* Decrement the count of pulses remaining using the number of
|
||||||
* pulses generated since the last interrupt. This will be the
|
* pulses generated since the last interrupt.
|
||||||
* same as the current RCR value *except* on the first interrupt.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
priv->count -= priv->rcr;
|
priv->count -= priv->prev;
|
||||||
|
|
||||||
/* Calculate and set the next RCR value */
|
/* Set up the next RCR. Set 'prev' to the value of the RCR that
|
||||||
|
* was loaded when the update occurred (just before this interrupt)
|
||||||
|
* and set 'curr' to the current value of the RCR register (which
|
||||||
|
* will bet loaded on the next update event).
|
||||||
|
*/
|
||||||
|
|
||||||
priv->rcr = pwm_pulsecount(priv->count);
|
priv->prev = priv->curr;
|
||||||
pwm_putreg(priv, STM32_ATIM_RCR_OFFSET, (uint16_t)priv->rcr - 1);
|
priv->curr = pwm_pulsecount(priv->count - priv->prev);
|
||||||
|
pwm_putreg(priv, STM32_ATIM_RCR_OFFSET, (uint16_t)priv->curr - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now all of the time critical stuff is done so we can do some debug output */
|
/* Now all of the time critical stuff is done so we can do some debug output */
|
||||||
|
|
||||||
pwmllvdbg("Update interrupt SR: %04x RCR: %d count: %d\n",
|
pwmllvdbg("Update interrupt SR: %04x prev: %d curr: %d count: %d\n",
|
||||||
regval, priv->rcr, priv->count);
|
regval, priv->prev, priv->curr, priv->count);
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user