summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1999-12-13 22:12:03 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1999-12-13 22:12:03 +0000
commite8918ec37136449816065811e81a9cd63b5e422f (patch)
treef0cdb83835d32bb1f8a5f5c7e16dc5d14eb9feba /c/src/lib/libbsp
parentRemoved warnings. (diff)
downloadrtems-e8918ec37136449816065811e81a9cd63b5e422f.tar.bz2
Patch from Eric Norum <eric@cls.usask.ca> to change to gen68360 clock handling.
I got tired of having strange clock rates (e.g. #define CONFIGURE_MICROSECONDS_PER_TICK 52489) and drifting times-of-day with the gen68360 BSP so I changed the way the programmable-interval clock interrupt works. The new version will have some jitter in the intervals between individual calls to the rtems_clock_tick routine, but the long-term average will match the CONFIGURE_MICROSECONDS_PER_TICK
Diffstat (limited to 'c/src/lib/libbsp')
-rw-r--r--c/src/lib/libbsp/m68k/gen68360/clock/ckinit.c86
1 files changed, 56 insertions, 30 deletions
diff --git a/c/src/lib/libbsp/m68k/gen68360/clock/ckinit.c b/c/src/lib/libbsp/m68k/gen68360/clock/ckinit.c
index e0d5c344c5..a2a50d5715 100644
--- a/c/src/lib/libbsp/m68k/gen68360/clock/ckinit.c
+++ b/c/src/lib/libbsp/m68k/gen68360/clock/ckinit.c
@@ -53,33 +53,49 @@ rtems_device_minor_number rtems_clock_minor;
char M360DefaultWatchdogFeeder = 1;
/*
+ * RTEMS and hardware have different notions of clock rate.
+ */
+static unsigned long rtems_nsec_per_tick;
+static unsigned long pit_nsec_per_tick;
+
+/*
* Periodic interval timer interrupt handler
*/
rtems_isr
Clock_isr (rtems_vector_number vector)
{
- /*
- * Perform a dummy read of DPRAM.
- * This works around a bug in Rev. B of the 68360
- */
- m360.dpram0[0];
+ static unsigned long nsec;
/*
- * Feed the watchdog
- * Application code can override this by
- * setting M360DefaultWatchdogFeeder to zero.
+ * See if it's really time for a `tick'
*/
- if (M360DefaultWatchdogFeeder) {
- m360.swsr = 0x55;
- m360.swsr = 0xAA;
- }
+ nsec += pit_nsec_per_tick;
+ if (nsec >= rtems_nsec_per_tick) {
+ nsec -= rtems_nsec_per_tick;
+
+ /*
+ * Perform a dummy read of DPRAM.
+ * This works around a bug in Rev. B of the 68360
+ */
+ m360.dpram0[0];
- /*
- * Announce the clock tick
- */
- Clock_driver_ticks++;
- rtems_clock_tick();
+ /*
+ * Feed the watchdog
+ * Application code can override this by
+ * setting M360DefaultWatchdogFeeder to zero.
+ */
+ if (M360DefaultWatchdogFeeder) {
+ m360.swsr = 0x55;
+ m360.swsr = 0xAA;
+ }
+
+ /*
+ * Announce the clock tick
+ */
+ Clock_driver_ticks++;
+ rtems_clock_tick();
+ }
}
void
@@ -98,29 +114,39 @@ Install_clock (rtems_isr_entry clock_isr)
{
Clock_driver_ticks = 0;
if ( BSP_Configuration.ticks_per_timeslice ) {
- int pitr;
-
/*
* Choose periodic interval timer register value
+ * The rate at which the periodic interval timer
+ * can generate interrupts is almost certainly not
+ * the same as desired by the BSP configuration.
+ * Handle the difference by choosing the largest PIT
+ * interval which is less than or equal to the RTEMS
+ * interval and skipping some hardware interrupts.
+ * To reduce the jitter in the calls to RTEMS the
+ * hardware interrupt interval is never less than
+ * the maximum non-prescaled value from the PIT.
+ *
* For a 25 MHz external clock the basic clock rate is
* 40 nsec * 128 * 4 = 20.48 usec/tick
*/
- pitr = ((BSP_Configuration.microseconds_per_tick * 100) + 1023) / 2048;
- if (pitr >= 256) {
- pitr = (pitr + 255) / 512;
- if (pitr >= 256)
- pitr = 255;
- else if (pitr == 0)
- pitr = 1;
- pitr |= 0x100;
+ int divisor;
+ extern int m360_clock_rate; /* This should be somewhere in a config file */
+ unsigned long nsec_per_chip_tick = 1000000000 / m360_clock_rate;
+ unsigned long nsec_per_pit_tick = 512 * nsec_per_chip_tick;
+
+ rtems_nsec_per_tick = BSP_Configuration.microseconds_per_tick * 1000;
+ divisor = rtems_nsec_per_tick / nsec_per_pit_tick;
+ if (divisor >= 256) {
+ divisor = 255;
}
- else if (pitr == 0) {
- pitr = 1;
+ else if (divisor == 0) {
+ divisor = 1;
}
+ pit_nsec_per_tick = nsec_per_pit_tick * divisor;
m360.pitr &= ~0x1FF;
m360.picr = (CLOCK_IRQ_LEVEL << 8) | CLOCK_VECTOR;
set_vector (clock_isr, CLOCK_VECTOR, 1);
- m360.pitr |= pitr;
+ m360.pitr |= divisor;
atexit (Clock_exit);
}
}