diff options
author | Joel Sherrill <joel.sherrill@OARcorp.com> | 2009-03-02 18:57:20 +0000 |
---|---|---|
committer | Joel Sherrill <joel.sherrill@OARcorp.com> | 2009-03-02 18:57:20 +0000 |
commit | cb54e106866c4b9afb5a58ce6ee34486c46bb0db (patch) | |
tree | ed8dfe82d283cff5d67c95c254835d779ea250d9 /c | |
parent | 2009-03-02 Daniel Hellstrom <daniel@gaisler.com> (diff) | |
download | rtems-cb54e106866c4b9afb5a58ce6ee34486c46bb0db.tar.bz2 |
2009-03-02 Till Straumann <strauman@slac.stanford.edu>
PR 1375/bsps
* clock/clock.c: Correct implementation of nanoseconds since last tick
handler.
Diffstat (limited to 'c')
-rw-r--r-- | c/src/lib/libbsp/m68k/uC5282/ChangeLog | 6 | ||||
-rw-r--r-- | c/src/lib/libbsp/m68k/uC5282/clock/clock.c | 63 |
2 files changed, 64 insertions, 5 deletions
diff --git a/c/src/lib/libbsp/m68k/uC5282/ChangeLog b/c/src/lib/libbsp/m68k/uC5282/ChangeLog index dfac8da347..c6fd4f78af 100644 --- a/c/src/lib/libbsp/m68k/uC5282/ChangeLog +++ b/c/src/lib/libbsp/m68k/uC5282/ChangeLog @@ -1,3 +1,9 @@ +2009-03-02 Till Straumann <strauman@slac.stanford.edu> + + PR 1375/bsps + * clock/clock.c: Correct implementation of nanoseconds since last tick + handler. + 2009-01-21 Eric Norum <norume@aps.anl.gov> PR 1358/bsps diff --git a/c/src/lib/libbsp/m68k/uC5282/clock/clock.c b/c/src/lib/libbsp/m68k/uC5282/clock/clock.c index 90308d8299..793b45c2c8 100644 --- a/c/src/lib/libbsp/m68k/uC5282/clock/clock.c +++ b/c/src/lib/libbsp/m68k/uC5282/clock/clock.c @@ -35,13 +35,66 @@ extern int __SRAMBASE[]; uint32_t bsp_clock_nanoseconds_since_last_tick(void) { - int i = MCF5282_PIT3_PCNTR; - if (MCF5282_PIT3_PCSR & MCF5282_PIT_PCSR_PIF) - i = MCF5282_PIT3_PCNTR - USEC_PER_TICK; - return (USEC_PER_TICK - i) * 1000; + uint32_t tdiff; + + /* Details to consider here: + * + * - PIT is 16-bit. To properly handle differences of two + * 16-bit numbers (which requires 17-bits) we want to + * do the arithmetic in a wider data type. PIT reading + * is a unsigned 16-bit count. + * + * => must make sure PIT is a *unsigned* 16-bit type. Otherwise + * values get sign-extended when converted to wider type + * (regardless of the signedness of wider type): + * + * (unsigned)(signed short)0xffff -> 0xffffffff. + * + * and thus + * + * (uint32_t)(int16_t)65535 - (uin32_t)(int16_t)1 + * + * would yield 0xfffffffe, not 65534! + * + * + * - PIT counts backwards from PMR -> zero, hence + * + * now - tick_base = (PMR - now) - (PMR - tick_base) = tick_base - now; + * + * result may be negative (if rolled-over). + * + * - PIF flag, counter and PCNTR_AT_TICK must all + * be read atomically - otherwise an interrupt may + * have altered their values while we're looking. + * + * NOTE: score framework calling this routine disables + * interrupts during execution of this callout. + * + * - Last but not least, rollover might have happened + * just between reading counter and PIF flag; hence + * we have to re-read the counter if PIF is set. + * + */ + + /* obtain current value */ + tdiff = (uint16_t)MCF5282_PIT3_PCNTR; + + if (MCF5282_PIT3_PCSR & MCF5282_PIT_PCSR_PIF) { + /* rollover may just have happened; + * must reload PCNTR. + */ + tdiff = + (uint32_t)(uint16_t)MCF5282_PIT3_PMR + + (uint32_t)(uint16_t)PCNTR_AT_TICK + - (uint32_t)(uint16_t)MCF5282_PIT3_PCNTR; + } else { + tdiff = + (uint32_t)(uint16_t)PCNTR_AT_TICK - tdiff; + } + + return tdiff * 1000; } -#define Clock_driver_nanoseconds_since_last_tick bsp_clock_nanoseconds_since_last_tick +#define Clock_driver_nanoseconds_since_last_tick \ + bsp_clock_nanoseconds_since_last_tick /* * Periodic interval timer interrupt handler |