stm32h7: Fix a bunch of tickless issues.
This commit is contained in:
parent
2fad06008a
commit
e5c8bb9b34
@ -114,9 +114,8 @@ struct stm32_tickless_s
|
||||
uint32_t frequency;
|
||||
#ifdef CONFIG_CLOCK_TIMEKEEPING
|
||||
uint64_t counter_mask;
|
||||
#else
|
||||
uint32_t overflow; /* Timer counter overflow */
|
||||
#endif
|
||||
uint32_t overflow; /* Timer counter overflow */
|
||||
volatile bool pending; /* True: pending task */
|
||||
uint32_t period; /* Interval period */
|
||||
uint32_t base;
|
||||
@ -331,14 +330,12 @@ static void stm32_interval_handler(void)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_CLOCK_TIMEKEEPING
|
||||
static void stm32_timing_handler(void)
|
||||
{
|
||||
g_tickless.overflow++;
|
||||
|
||||
STM32_TIM_ACKINT(g_tickless.tch, 0);
|
||||
STM32_TIM_ACKINT(g_tickless.tch, ATIM_SR_UIF);
|
||||
}
|
||||
#endif /* CONFIG_CLOCK_TIMEKEEPING */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_tickless_handler
|
||||
@ -359,12 +356,10 @@ static int stm32_tickless_handler(int irq, void *context, void *arg)
|
||||
{
|
||||
int interrupt_flags = stm32_tickless_getint();
|
||||
|
||||
#ifndef CONFIG_CLOCK_TIMEKEEPING
|
||||
if (interrupt_flags & ATIM_SR_UIF)
|
||||
{
|
||||
stm32_timing_handler();
|
||||
}
|
||||
#endif /* CONFIG_CLOCK_TIMEKEEPING */
|
||||
|
||||
if (interrupt_flags & (1 << g_tickless.channel))
|
||||
{
|
||||
@ -381,8 +376,13 @@ static int stm32_tickless_handler(int irq, void *context, void *arg)
|
||||
|
||||
static uint64_t stm32_get_counter(void)
|
||||
{
|
||||
#ifdef HAVE_32BIT_TICKLESS
|
||||
return ((uint64_t)g_tickless.overflow << 32) |
|
||||
STM32_TIM_GETCOUNTER(g_tickless.tch);
|
||||
#else
|
||||
return ((uint64_t)g_tickless.overflow << 16) |
|
||||
STM32_TIM_GETCOUNTER(g_tickless.tch);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -553,8 +553,9 @@ void up_timer_initialize(void)
|
||||
g_tickless.channel = CONFIG_STM32H7_TICKLESS_CHANNEL;
|
||||
g_tickless.pending = false;
|
||||
g_tickless.period = 0;
|
||||
g_tickless.overflow = 0;
|
||||
|
||||
tmrinfo("timer=%d channel=%d frequency=%d Hz\n",
|
||||
tmrinfo("timer=%d channel=%d frequency=%lu Hz\n",
|
||||
g_tickless.timer, g_tickless.channel, g_tickless.frequency);
|
||||
|
||||
g_tickless.tch = stm32_tim_init(g_tickless.timer);
|
||||
@ -571,13 +572,11 @@ void up_timer_initialize(void)
|
||||
/* Should this be changed to 0xffff because we use 16 bit timers? */
|
||||
|
||||
g_tickless.counter_mask = 0xffffffffull;
|
||||
#else
|
||||
g_tickless.overflow = 0;
|
||||
#endif
|
||||
|
||||
/* Set up to receive the callback when the counter overflow occurs */
|
||||
|
||||
STM32_TIM_SETISR(g_tickless.tch, stm32_tickless_handler, NULL, 0);
|
||||
#endif
|
||||
|
||||
/* Initialize interval to zero */
|
||||
|
||||
@ -607,7 +606,7 @@ void up_timer_initialize(void)
|
||||
|
||||
/* Start the timer */
|
||||
|
||||
STM32_TIM_ACKINT(g_tickless.tch, 0);
|
||||
STM32_TIM_ACKINT(g_tickless.tch, ~0);
|
||||
STM32_TIM_ENABLEINT(g_tickless.tch, 0);
|
||||
|
||||
#if defined(CONFIG_ARMV7M_SYSTICK) && defined(CONFIG_CPULOAD_PERIOD)
|
||||
@ -648,7 +647,6 @@ void up_timer_initialize(void)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_CLOCK_TIMEKEEPING
|
||||
int up_timer_gettime(FAR struct timespec *ts)
|
||||
{
|
||||
uint64_t usec;
|
||||
@ -680,7 +678,7 @@ int up_timer_gettime(FAR struct timespec *ts)
|
||||
|
||||
overflow = g_tickless.overflow;
|
||||
counter = STM32_TIM_GETCOUNTER(g_tickless.tch);
|
||||
pending = STM32_TIM_CHECKINT(g_tickless.tch, 0);
|
||||
pending = STM32_TIM_CHECKINT(g_tickless.tch, ATIM_SR_UIF);
|
||||
verify = STM32_TIM_GETCOUNTER(g_tickless.tch);
|
||||
|
||||
/* If an interrupt was pending before we re-enabled interrupts,
|
||||
@ -689,7 +687,7 @@ int up_timer_gettime(FAR struct timespec *ts)
|
||||
|
||||
if (pending)
|
||||
{
|
||||
STM32_TIM_ACKINT(g_tickless.tch, 0);
|
||||
STM32_TIM_ACKINT(g_tickless.tch, ATIM_SR_UIF);
|
||||
|
||||
/* Increment the overflow count and use the value of the
|
||||
* guaranteed to be AFTER the overflow occurred.
|
||||
@ -708,7 +706,7 @@ int up_timer_gettime(FAR struct timespec *ts)
|
||||
tmrinfo("counter=%lu (%lu) overflow=%lu, pending=%i\n",
|
||||
(unsigned long)counter, (unsigned long)verify,
|
||||
(unsigned long)overflow, pending);
|
||||
tmrinfo("frequency=%u\n", g_tickless.frequency);
|
||||
tmrinfo("frequency=%lu\n", g_tickless.frequency);
|
||||
|
||||
/* Convert the whole thing to units of microseconds.
|
||||
*
|
||||
@ -730,13 +728,27 @@ int up_timer_gettime(FAR struct timespec *ts)
|
||||
ts->tv_sec = sec;
|
||||
ts->tv_nsec = (usec - (sec * USEC_PER_SEC)) * NSEC_PER_USEC;
|
||||
|
||||
tmrinfo("usec=%llu ts=(%u, %lu)\n",
|
||||
tmrinfo("usec=%llu ts=(%lu, %lu)\n",
|
||||
usec, (unsigned long)ts->tv_sec, (unsigned long)ts->tv_nsec);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
#else
|
||||
#ifdef CONFIG_CLOCK_TIMEKEEPING
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_timer_getcounter
|
||||
*
|
||||
* Description:
|
||||
* To be provided
|
||||
*
|
||||
* Input Parameters:
|
||||
* cycles - 64-bit return value
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int up_timer_getcounter(FAR uint64_t *cycles)
|
||||
{
|
||||
@ -744,8 +756,6 @@ int up_timer_getcounter(FAR uint64_t *cycles)
|
||||
return OK;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_CLOCK_TIMEKEEPING */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_timer_getmask
|
||||
*
|
||||
@ -760,12 +770,15 @@ int up_timer_getcounter(FAR uint64_t *cycles)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_CLOCK_TIMEKEEPING
|
||||
void up_timer_getmask(FAR uint64_t *mask)
|
||||
{
|
||||
DEBUGASSERT(mask != NULL);
|
||||
*mask = g_tickless.counter_mask;
|
||||
|
||||
/* Should this be changed to 0xffff because we use 16 bit timers? */
|
||||
|
||||
*mask = 0xffffffffull;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_CLOCK_TIMEKEEPING */
|
||||
|
||||
/****************************************************************************
|
||||
@ -1044,8 +1057,13 @@ int up_alarm_start(FAR const struct timespec *ts)
|
||||
|
||||
int up_alarm_cancel(FAR struct timespec *ts)
|
||||
{
|
||||
#ifdef HAVE_32BIT_TICKLESS
|
||||
uint64_t nsecs = (((uint64_t)g_tickless.overflow << 32) |
|
||||
STM32_TIM_GETCOUNTER(g_tickless.tch)) * NSEC_PER_TICK;
|
||||
#else
|
||||
uint64_t nsecs = (((uint64_t)g_tickless.overflow << 16) |
|
||||
STM32_TIM_GETCOUNTER(g_tickless.tch)) * NSEC_PER_TICK;
|
||||
#endif
|
||||
|
||||
ts->tv_sec = nsecs / NSEC_PER_SEC;
|
||||
ts->tv_nsec = nsecs - ts->tv_sec * NSEC_PER_SEC;
|
||||
|
Loading…
Reference in New Issue
Block a user