/*#*
*#* $Log$
+ *#* Revision 1.29 2006/02/21 21:28:02 bernie
+ *#* New time handling based on TIMER_TICKS_PER_SEC to support slow timers with ticks longer than 1ms.
+ *#*
*#* Revision 1.28 2006/02/17 22:24:21 bernie
*#* Update POSIX timer emulator.
*#*
#include <cfg/compiler.h>
#include <appconfig.h>
-/*! Number of timer ticks per second. */
-#define TIMER_TICKS_PER_SEC (TIMER_TICKS_PER_MSEC * 1000)
-
-/*! Number of ticks per microsecond */
-#define TIMER_TICKS_PER_USEC ((TIMER_TICKS_PER_MSEC + 500) / 1000)
-
extern volatile ticks_t _clock;
//TODO: take care of slow timers so add convertions for seconds to ticks and viceversa.
-/*! Convert \a ms [ms] to ticks */
+/*! Convert \a ms [ms] to ticks. */
INLINE ticks_t ms_to_ticks(mtime_t ms)
{
- return ms * TIMER_TICKS_PER_MSEC;
+#if TIMER_TICKS_PER_SEC < 1000
+ /* Slow timer: avoid rounding down too much. */
+ return (ms * TIMER_TICKS_PER_SEC) / 1000;
+#else
+ /* Fast timer: don't overflow ticks_t. */
+ return ms * ((TIMER_TICKS_PER_SEC + 500) / 1000);
+#endif
}
-/*! Convert \a us [us] to ticks */
+/*! Convert \a us [us] to ticks. */
INLINE ticks_t us_to_ticks(utime_t us)
{
-#if TIMER_TICKS_PER_MSEC < 10000
- return (us * TIMER_TICKS_PER_MSEC + 500) / 1000;
+#if TIMER_TICKS_PER_SEC < 1000
+ /* Slow timer: avoid rounding down too much. */
+ return ((us / 1000) * TIMER_TICKS_PER_SEC) / 1000;
#else
- return (us * TIMER_TICKS_PER_USEC);
+ /* Fast timer: don't overflow ticks_t. */
+ return (us * ((TIMER_TICKS_PER_SEC + 500) / 1000)) / 1000;
#endif
}
-/*! Convert \a ticks [ticks] to ms */
+/*! Convert \a ticks [ticks] to ms. */
INLINE mtime_t ticks_to_ms(ticks_t ticks)
{
- return (ticks + TIMER_TICKS_PER_MSEC / 2) / TIMER_TICKS_PER_MSEC;
+#if TIMER_TICKS_PER_SEC < 1000
+ /* Slow timer: avoid rounding down too much. */
+ return (ticks * 1000) / TIMER_TICKS_PER_SEC;
+#else
+ /* Fast timer: avoid overflowing ticks_t. */
+ return ticks / (TIMER_TICKS_PER_SEC / 1000);
+#endif
}
-/*! Convert \a ticks [ticks] to us */
+/*! Convert \a ticks [ticks] to us. */
INLINE utime_t ticks_to_us(ticks_t ticks)
{
-#if TIMER_TICKS_PER_USEC > 10
- return (ticks / TIMER_TICKS_PER_USEC);
+#if TIMER_TICKS_PER_SEC < 1000
+ /* Slow timer: avoid rounding down too much. */
+ return ((ticks * 1000) / TIMER_TICKS_PER_SEC) * 1000;
#else
- return (ticks * 1000 + TIMER_TICKS_PER_MSEC / 2) / TIMER_TICKS_PER_MSEC;
+ /* Fast timer: avoid overflowing ticks_t. */
+ return (ticks / (TIMER_TICKS_PER_SEC / 1000)) * 1000;
#endif
}
/*! Convert \a us [us] to hpticks */
INLINE hptime_t us_to_hptime(utime_t us)
{
- #if TIMER_HW_HPTICKS_PER_SEC > 10000000UL
- return(us * ((TIMER_HW_HPTICKS_PER_SEC + 500000UL) / 1000000UL));
- #else
- return((us * TIMER_HW_HPTICKS_PER_SEC + 500000UL) / 1000000UL);
- #endif /* TIMER_HW_HPTICKS_PER_SEC > 10000000UL */
+#if TIMER_HW_HPTICKS_PER_SEC > 10000000UL
+ return(us * ((TIMER_HW_HPTICKS_PER_SEC + 500000UL) / 1000000UL));
+#else
+ return((us * TIMER_HW_HPTICKS_PER_SEC + 500000UL) / 1000000UL);
+#endif
}
/*! Convert \a hpticks [hptime] to usec */
INLINE utime_t hptime_to_us(hptime_t hpticks)
{
- #if TIMER_HW_HPTICKS_PER_SEC < 100000UL
- return(hpticks * (1000000UL / TIMER_HW_HPTICKS_PER_SEC));
- #else
- return((hpticks * 1000000UL) / TIMER_HW_HPTICKS_PER_SEC);
- #endif /* TIMER_HW_HPTICKS_PER_SEC < 100000UL */
+#if TIMER_HW_HPTICKS_PER_SEC < 100000UL
+ return(hpticks * (1000000UL / TIMER_HW_HPTICKS_PER_SEC));
+#else
+ return((hpticks * 1000000UL) / TIMER_HW_HPTICKS_PER_SEC);
+#endif /* TIMER_HW_HPTICKS_PER_SEC < 100000UL */
}
/*#*
*#* $Log$
+ *#* Revision 1.26 2006/02/21 21:28:02 bernie
+ *#* New time handling based on TIMER_TICKS_PER_SEC to support slow timers with ticks longer than 1ms.
+ *#*
*#* Revision 1.25 2005/07/19 07:26:37 bernie
*#* Refactor to decouple timer ticks from milliseconds.
*#*
#include <hw.h>
/*!
- * Values for CONFIG_TIMER.
+ * \name Values for CONFIG_TIMER.
*
* Select which hardware timer interrupt to use for system clock and softtimers.
* \note The timer 1 overflow mode set the timer as a 24 kHz PWM.
+ *
+ * \{
*/
#define TIMER_ON_OUTPUT_COMPARE0 1
#define TIMER_ON_OVERFLOW1 2
#define TIMER_ON_OUTPUT_COMPARE2 3
#define TIMER_ON_OVERFLOW3 4
+/* \} */
-/*! HW dependent timer initialization */
+/*
+ * Hardware dependent timer initialization.
+ */
#if (CONFIG_TIMER == TIMER_ON_OUTPUT_COMPARE0)
#define TIMER_PRESCALER 64
#define TIMER_HW_BITS 8
#define DEFINE_TIMER_ISR SIGNAL(SIG_OUTPUT_COMPARE0)
- #define TIMER_TICKS_PER_MSEC 1
+ #define TIMER_TICKS_PER_SEC 1000
#define TIMER_HW_CNT OCR_DIVISOR
//! Type of time expressed in ticks of the hardware high-precision timer
/*! This value is the maximum in overflow based timers. */
#define TIMER_HW_CNT (1 << TIMER_HW_BITS)
#define DEFINE_TIMER_ISR SIGNAL(SIG_OVERFLOW1)
- #define TIMER_TICKS_PER_MSEC (((TIMER_HW_HPTICKS_PER_SEC + TIMER_HW_CNT / 2) / TIMER_HW_CNT + 500) / 1000)
+ #define TIMER_TICKS_PER_SEC ((TIMER_HW_HPTICKS_PER_SEC + TIMER_HW_CNT / 2) / TIMER_HW_CNT)
//! Type of time expressed in ticks of the hardware high precision timer
typedef uint16_t hptime_t;
#define TIMER_PRESCALER 64
#define TIMER_HW_BITS 8
#define DEFINE_TIMER_ISR SIGNAL(SIG_OUTPUT_COMPARE2)
- #define TIMER_TICKS_PER_MSEC 1
+ #define TIMER_TICKS_PER_SEC 1000
/*! Value for OCR register in output-compare based timers. */
#define TIMER_HW_CNT OCR_DIVISOR
/*! This value is the maximum in overflow based timers. */
#define TIMER_HW_CNT (1 << TIMER_HW_BITS)
#define DEFINE_TIMER_ISR SIGNAL(SIG_OVERFLOW3)
- #define TIMER_TICKS_PER_MSEC (((TIMER_HW_HPTICKS_PER_SEC + TIMER_HW_CNT / 2) / TIMER_HW_CNT + 500) / 1000)
+ #define TIMER_TICKS_PER_SEC ((TIMER_HW_HPTICKS_PER_SEC + TIMER_HW_CNT / 2) / TIMER_HW_CNT)
//! Type of time expressed in ticks of the hardware high precision timer
typedef uint16_t hptime_t;
#endif /* CONFIG_TIMER */
-/*! Frequency of the hardware high precision timer */
+/*! Frequency of the hardware high precision timer. */
#define TIMER_HW_HPTICKS_PER_SEC ((CLOCK_FREQ + TIMER_PRESCALER / 2) / TIMER_PRESCALER)
/*!
* System timer: additional division after the prescaler
* 12288000 / 64 / 192 (0..191) = 1 ms
*/
-#define OCR_DIVISOR (((CLOCK_FREQ + TIMER_PRESCALER / 2) / TIMER_PRESCALER + TICKS_PER_SEC / 2) / TICKS_PER_SEC - 1) /* 191 */
+#define OCR_DIVISOR (((CLOCK_FREQ + TIMER_PRESCALER / 2) / TIMER_PRESCALER + TIMER_TICKS_PER_SEC / 2) / TIMER_TICKS_PER_SEC - 1)
/*! Not needed, IRQ timer flag cleared automatically */
#define timer_hw_irq() do {} while (0)
+#error This code must be revised for the new timer API
/*!
* \file
* <!--
- * Copyright 2004 Giovanni Bajo
* Copyright 2004 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2004 Giovanni Bajo
* This file is part of DevLib - See README.devlib for information.
* -->
*
/*#*
*#* $Log$
+ *#* Revision 1.9 2006/02/21 21:28:02 bernie
+ *#* New time handling based on TIMER_TICKS_PER_SEC to support slow timers with ticks longer than 1ms.
+ *#*
*#* Revision 1.8 2005/11/04 16:20:02 bernie
*#* Fix reference to README.devlib in header.
*#*
+#error This code must be revised for the new timer API
/*!
* \file
* <!--
- * Copyright 2000 Bernardo Innocenti
* Copyright 2003,2004 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2000 Bernardo Innocenti
* This file is part of DevLib - See README.devlib for information.
* -->
*
/*#*
*#* $Log$
+ *#* Revision 1.6 2006/02/21 21:28:02 bernie
+ *#* New time handling based on TIMER_TICKS_PER_SEC to support slow timers with ticks longer than 1ms.
+ *#*
*#* Revision 1.5 2005/11/04 16:20:02 bernie
*#* Fix reference to README.devlib in header.
*#*
#ifndef TIMER_I196_H
#define TIMER_I196_H
- /*!
- * Retrigger TIMER2, adjusting the time to account for
- * the interrupt prologue latency.
- */
-# define TIMER_RETRIGGER (TIMER2 -= TICKS_RATE)
+/*!
+ * Retrigger TIMER2, adjusting the time to account for
+ * the interrupt prologue latency.
+ */
+#define TIMER_RETRIGGER (TIMER2 -= TICKS_RATE)
-# define TIMER_INIT \
- TIMER2 = (65535 - TICKS_RATE); \
- INT_MASK1 |= INT1F_T2OVF; \
- ATOMIC( \
- WSR = 1; \
- IOC3 |= IOC3F_T2_ENA; \
- WSR = 0; \
- )
+#define TIMER_INIT \
+ TIMER2 = (65535 - TICKS_RATE); \
+ INT_MASK1 |= INT1F_T2OVF; \
+ ATOMIC( \
+ WSR = 1; \
+ IOC3 |= IOC3F_T2_ENA; \
+ WSR = 0; \
+ )
#define DEFINE_TIMER_ISR \
INTERRUPT(0x38) void TM2_OVFL_interrupt(void); \
/*#*
*#* $Log$
+ *#* Revision 1.5 2006/02/21 21:28:02 bernie
+ *#* New time handling based on TIMER_TICKS_PER_SEC to support slow timers with ticks longer than 1ms.
+ *#*
*#* Revision 1.4 2006/02/17 22:24:21 bernie
*#* Update POSIX timer emulator.
*#*
sa.sa_flags = SA_RESTART;
sigaction(SIGALRM, &sa, NULL);
- // Setup POSIX realtime timer to interrupt every 10ms.
+ // Setup POSIX realtime timer to interrupt every 1/TIMER_TICKS_PER_SEC.
static struct itimerval itv =
{
- { 0, 1000 / TIMER_TICKS_PER_MSEC }, /* it_interval */
- { 0, 1000 / TIMER_TICKS_PER_MSEC } /* it_value */
+ { 0, 1000000 / TIMER_TICKS_PER_SEC }, /* it_interval */
+ { 0, 1000000 / TIMER_TICKS_PER_SEC } /* it_value */
};
setitimer(ITIMER_REAL, &itv, NULL);
}
/*#*
*#* $Log$
+ *#* Revision 1.2 2006/02/21 21:28:02 bernie
+ *#* New time handling based on TIMER_TICKS_PER_SEC to support slow timers with ticks longer than 1ms.
+ *#*
*#* Revision 1.1 2005/11/27 03:58:18 bernie
*#* Add POSIX timer emulator.
*#*
// HW dependent timer initialization
-#define DEFINE_TIMER_ISR void timer_isr(int)
-#define TIMER_TICKS_PER_MSEC 1
+#define DEFINE_TIMER_ISR void timer_isr(UNUSED_ARG(int, arg))
+#define TIMER_TICKS_PER_SEC 250
#define TIMER_HW_CNT (1<<31) /* We assume 32bit integers here */
-/// Type of time expressed in ticks of the hardware high-precision timer.
-//typedef unsigned int hptime_t;
#include <os/hptime.h>
/// Frequency of the hardware high-precision timer.
/*#*
*#* $Log$
+ *#* Revision 1.3 2006/02/21 21:28:02 bernie
+ *#* New time handling based on TIMER_TICKS_PER_SEC to support slow timers with ticks longer than 1ms.
+ *#*
*#* Revision 1.2 2006/02/20 02:01:35 bernie
*#* Port to Qt 4.1.
*#*
// Record initial time
system_time.start();
- // Activate 1ms timer interrupt
+ // Activate timer interrupt
timer.connect(&timer, SIGNAL(timeout()), this, SLOT(timerInterrupt()));
- timer.start(1);
+ timer.start(1000 / TIMER_TICKS_PER_SEC);
initialized = true;
}
/*#*
*#* $Log$
+ *#* Revision 1.3 2006/02/21 21:28:02 bernie
+ *#* New time handling based on TIMER_TICKS_PER_SEC to support slow timers with ticks longer than 1ms.
+ *#*
*#* Revision 1.2 2005/11/27 03:57:00 bernie
*#* Documentation fixes.
*#*
// HW dependent timer initialization
#define DEFINE_TIMER_ISR void timer_isr(void)
-#define TIMER_TICKS_PER_MSEC 1
+#define TIMER_TICKS_PER_SEC 250
#define TIMER_HW_CNT (1<<31) /* We assume 32bit integers here */
/// Type of time expressed in ticks of the hardware high-precision timer.
/*#*
*#* $Log$
+ *#* Revision 1.3 2006/02/21 21:28:02 bernie
+ *#* New time handling based on TIMER_TICKS_PER_SEC to support slow timers with ticks longer than 1ms.
+ *#*
*#* Revision 1.2 2005/11/27 03:58:18 bernie
*#* Add POSIX timer emulator.
*#*
#ifdef TIMER1_OVF_COUNT
kprintf("TIMER1_OVF_COUNT=%d\n", (int)TIMER1_OVF_COUNT);
#endif
- kprintf("TIMER_TICKS_PER_MSEC=%d\n", (int)TIMER_TICKS_PER_MSEC);
+ kprintf("TIMER_TICKS_PER_SEC=%d\n", (int)TIMER_TICKS_PER_SEC);
kprintf("\n");
kprintf("ms_to_ticks(100)=%lu\n", ms_to_ticks(100));
kprintf("ms_to_ticks(10000)=%lu\n", ms_to_ticks(10000));
timer_test_delay();
timer_test_async();
timer_test_poll();
+ return 0;
}