All timer lower half drivers. Port Sebastien's changes to all all other implementations of the timer lower half. Very many just and untested. Expect some problems.

This commit is contained in:
Gregory Nutt 2016-11-17 15:03:31 -06:00
parent 197cec58d2
commit 19c1c9d78b
5 changed files with 133 additions and 140 deletions

View File

@ -92,12 +92,13 @@ struct sam34_lowerhalf_s
/* Private data */
tccb_t handler; /* Current user interrupt handler */
uint32_t timeout; /* The current timeout value (us) */
uint32_t clkticks; /* actual clock ticks for current interval */
uint32_t val; /* rtt value of current timeout */
uint32_t adjustment; /* time lost due to clock resolution truncation (us) */
bool started; /* The timer has been started */
tccb_t callback; /* Current user interrupt callback */
FAR void *arg; /* Argument that accompanies the callback */
uint32_t timeout; /* The current timeout value (us) */
uint32_t clkticks; /* Actual clock ticks for current interval */
uint32_t val; /* rtt value of current timeout */
uint32_t adjustment; /* Time lost due to clock resolution truncation (us) */
bool started; /* The timer has been started */
};
/****************************************************************************
@ -125,8 +126,8 @@ static int sam34_getstatus(FAR struct timer_lowerhalf_s *lower,
FAR struct timer_status_s *status);
static int sam34_settimeout(FAR struct timer_lowerhalf_s *lower,
uint32_t timeout);
static tccb_t sam34_sethandler(FAR struct timer_lowerhalf_s *lower,
tccb_t handler);
static void sam34_setcallback(FAR struct timer_lowerhalf_s *lower,
tccb_t callback, FAR void *arg);
static int sam34_ioctl(FAR struct timer_lowerhalf_s *lower, int cmd,
unsigned long arg);
@ -137,12 +138,12 @@ static int sam34_ioctl(FAR struct timer_lowerhalf_s *lower, int cmd,
static const struct timer_ops_s g_tcops =
{
.start = sam34_start,
.stop = sam34_stop,
.getstatus = sam34_getstatus,
.settimeout = sam34_settimeout,
.sethandler = sam34_sethandler,
.ioctl = sam34_ioctl,
.start = sam34_start,
.stop = sam34_stop,
.getstatus = sam34_getstatus,
.settimeout = sam34_settimeout,
.setcallback = sam34_setcallback,
.ioctl = sam34_ioctl,
};
/* "Lower half" driver state */
@ -160,6 +161,7 @@ static struct sam34_lowerhalf_s g_tcdev;
* Get the contents of the value register.
*
****************************************************************************/
static inline uint32_t sam34_readvr(void)
{
register uint32_t v;
@ -289,9 +291,9 @@ static int sam34_interrupt(int irq, FAR void *context)
uint32_t vr;
uint32_t lateticks;
/* Is there a registered handler? */
/* Is there a registered callback? */
if (priv->handler && priv->handler(&priv->timeout))
if (priv->callback && priv->callback(&priv->timeout, priv->arg))
{
/* Disable int before writing new alarm */
@ -388,7 +390,7 @@ static int sam34_start(FAR struct timer_lowerhalf_s *lower)
priv->val = vr + priv->clkticks; /* value at end of interval */
sam34_putreg(priv->val-1, SAM_RTT_AR); /* Set interval */
if (priv->handler)
if (priv->callback)
{
/* Clear status and enable interrupt */
@ -475,7 +477,7 @@ static int sam34_getstatus(FAR struct timer_lowerhalf_s *lower,
status->flags |= TCFLAGS_ACTIVE;
}
if (priv->handler)
if (priv->callback)
{
status->flags |= TCFLAGS_HANDLER;
}
@ -544,17 +546,18 @@ static int sam34_settimeout(FAR struct timer_lowerhalf_s *lower,
}
/****************************************************************************
* Name: sam34_sethandler
* Name: sam34_setcallback
*
* Description:
* Call this user provided timeout handler.
* Call this user provided timeout callback.
*
* Input Parameters:
* lower - A pointer the publicly visible representation of the "lower-half"
* driver state structure.
* newhandler - The new timer expiration function pointer. If this
* function pointer is NULL, then the reset-on-expiration
* behavior is restored,
* lower - A pointer the publicly visible representation of the "lower-half"
* driver state structure.
* callback - The new timer expiration function pointer. If this
* function pointer is NULL, then the reset-on-expiration
* behavior is restored,
* arg - Argument that will be provided in the callback
*
* Returned Values:
* The previous timer expiration function pointer or NULL is there was
@ -562,28 +565,23 @@ static int sam34_settimeout(FAR struct timer_lowerhalf_s *lower,
*
****************************************************************************/
static tccb_t sam34_sethandler(FAR struct timer_lowerhalf_s *lower,
tccb_t handler)
static void sam34_setcallback(FAR struct timer_lowerhalf_s *lower,
tccb_t callback, FAR void *arg)
{
FAR struct sam34_lowerhalf_s *priv = (FAR struct sam34_lowerhalf_s *)lower;
irqstate_t flags;
tccb_t oldhandler;
flags = enter_critical_section();
DEBUGASSERT(priv);
tmrinfo("Entry: handler=%p\n", handler);
tmrinfo("Entry: callback=%p\n", callback);
/* Get the old handler return value */
/* Save the new callback and argument */
oldhandler = priv->handler;
/* Save the new handler */
priv->handler = handler;
priv->callback = callback;
priv->arg = arg;
leave_critical_section(flags);
return oldhandler;
}
/****************************************************************************

View File

@ -90,13 +90,14 @@ struct sam34_lowerhalf_s
/* Private data */
uint32_t base; /* Base address of the timer */
tccb_t handler; /* Current user interrupt handler */
uint32_t timeout; /* The current timeout value (us) */
uint32_t adjustment; /* time lost due to clock resolution truncation (us) */
uint32_t clkticks; /* actual clock ticks for current interval */
bool started; /* The timer has been started */
uint16_t periphid; /* peripheral id */
uint32_t base; /* Base address of the timer */
tccb_t callback; /* Current user interrupt callback */
FAR void *arg; /* Argument passed to the callback function */
uint32_t timeout; /* The current timeout value (us) */
uint32_t adjustment; /* time lost due to clock resolution truncation (us) */
uint32_t clkticks; /* actual clock ticks for current interval */
bool started; /* The timer has been started */
uint16_t periphid; /* peripheral id */
};
/****************************************************************************
@ -124,8 +125,8 @@ static int sam34_getstatus(FAR struct timer_lowerhalf_s *lower,
FAR struct timer_status_s *status);
static int sam34_settimeout(FAR struct timer_lowerhalf_s *lower,
uint32_t timeout);
static tccb_t sam34_sethandler(FAR struct timer_lowerhalf_s *lower,
tccb_t handler);
static void sam34_sethandler(FAR struct timer_lowerhalf_s *lower,
tccb_t callback, FAR void *arg);
static int sam34_ioctl(FAR struct timer_lowerhalf_s *lower, int cmd,
unsigned long arg);
@ -267,11 +268,11 @@ static int sam34_interrupt(int irq, FAR void *context)
{
uint32_t timeout;
/* Is there a registered handler? If the handler has been nullified,
/* Is there a registered callback? If the callback has been nullified,
* the timer will be stopped.
*/
if (priv->handler && priv->handler(&priv->timeout))
if (priv->callback && priv->callback(&priv->timeout, priv->arg))
{
/* Calculate new ticks / dither adjustment */
@ -286,7 +287,7 @@ static int sam34_interrupt(int irq, FAR void *context)
}
else
{
/* No handler or the handler returned false.. stop the timer */
/* No callback or the callback returned false.. stop the timer */
sam34_stop((FAR struct timer_lowerhalf_s *)priv);
tmrinfo("Stopped\n");
@ -340,7 +341,7 @@ static int sam34_start(FAR struct timer_lowerhalf_s *lower)
sam34_putreg(priv->clkticks, priv->base + SAM_TC_RC_OFFSET); /* Set interval */
if (priv->handler)
if (priv->callback)
{
/* Clear status and enable interrupt */
@ -422,7 +423,7 @@ static int sam34_getstatus(FAR struct timer_lowerhalf_s *lower,
status->flags |= TCFLAGS_ACTIVE;
}
if (priv->handler)
if (priv->callback)
{
status->flags |= TCFLAGS_HANDLER;
}
@ -493,17 +494,18 @@ static int sam34_settimeout(FAR struct timer_lowerhalf_s *lower,
}
/****************************************************************************
* Name: sam34_sethandler
* Name: sam34_setcallback
*
* Description:
* Call this user provided timeout handler.
* Call this user provided timeout callback.
*
* Input Parameters:
* lower - A pointer the publicly visible representation of the "lower-half"
* driver state structure.
* newhandler - The new timer expiration function pointer. If this
* function pointer is NULL, then the reset-on-expiration
* behavior is restored,
* lower - A pointer the publicly visible representation of the "lower-half"
* driver state structure.
* callback - The new timer expiration function pointer. If this
* function pointer is NULL, then the reset-on-expiration
* behavior is restored,
* arg - Argument to be provided with the callback.
*
* Returned Values:
* The previous timer expiration function pointer or NULL is there was
@ -511,28 +513,23 @@ static int sam34_settimeout(FAR struct timer_lowerhalf_s *lower,
*
****************************************************************************/
static tccb_t sam34_sethandler(FAR struct timer_lowerhalf_s *lower,
tccb_t handler)
static void sam34_sethandler(FAR struct timer_lowerhalf_s *lower,
tccb_t callback, FAR void *arg)
{
FAR struct sam34_lowerhalf_s *priv = (FAR struct sam34_lowerhalf_s *)lower;
irqstate_t flags;
tccb_t oldhandler;
flags = enter_critical_section();
DEBUGASSERT(priv);
tmrinfo("Entry: handler=%p\n", handler);
tmrinfo("Entry: callback=%p\n", callback);
/* Get the old handler return value */
/* Save the new callback and its argument */
oldhandler = priv->handler;
/* Save the new handler */
priv->handler = handler;
priv->callback = callback;
priv->arg = arg;
leave_critical_section(flags);
return oldhandler;
}
/****************************************************************************

View File

@ -107,7 +107,8 @@ struct stm32_lowerhalf_s
{
FAR const struct timer_ops_s *ops; /* Lower half operations */
FAR struct stm32_tim_dev_s *tim; /* stm32 timer driver */
tccb_t usrhandler; /* Current user interrupt handler */
tccb_t callback; /* Current user interrupt callback */
FAR void *arg; /* Argument passed to upper half callback */
const xcpt_t timhandler; /* Current timer interrupt handler */
bool started; /* True: Timer has been started */
const uint8_t resolution; /* Number of bits in the timer (16 or 32 bits) */
@ -170,8 +171,8 @@ static int stm32_start(FAR struct timer_lowerhalf_s *lower);
static int stm32_stop(FAR struct timer_lowerhalf_s *lower);
static int stm32_settimeout(FAR struct timer_lowerhalf_s *lower,
uint32_t timeout);
static tccb_t stm32_sethandler(FAR struct timer_lowerhalf_s *lower,
tccb_t handler);
static void stm32_setcallback(FAR struct timer_lowerhalf_s *lower,
tccb_t callback, FAR void *arg);
/****************************************************************************
* Private Data
@ -180,137 +181,137 @@ static tccb_t stm32_sethandler(FAR struct timer_lowerhalf_s *lower,
static const struct timer_ops_s g_timer_ops =
{
.start = stm32_start,
.stop = stm32_stop,
.getstatus = NULL,
.settimeout = stm32_settimeout,
.sethandler = stm32_sethandler,
.ioctl = NULL,
.start = stm32_start,
.stop = stm32_stop,
.getstatus = NULL,
.settimeout = stm32_settimeout,
.setcallback = stm32_setcallback,
.ioctl = NULL,
};
#ifdef CONFIG_STM32_TIM1
static struct stm32_lowerhalf_s g_tim1_lowerhalf =
{
.ops = &g_timer_ops,
.timhandler = stm32_tim1_interrupt,
.resolution = STM32_TIM1_RES,
.ops = &g_timer_ops,
.timhandler = stm32_tim1_interrupt,
.resolution = STM32_TIM1_RES,
};
#endif
#ifdef CONFIG_STM32_TIM2
static struct stm32_lowerhalf_s g_tim2_lowerhalf =
{
.ops = &g_timer_ops,
.timhandler = stm32_tim2_interrupt,
.resolution = STM32_TIM2_RES,
.ops = &g_timer_ops,
.timhandler = stm32_tim2_interrupt,
.resolution = STM32_TIM2_RES,
};
#endif
#ifdef CONFIG_STM32_TIM3
static struct stm32_lowerhalf_s g_tim3_lowerhalf =
{
.ops = &g_timer_ops,
.timhandler = stm32_tim3_interrupt,
.resolution = STM32_TIM3_RES,
.ops = &g_timer_ops,
.timhandler = stm32_tim3_interrupt,
.resolution = STM32_TIM3_RES,
};
#endif
#ifdef CONFIG_STM32_TIM4
static struct stm32_lowerhalf_s g_tim4_lowerhalf =
{
.ops = &g_timer_ops,
.timhandler = stm32_tim4_interrupt,
.resolution = STM32_TIM4_RES,
.ops = &g_timer_ops,
.timhandler = stm32_tim4_interrupt,
.resolution = STM32_TIM4_RES,
};
#endif
#ifdef CONFIG_STM32_TIM5
static struct stm32_lowerhalf_s g_tim5_lowerhalf =
{
.ops = &g_timer_ops,
.timhandler = stm32_tim5_interrupt,
.resolution = STM32_TIM5_RES,
.ops = &g_timer_ops,
.timhandler = stm32_tim5_interrupt,
.resolution = STM32_TIM5_RES,
};
#endif
#ifdef CONFIG_STM32_TIM6
static struct stm32_lowerhalf_s g_tim6_lowerhalf =
{
.ops = &g_timer_ops,
.timhandler = stm32_tim6_interrupt,
.resolution = STM32_TIM6_RES,
.ops = &g_timer_ops,
.timhandler = stm32_tim6_interrupt,
.resolution = STM32_TIM6_RES,
};
#endif
#ifdef CONFIG_STM32_TIM7
static struct stm32_lowerhalf_s g_tim7_lowerhalf =
{
.ops = &g_timer_ops,
.timhandler = stm32_tim7_interrupt,
.resolution = STM32_TIM7_RES,
.ops = &g_timer_ops,
.timhandler = stm32_tim7_interrupt,
.resolution = STM32_TIM7_RES,
};
#endif
#ifdef CONFIG_STM32_TIM8
static struct stm32_lowerhalf_s g_tim8_lowerhalf =
{
.ops = &g_timer_ops,
.timhandler = stm32_tim8_interrupt,
.resolution = STM32_TIM8_RES,
.ops = &g_timer_ops,
.timhandler = stm32_tim8_interrupt,
.resolution = STM32_TIM8_RES,
};
#endif
#ifdef CONFIG_STM32_TIM9
static struct stm32_lowerhalf_s g_tim9_lowerhalf =
{
.ops = &g_timer_ops,
.timhandler = stm32_tim9_interrupt,
.resolution = STM32_TIM9_RES,
.ops = &g_timer_ops,
.timhandler = stm32_tim9_interrupt,
.resolution = STM32_TIM9_RES,
};
#endif
#ifdef CONFIG_STM32_TIM10
static struct stm32_lowerhalf_s g_tim10_lowerhalf =
{
.ops = &g_timer_ops,
.timhandler = stm32_tim10_interrupt,
.resolution = STM32_TIM10_RES,
.ops = &g_timer_ops,
.timhandler = stm32_tim10_interrupt,
.resolution = STM32_TIM10_RES,
};
#endif
#ifdef CONFIG_STM32_TIM11
static struct stm32_lowerhalf_s g_tim11_lowerhalf =
{
.ops = &g_timer_ops,
.timhandler = stm32_tim11_interrupt,
.resolution = STM32_TIM11_RES,
.ops = &g_timer_ops,
.timhandler = stm32_tim11_interrupt,
.resolution = STM32_TIM11_RES,
};
#endif
#ifdef CONFIG_STM32_TIM12
static struct stm32_lowerhalf_s g_tim12_lowerhalf =
{
.ops = &g_timer_ops,
.timhandler = stm32_tim12_interrupt,
.resolution = STM32_TIM12_RES,
.ops = &g_timer_ops,
.timhandler = stm32_tim12_interrupt,
.resolution = STM32_TIM12_RES,
};
#endif
#ifdef CONFIG_STM32_TIM13
static struct stm32_lowerhalf_s g_tim13_lowerhalf =
{
.ops = &g_timer_ops,
.timhandler = stm32_tim13_interrupt,
.resolution = STM32_TIM13_RES,
.ops = &g_timer_ops,
.timhandler = stm32_tim13_interrupt,
.resolution = STM32_TIM13_RES,
};
#endif
#ifdef CONFIG_STM32_TIM14
static struct stm32_lowerhalf_s g_tim14_lowerhalf =
{
.ops = &g_timer_ops,
.timhandler = stm32_tim14_interrupt,
.resolution = STM32_TIM14_RES,
.ops = &g_timer_ops,
.timhandler = stm32_tim14_interrupt,
.resolution = STM32_TIM14_RES,
};
#endif
@ -442,7 +443,7 @@ static int stm32_timer_handler(FAR struct stm32_lowerhalf_s *lower)
STM32_TIM_ACKINT(lower->tim, 0);
if (lower->usrhandler(&next_interval_us))
if (lower->callback(&next_interval_us, lower->arg))
{
if (next_interval_us > 0)
{
@ -480,7 +481,7 @@ static int stm32_start(FAR struct timer_lowerhalf_s *lower)
{
STM32_TIM_SETMODE(priv->tim, STM32_TIM_MODE_UP);
if (priv->usrhandler != NULL)
if (priv->callback != NULL)
{
STM32_TIM_SETISR(priv->tim, priv->timhandler, 0);
STM32_TIM_ENABLEINT(priv->tim, 0);
@ -571,17 +572,18 @@ static int stm32_settimeout(FAR struct timer_lowerhalf_s *lower, uint32_t timeou
}
/****************************************************************************
* Name: stm32_sethandler
* Name: stm32_setcallback
*
* Description:
* Call this user provided timeout handler.
* Call this user provided timeout callback.
*
* Input Parameters:
* lower - A pointer the publicly visible representation of the "lower-half"
* driver state structure.
* newhandler - The new timer expiration function pointer. If this
* callback - The new timer expiration function pointer. If this
* function pointer is NULL, then the reset-on-expiration
* behavior is restored,
* arg - Argument that will be provided in the callback
*
* Returned Values:
* The previous timer expiration function pointer or NULL is there was
@ -589,22 +591,19 @@ static int stm32_settimeout(FAR struct timer_lowerhalf_s *lower, uint32_t timeou
*
****************************************************************************/
static tccb_t stm32_sethandler(FAR struct timer_lowerhalf_s *lower,
tccb_t newhandler)
static void stm32_setcallback(FAR struct timer_lowerhalf_s *lower,
tccb_t callback, FAR void *arg)
{
FAR struct stm32_lowerhalf_s *priv = (FAR struct stm32_lowerhalf_s *)lower;
irqstate_t flags = enter_critical_section();
/* Get the old handler return value */
/* Save the new callback */
tccb_t oldhandler = priv->usrhandler;
priv->callback = callback;
priv->arg = arg;
/* Save the new handler */
priv->usrhandler = newhandler;
if (newhandler != NULL && priv->started)
if (callback != NULL && priv->started)
{
STM32_TIM_SETISR(priv->tim, priv->timhandler, 0);
STM32_TIM_ENABLEINT(priv->tim, 0);
@ -616,7 +615,6 @@ static tccb_t stm32_sethandler(FAR struct timer_lowerhalf_s *lower,
}
leave_critical_section(flags);
return oldhandler;
}
/****************************************************************************
@ -723,9 +721,9 @@ int stm32_timer_initialize(FAR const char *devpath, int timer)
/* Initialize the elements of lower half state structure */
lower->started = false;
lower->usrhandler = NULL;
lower->tim = stm32_tim_init(timer);
lower->started = false;
lower->callback = NULL;
lower->tim = stm32_tim_init(timer);
if (lower->tim == NULL)
{

View File

@ -148,8 +148,8 @@ static int stm32l4_start(FAR struct timer_lowerhalf_s *lower);
static int stm32l4_stop(FAR struct timer_lowerhalf_s *lower);
static int stm32l4_settimeout(FAR struct timer_lowerhalf_s *lower,
uint32_t timeout);
static tccb_t stm32l4_setcallback(FAR struct timer_lowerhalf_s *lower,
tccb_t callback, FAR void *arg);
static void stm32l4_setcallback(FAR struct timer_lowerhalf_s *lower,
tccb_t callback, FAR void *arg);
/****************************************************************************
* Private Data

View File

@ -1,7 +1,7 @@
/****************************************************************************
* drivers/timers/timer.c
*
* Copyright (C) 2014 Gregory Nutt. All rights reserved.
* Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved.
* Authors: Gregory Nutt <gnutt@nuttx.org>
* Bob Doiron
*