stm32h7: Fix a bunch of tickless issues.

This commit is contained in:
Anthony Merlino 2021-04-10 20:10:47 -04:00 committed by Xiang Xiao
parent 2fad06008a
commit e5c8bb9b34

View File

@ -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;