From 766a22ae58928039e82f428d17a8a944ab2fb553 Mon Sep 17 00:00:00 2001 From: bernie Date: Tue, 21 Feb 2006 21:28:02 +0000 Subject: [PATCH] New time handling based on TIMER_TICKS_PER_SEC to support slow timers with ticks longer than 1ms. git-svn-id: https://src.develer.com/svnoss/bertos/trunk@537 38d2e660-2303-0410-9eaa-f027e97ec537 --- drv/timer.h | 69 +++++++++++++++++++++++++++------------------- drv/timer_avr.h | 24 ++++++++++------ drv/timer_dsp56k.h | 6 +++- drv/timer_i196.h | 32 +++++++++++---------- drv/timer_posix.c | 9 ++++-- drv/timer_posix.h | 9 +++--- drv/timer_qt.c | 7 +++-- drv/timer_qt.h | 5 +++- drv/timer_test.c | 6 +++- 9 files changed, 105 insertions(+), 62 deletions(-) diff --git a/drv/timer.h b/drv/timer.h index c78bee39..c77936ad 100755 --- a/drv/timer.h +++ b/drv/timer.h @@ -15,6 +15,9 @@ /*#* *#* $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. *#* @@ -116,12 +119,6 @@ #include #include -/*! 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; @@ -171,56 +168,72 @@ INLINE ticks_t timer_clock_unlocked(void) //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 */ } diff --git a/drv/timer_avr.h b/drv/timer_avr.h index 0ba8d52b..12203954 100755 --- a/drv/timer_avr.h +++ b/drv/timer_avr.h @@ -16,6 +16,9 @@ /*#* *#* $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. *#* @@ -44,23 +47,28 @@ #include /*! - * 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 @@ -73,7 +81,7 @@ /*! 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; @@ -83,7 +91,7 @@ #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 @@ -98,7 +106,7 @@ /*! 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; @@ -108,14 +116,14 @@ #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) diff --git a/drv/timer_dsp56k.h b/drv/timer_dsp56k.h index 11fbc675..e343af4a 100755 --- a/drv/timer_dsp56k.h +++ b/drv/timer_dsp56k.h @@ -1,8 +1,9 @@ +#error This code must be revised for the new timer API /*! * \file * * @@ -15,6 +16,9 @@ /*#* *#* $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. *#* diff --git a/drv/timer_i196.h b/drv/timer_i196.h index c478a897..339cd6de 100755 --- a/drv/timer_i196.h +++ b/drv/timer_i196.h @@ -1,8 +1,9 @@ +#error This code must be revised for the new timer API /*! * \file * * @@ -15,6 +16,9 @@ /*#* *#* $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. *#* @@ -35,20 +39,20 @@ #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); \ diff --git a/drv/timer_posix.c b/drv/timer_posix.c index 6d6e3673..6204885e 100755 --- a/drv/timer_posix.c +++ b/drv/timer_posix.c @@ -14,6 +14,9 @@ /*#* *#* $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. *#* @@ -55,11 +58,11 @@ static void timer_hw_init(void) 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); } diff --git a/drv/timer_posix.h b/drv/timer_posix.h index cd9ec84d..fbaf9e4f 100755 --- a/drv/timer_posix.h +++ b/drv/timer_posix.h @@ -14,6 +14,9 @@ /*#* *#* $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. *#* @@ -26,12 +29,10 @@ // 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 /// Frequency of the hardware high-precision timer. diff --git a/drv/timer_qt.c b/drv/timer_qt.c index a11e9ca6..c6ff698f 100755 --- a/drv/timer_qt.c +++ b/drv/timer_qt.c @@ -14,6 +14,9 @@ /*#* *#* $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. *#* @@ -78,9 +81,9 @@ public: // 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; } diff --git a/drv/timer_qt.h b/drv/timer_qt.h index b0fe0a86..a4772de4 100755 --- a/drv/timer_qt.h +++ b/drv/timer_qt.h @@ -14,6 +14,9 @@ /*#* *#* $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. *#* @@ -27,7 +30,7 @@ // 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. diff --git a/drv/timer_test.c b/drv/timer_test.c index bfc712ad..0d01307f 100755 --- a/drv/timer_test.c +++ b/drv/timer_test.c @@ -13,6 +13,9 @@ /*#* *#* $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. *#* @@ -34,7 +37,7 @@ static void timer_test_constants(void) #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)); @@ -115,4 +118,5 @@ int main(void) timer_test_delay(); timer_test_async(); timer_test_poll(); + return 0; } -- 2.25.1