Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.arch.embedded > #26445

A timer driver for Cortex-M0+... it rarely doesn't work

From pozz <pozzugno@gmail.com>
Newsgroups comp.arch.embedded
Subject A timer driver for Cortex-M0+... it rarely doesn't work
Date 2017-04-27 00:55 +0200
Organization A noiseless patient Spider
Message-ID <odr8bp$op3$1@dont-email.me> (permalink)

Show all headers | View raw


I don't know if it is an issue specific to Atmel SAMC21 Cortex-M0+ 
devices or not.

I wrote a simple timer driver: a 32-bits hw counter clocked at 875kHz 
(14MHz/16) that triggers an interrupt on overflow (every 1h 21').  In 
the interrupt I increment the 32-bits global variable _ticks_high.
The 64-bits number composed by _ticks_high (upper 32-bits) and the hw 
counter (lower 32-bits) is my system tick.  This 64-bits software 
counter, incremented at 875kHz, will never overflow during my life, so 
it's good :-)

In timer.h I have:
--- Start of timer.h ---
#include <stdint.h>
#include <io.h>  // Atmel specific

#define TIMER_FREQ    875000

typedef uint64_t Timer;
extern uint32_t _ticks_high;

#define volatileAccess(v) *((volatile typeof((v)) *) &(v))

static inline uint64_t ticks(void) {
   uint32_t h1 = volatileAccess(_ticks_high);
   TC0->COUNT32.CTRLBSET.reg =
        TC_CTRLBSET_CMD(TC_CTRLBSET_CMD_READSYNC_Val);
   uint32_t l1 = TC0->COUNT32.COUNT.reg;
   uint32_t h2 = volatileAccess(_ticks_high);
   if (h2 != h1) return ((uint64_t)h2 << 32) + 0;
   else          return ((uint64_t)h1 << 32) + l1;
}

static inline void TimerSet(Timer *tmr, uint64_t delay) {
   /* delay is in ms */
   *tmr = ticks() + delay * TIMER_FREQ / 1000;
}

static inline int TimerExpired(Timer *tmr) {
	return ticks() >= *tmr;
}
--- End of timer.h ---

In timer.c I have the ISR:
--- Start of timer.c ---
...
void TC0_Handler(void) {
   if (TC0->COUNT32.INTFLAG.reg & TC_INTFLAG_OVF) {
     ++_ticks_high;
     TC0->COUNT32.INTFLAG.reg = TC_INTFLAG_OVF;
   }
}
...
--- End of timer.c ---

The idea is simple (and stolen from a post appeared on this newsgroup). 
At first, the 64-bits software counter must be calculated disabling 
interrupts, because if a timer interrupt triggers during calculation, 
the overall software counter could be wrong.
By reading _ticks_high before and after reading hw counter, we can avoid 
to disable the interrupts.


Now I have a code that uses timers. It's a simple state-machine that 
manages communication over a bus.
--- Start of bus.c ---
...
int bus_task(void) {
   switch(bus.state) {
     case BUS_IDLE:
       if (TimerExpired(&bus.tmr_answer)) {
         /* Send new request on the bus */
         ...
         TimerSet(&bus.tmr_answer, timeout_answer);
         bus.state = BUS_WAITING_ANSWER;
       }
       break;

     case BUS_WAITING_ANSWER:
       if (TimerExpired(&bus.tmr_answer)) {
         /* No reply */
         bus.state = BUS_IDLE;
         TimerSet(&bus.tmr_answer, 0);
       } else {
         if (reply_received() == true)	{
           /* Analyze the reply */
           bus.state = BUS_IDLE;
           TimerSet(&bus.tmr_answer, 0);
         }
       }
       break;
   }
   return 0;
}
...
--- End of bus.c ---

I don't think I need to explain the code in bus.c. The only thing to 
specify is that bus_task() is called continuously in the main loop.

99% of the time this code works well. Unfortunately I have seen some 
strange events. Rarely (very rarely, one time in a week) the bus seems 
frozen for a time. After that it restarts the normal activity magically.
There's a thing that relates those strange events to driver of timers: 
the bus stall time lasts exactly 1h 21', the overflow period of hw counter.

I suspect there's a problem in my low-level driver and sometimes, maybe 
near the overflow, the code doesn't work as I expect.
Maybe the TimerSet() function sometimes sets a wrong value to the 
uint64_t timer, maybe a tick value that will happen only at the next 
overflow of the hw counter.

Do you see where is the problem?

Back to comp.arch.embedded | Previous | Next — Next in thread | Find similar | Unroll thread


Thread

A timer driver for Cortex-M0+... it rarely doesn't work pozz <pozzugno@gmail.com> - 2017-04-27 00:55 +0200
  Re: A timer driver for Cortex-M0+... it rarely doesn't work Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> - 2017-04-26 23:24 +0000
    Re: A timer driver for Cortex-M0+... it rarely doesn't work pozz <pozzugno@gmail.com> - 2017-04-27 09:32 +0200
      Re: A timer driver for Cortex-M0+... it rarely doesn't work Jack <jack4747@gmail.com> - 2017-04-27 01:15 -0700
  Re: A timer driver for Cortex-M0+... it rarely doesn't work John Speth <johnspeth@yahoo.com> - 2017-04-26 17:17 -0700
    Re: A timer driver for Cortex-M0+... it rarely doesn't work pozz <pozzugno@gmail.com> - 2017-04-27 09:37 +0200
      Re: A timer driver for Cortex-M0+... it rarely doesn't work David Brown <david.brown@hesbynett.no> - 2017-04-27 10:13 +0200
        Re: A timer driver for Cortex-M0+... it rarely doesn't work John Speth <johnspeth@yahoo.com> - 2017-04-27 10:24 -0700
          Re: A timer driver for Cortex-M0+... it rarely doesn't work David Brown <david.brown@hesbynett.no> - 2017-04-27 22:04 +0200
  Re: A timer driver for Cortex-M0+... it rarely doesn't work David Brown <david.brown@hesbynett.no> - 2017-04-27 10:01 +0200
    Re: A timer driver for Cortex-M0+... it rarely doesn't work David Brown <david.brown@hesbynett.no> - 2017-04-27 10:27 +0200
      Re: A timer driver for Cortex-M0+... it rarely doesn't work pozz <pozzugno@gmail.com> - 2017-04-27 11:53 +0200
        Re: A timer driver for Cortex-M0+... it rarely doesn't work Stef <stef33d@yahooI-N-V-A-L-I-D.com.invalid> - 2017-05-01 10:09 +0200
          Re: A timer driver for Cortex-M0+... it rarely doesn't work pozz <pozzugno@gmail.com> - 2017-05-02 09:03 +0200
            Re: A timer driver for Cortex-M0+... it rarely doesn't work Stef <stef33d@yahooI-N-V-A-L-I-D.com.invalid> - 2017-05-04 10:06 +0200
    Re: A timer driver for Cortex-M0+... it rarely doesn't work pozz <pozzugno@gmail.com> - 2017-04-27 11:38 +0200
      Re: A timer driver for Cortex-M0+... it rarely doesn't work David Brown <david.brown@hesbynett.no> - 2017-04-27 12:54 +0200
        Re: A timer driver for Cortex-M0+... it rarely doesn't work pozz <pozzugno@gmail.com> - 2017-04-27 13:51 +0200
          Re: A timer driver for Cortex-M0+... it rarely doesn't work David Brown <david.brown@hesbynett.no> - 2017-04-27 15:39 +0200
            Re: A timer driver for Cortex-M0+... it rarely doesn't work pozz <pozzugno@gmail.com> - 2017-04-28 09:24 +0200
              Re: A timer driver for Cortex-M0+... it rarely doesn't work David Brown <david.brown@hesbynett.no> - 2017-04-28 11:05 +0200
                Re: A timer driver for Cortex-M0+... it rarely doesn't work pozz <pozzugno@gmail.com> - 2017-04-28 12:18 +0200
                Re: A timer driver for Cortex-M0+... it rarely doesn't work David Brown <david.brown@hesbynett.no> - 2017-04-28 13:10 +0200
                ARM developing under Linux [was Re: A timer driver for Cortex-M0+... it rarely doesn't work] pozz <pozzugno@gmail.com> - 2017-05-02 09:14 +0200
                Re: ARM developing under Linux [was Re: A timer driver for Cortex-M0+... it rarely doesn't work] David Brown <david.brown@hesbynett.no> - 2017-05-02 11:34 +0200
                Re: ARM developing under Linux [was Re: A timer driver for Cortex-M0+... it rarely doesn't work] pozz <pozzugno@gmail.com> - 2017-05-03 09:04 +0200
                Re: ARM developing under Linux [was Re: A timer driver for Cortex-M0+... it rarely doesn't work] David Brown <david.brown@hesbynett.no> - 2017-05-03 10:59 +0200
  Re: A timer driver for Cortex-M0+... it rarely doesn't work Dimiter_Popoff <dp@tgi-sci.com> - 2017-04-27 11:02 +0300
    Re: A timer driver for Cortex-M0+... it rarely doesn't work David Brown <david.brown@hesbynett.no> - 2017-04-27 11:06 +0200
      Re: A timer driver for Cortex-M0+... it rarely doesn't work Dimiter_Popoff <dp@tgi-sci.com> - 2017-04-27 14:20 +0300
        Re: A timer driver for Cortex-M0+... it rarely doesn't work David Brown <david.brown@hesbynett.no> - 2017-04-27 16:16 +0200
      Re: A timer driver for Cortex-M0+... it rarely doesn't work Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> - 2017-04-27 12:03 +0000
        Re: A timer driver for Cortex-M0+... it rarely doesn't work David Brown <david.brown@hesbynett.no> - 2017-04-27 16:18 +0200

csiph-web