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
This commit is contained in:
Joel Sherrill
1999-12-13 22:12:03 +00:00
parent c629812c01
commit e8918ec371

View File

@@ -52,6 +52,12 @@ rtems_device_minor_number rtems_clock_minor;
char M360DefaultWatchdogFeeder = 1; 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 * Periodic interval timer interrupt handler
*/ */
@@ -59,6 +65,15 @@ char M360DefaultWatchdogFeeder = 1;
rtems_isr rtems_isr
Clock_isr (rtems_vector_number vector) Clock_isr (rtems_vector_number vector)
{ {
static unsigned long nsec;
/*
* See if it's really time for a `tick'
*/
nsec += pit_nsec_per_tick;
if (nsec >= rtems_nsec_per_tick) {
nsec -= rtems_nsec_per_tick;
/* /*
* Perform a dummy read of DPRAM. * Perform a dummy read of DPRAM.
* This works around a bug in Rev. B of the 68360 * This works around a bug in Rev. B of the 68360
@@ -81,6 +96,7 @@ Clock_isr (rtems_vector_number vector)
Clock_driver_ticks++; Clock_driver_ticks++;
rtems_clock_tick(); rtems_clock_tick();
} }
}
void void
Clock_exit (void) Clock_exit (void)
@@ -98,29 +114,39 @@ Install_clock (rtems_isr_entry clock_isr)
{ {
Clock_driver_ticks = 0; Clock_driver_ticks = 0;
if ( BSP_Configuration.ticks_per_timeslice ) { if ( BSP_Configuration.ticks_per_timeslice ) {
int pitr;
/* /*
* Choose periodic interval timer register value * 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 * For a 25 MHz external clock the basic clock rate is
* 40 nsec * 128 * 4 = 20.48 usec/tick * 40 nsec * 128 * 4 = 20.48 usec/tick
*/ */
pitr = ((BSP_Configuration.microseconds_per_tick * 100) + 1023) / 2048; int divisor;
if (pitr >= 256) { extern int m360_clock_rate; /* This should be somewhere in a config file */
pitr = (pitr + 255) / 512; unsigned long nsec_per_chip_tick = 1000000000 / m360_clock_rate;
if (pitr >= 256) unsigned long nsec_per_pit_tick = 512 * nsec_per_chip_tick;
pitr = 255;
else if (pitr == 0) rtems_nsec_per_tick = BSP_Configuration.microseconds_per_tick * 1000;
pitr = 1; divisor = rtems_nsec_per_tick / nsec_per_pit_tick;
pitr |= 0x100; if (divisor >= 256) {
divisor = 255;
} }
else if (pitr == 0) { else if (divisor == 0) {
pitr = 1; divisor = 1;
} }
pit_nsec_per_tick = nsec_per_pit_tick * divisor;
m360.pitr &= ~0x1FF; m360.pitr &= ~0x1FF;
m360.picr = (CLOCK_IRQ_LEVEL << 8) | CLOCK_VECTOR; m360.picr = (CLOCK_IRQ_LEVEL << 8) | CLOCK_VECTOR;
set_vector (clock_isr, CLOCK_VECTOR, 1); set_vector (clock_isr, CLOCK_VECTOR, 1);
m360.pitr |= pitr; m360.pitr |= divisor;
atexit (Clock_exit); atexit (Clock_exit);
} }
} }