mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2025-12-05 15:15:44 +00:00
2010-05-09 Joel Sherrill <joel.sherrill@oarcorp.com>
* timer/timer.c: Now runs on 486 and below again. Reformatted.
This commit is contained in:
@@ -1,3 +1,7 @@
|
||||
2010-05-09 Joel Sherrill <joel.sherrill@oarcorp.com>
|
||||
|
||||
* timer/timer.c: Now runs on 486 and below again. Reformatted.
|
||||
|
||||
2010-04-30 Sebastian Huber <sebastian.huber@embedded-brains.de>
|
||||
|
||||
* Makefile.am, preinstall.am: Update for generic interrupt support
|
||||
|
||||
@@ -1,42 +1,31 @@
|
||||
/*-------------------------------------------------------------------------+
|
||||
| timer.c v1.1 - PC386 BSP - 1997/08/07
|
||||
+--------------------------------------------------------------------------+
|
||||
| This file contains the PC386 timer package.
|
||||
+--------------------------------------------------------------------------+
|
||||
| NOTE: It is important that the timer start/stop overhead be determined
|
||||
| when porting or modifying this code.
|
||||
+--------------------------------------------------------------------------+
|
||||
| (C) Copyright 1997 -
|
||||
| - NavIST Group - Real-Time Distributed Systems and Industrial Automation
|
||||
|
|
||||
| http://pandora.ist.utl.pt
|
||||
|
|
||||
| Instituto Superior Tecnico * Lisboa * PORTUGAL
|
||||
+--------------------------------------------------------------------------+
|
||||
| Disclaimer:
|
||||
|
|
||||
| This file is provided "AS IS" without warranty of any kind, either
|
||||
| expressed or implied.
|
||||
+--------------------------------------------------------------------------+
|
||||
| This code is base on:
|
||||
| timer.c,v 1.7 1995/12/19 20:07:43 joel Exp - go32 BSP
|
||||
|
|
||||
| Rosimildo daSilva -ConnectTel, Inc - Fixed infinite loop in the Calibration
|
||||
| routine. I've seen this problems with faster machines ( pentiums ). Sometimes
|
||||
| RTEMS just hangs at startup.
|
||||
|
|
||||
| With the following copyright notice:
|
||||
| **************************************************************************
|
||||
| * COPYRIGHT (c) 1989-1999.
|
||||
| * On-Line Applications Research Corporation (OAR).
|
||||
| *
|
||||
| * The license and distribution terms for this file may be
|
||||
| * found in found in the file LICENSE in this distribution or at
|
||||
| * http://www.rtems.com/license/LICENSE.
|
||||
| **************************************************************************
|
||||
|
|
||||
| $Id$
|
||||
+--------------------------------------------------------------------------*/
|
||||
/*
|
||||
* This file contains the PC386 timer package.
|
||||
*
|
||||
* Rosimildo daSilva -ConnectTel, Inc - Fixed infinite loop in the Calibration
|
||||
* routine. I've seen this problems with faster machines ( pentiums ). Sometimes
|
||||
* RTEMS just hangs at startup.
|
||||
*
|
||||
* Joel 9 May 2010: This is now seen sometimes on qemu.
|
||||
*
|
||||
* Modifications by:
|
||||
* (C) Copyright 1997 -
|
||||
* NavIST Group - Real-Time Distributed Systems and Industrial Automation
|
||||
* http://pandora.ist.utl.pt
|
||||
* Instituto Superior Tecnico * Lisboa * PORTUGAL
|
||||
*
|
||||
* This file is provided "AS IS" without warranty of any kind, either
|
||||
* expressed or implied.
|
||||
*
|
||||
* Based upon code by
|
||||
* COPYRIGHT (c) 1989-1999.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.com/license/LICENSE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
@@ -44,144 +33,115 @@
|
||||
#include <bsp/irq.h>
|
||||
#include <libcpu/cpuModel.h>
|
||||
|
||||
/*-------------------------------------------------------------------------+
|
||||
| Constants
|
||||
+--------------------------------------------------------------------------*/
|
||||
#define AVG_OVERHEAD 0 /* 0.1 microseconds to start/stop timer. */
|
||||
#define LEAST_VALID 1 /* Don't trust a value lower than this. */
|
||||
#define SLOW_DOWN_IO 0x80 /* io which does nothing */
|
||||
/*
|
||||
* Constants
|
||||
*/
|
||||
#define AVG_OVERHEAD 0 /* 0.1 microseconds to start/stop timer. */
|
||||
#define LEAST_VALID 1 /* Don't trust a value lower than this. */
|
||||
#define SLOW_DOWN_IO 0x80 /* io which does nothing */
|
||||
|
||||
#define TWO_MS (uint32_t)(2000) /* TWO_MS = 2000us (sic!) */
|
||||
#define TWO_MS (uint32_t)(2000) /* TWO_MS = 2000us (sic!) */
|
||||
|
||||
#define MSK_NULL_COUNT 0x40 /* bit counter available for reading */
|
||||
#define MSK_NULL_COUNT 0x40 /* bit counter available for reading */
|
||||
|
||||
#define CMD_READ_BACK_STATUS 0xE2 /* command read back status */
|
||||
/*-------------------------------------------------------------------------+
|
||||
| Global Variables
|
||||
+--------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Global Variables
|
||||
*/
|
||||
volatile uint32_t Ttimer_val;
|
||||
bool benchmark_timer_find_average_overhead = true;
|
||||
bool benchmark_timer_find_average_overhead = true;
|
||||
volatile unsigned int fastLoop1ms, slowLoop1ms;
|
||||
|
||||
void (*benchmark_timer_initialize_function)(void) = 0;
|
||||
uint32_t (*benchmark_timer_read_function)(void) = 0;
|
||||
void (*Timer_exit_function)(void) = 0;
|
||||
|
||||
/*-------------------------------------------------------------------------+
|
||||
| External Prototypes
|
||||
+--------------------------------------------------------------------------*/
|
||||
/* timer (int 08h) Interrupt Service Routine (defined in 'timerisr.s') */
|
||||
extern void timerisr(void);
|
||||
/* timer (int 08h) Interrupt Service Routine (defined in 'timerisr.s') */
|
||||
|
||||
/*
|
||||
* forward declarations
|
||||
*/
|
||||
|
||||
void Timer_exit(void);
|
||||
|
||||
/*-------------------------------------------------------------------------+
|
||||
| Pentium optimized timer handling.
|
||||
+--------------------------------------------------------------------------*/
|
||||
/*
|
||||
* Pentium optimized timer handling.
|
||||
*/
|
||||
|
||||
/*-------------------------------------------------------------------------+
|
||||
| Function: Timer_exit
|
||||
| Description: Timer cleanup routine at RTEMS exit. NOTE: This routine is
|
||||
| not really necessary, since there will be a reset at exit.
|
||||
| Global Variables: None.
|
||||
| Arguments: None.
|
||||
| Returns: Nothing.
|
||||
+--------------------------------------------------------------------------*/
|
||||
void
|
||||
tsc_timer_exit(void)
|
||||
/*
|
||||
* Timer cleanup routine at RTEMS exit. NOTE: This routine is
|
||||
* not really necessary, since there will be a reset at exit.
|
||||
*/
|
||||
|
||||
void tsc_timer_exit(void)
|
||||
{
|
||||
} /* tsc_timer_exit */
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------+
|
||||
| Function: benchmark_timer_initialize
|
||||
| Description: Timer initialization routine.
|
||||
| Global Variables: Ttimer_val.
|
||||
| Arguments: None.
|
||||
| Returns: Nothing.
|
||||
+--------------------------------------------------------------------------*/
|
||||
void
|
||||
tsc_timer_initialize(void)
|
||||
void tsc_timer_initialize(void)
|
||||
{
|
||||
static bool First = true;
|
||||
|
||||
if (First)
|
||||
{
|
||||
if (First) {
|
||||
First = false;
|
||||
|
||||
atexit(Timer_exit); /* Try not to hose the system at exit. */
|
||||
}
|
||||
Ttimer_val = rdtsc(); /* read starting time */
|
||||
} /* tsc_timer_initialize */
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------+
|
||||
| Function: benchmark_timer_read
|
||||
| Description: Read hardware timer value.
|
||||
| Global Variables: Ttimer_val, benchmark_timer_find_average_overhead.
|
||||
| Arguments: None.
|
||||
| Returns: Nothing.
|
||||
+--------------------------------------------------------------------------*/
|
||||
uint32_t
|
||||
tsc_read_timer(void)
|
||||
/*
|
||||
*
|
||||
*/
|
||||
uint32_t tsc_read_timer(void)
|
||||
{
|
||||
register uint32_t total;
|
||||
register uint32_t total;
|
||||
|
||||
total = (uint32_t)(rdtsc() - Ttimer_val);
|
||||
|
||||
if (benchmark_timer_find_average_overhead)
|
||||
return total;
|
||||
else if (total < LEAST_VALID)
|
||||
return 0; /* below timer resolution */
|
||||
else
|
||||
return (total - AVG_OVERHEAD);
|
||||
} /* tsc_read_timer */
|
||||
|
||||
/*-------------------------------------------------------------------------+
|
||||
| Non-Pentium timer handling.
|
||||
+--------------------------------------------------------------------------*/
|
||||
#define US_PER_ISR 250 /* Number of micro-seconds per timer interruption */
|
||||
if (total < LEAST_VALID)
|
||||
return 0; /* below timer resolution */
|
||||
|
||||
/*-------------------------------------------------------------------------+
|
||||
| Function: Timer_exit
|
||||
| Description: Timer cleanup routine at RTEMS exit. NOTE: This routine is
|
||||
| not really necessary, since there will be a reset at exit.
|
||||
| Global Variables: None.
|
||||
| Arguments: None.
|
||||
| Returns: Nothing.
|
||||
+--------------------------------------------------------------------------*/
|
||||
static void
|
||||
timerOff(const rtems_raw_irq_connect_data* used)
|
||||
{
|
||||
/*
|
||||
* disable interrrupt at i8259 level
|
||||
*/
|
||||
BSP_irq_disable_at_i8259s(used->idtIndex - BSP_IRQ_VECTOR_BASE);
|
||||
/* reset timer mode to standard (DOS) value */
|
||||
outport_byte(TIMER_MODE, TIMER_SEL0|TIMER_16BIT|TIMER_RATEGEN);
|
||||
outport_byte(TIMER_CNTR0, 0);
|
||||
outport_byte(TIMER_CNTR0, 0);
|
||||
} /* Timer_exit */
|
||||
|
||||
static void
|
||||
timerOn(const rtems_raw_irq_connect_data* used)
|
||||
{
|
||||
/* load timer for US_PER_ISR microsecond period */
|
||||
outport_byte(TIMER_MODE, TIMER_SEL0|TIMER_16BIT|TIMER_RATEGEN);
|
||||
outport_byte(TIMER_CNTR0, US_TO_TICK(US_PER_ISR) >> 0 & 0xff);
|
||||
outport_byte(TIMER_CNTR0, US_TO_TICK(US_PER_ISR) >> 8 & 0xff);
|
||||
/*
|
||||
* enable interrrupt at i8259 level
|
||||
*/
|
||||
BSP_irq_enable_at_i8259s(used->idtIndex - BSP_IRQ_VECTOR_BASE);
|
||||
return (total - AVG_OVERHEAD);
|
||||
}
|
||||
|
||||
static int
|
||||
timerIsOn(const rtems_raw_irq_connect_data *used)
|
||||
/*
|
||||
* Non-Pentium timer handling.
|
||||
*/
|
||||
#define US_PER_ISR 250 /* Number of micro-seconds per timer interruption */
|
||||
|
||||
/*
|
||||
* Timer cleanup routine at RTEMS exit. NOTE: This routine is
|
||||
* not really necessary, since there will be a reset at exit.
|
||||
*/
|
||||
static void timerOff(const rtems_raw_irq_connect_data* used)
|
||||
{
|
||||
return BSP_irq_enabled_at_i8259s(used->idtIndex - BSP_IRQ_VECTOR_BASE);
|
||||
/*
|
||||
* disable interrrupt at i8259 level
|
||||
*/
|
||||
BSP_irq_disable_at_i8259s(used->idtIndex - BSP_IRQ_VECTOR_BASE);
|
||||
/* reset timer mode to standard (DOS) value */
|
||||
outport_byte(TIMER_MODE, TIMER_SEL0|TIMER_16BIT|TIMER_RATEGEN);
|
||||
outport_byte(TIMER_CNTR0, 0);
|
||||
outport_byte(TIMER_CNTR0, 0);
|
||||
}
|
||||
|
||||
static void timerOn(const rtems_raw_irq_connect_data* used)
|
||||
{
|
||||
/* load timer for US_PER_ISR microsecond period */
|
||||
outport_byte(TIMER_MODE, TIMER_SEL0|TIMER_16BIT|TIMER_RATEGEN);
|
||||
outport_byte(TIMER_CNTR0, US_TO_TICK(US_PER_ISR) >> 0 & 0xff);
|
||||
outport_byte(TIMER_CNTR0, US_TO_TICK(US_PER_ISR) >> 8 & 0xff);
|
||||
|
||||
/*
|
||||
* enable interrrupt at i8259 level
|
||||
*/
|
||||
BSP_irq_enable_at_i8259s(used->idtIndex - BSP_IRQ_VECTOR_BASE);
|
||||
}
|
||||
|
||||
static int timerIsOn(const rtems_raw_irq_connect_data *used)
|
||||
{
|
||||
return BSP_irq_enabled_at_i8259s(used->idtIndex - BSP_IRQ_VECTOR_BASE);
|
||||
}
|
||||
|
||||
static rtems_raw_irq_connect_data timer_raw_irq_data = {
|
||||
@@ -192,39 +152,35 @@ static rtems_raw_irq_connect_data timer_raw_irq_data = {
|
||||
timerIsOn
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------------------+
|
||||
| Function: Timer_exit
|
||||
| Description: Timer cleanup routine at RTEMS exit. NOTE: This routine is
|
||||
| not really necessary, since there will be a reset at exit.
|
||||
| Global Variables: None.
|
||||
| Arguments: None.
|
||||
| Returns: Nothing.
|
||||
+--------------------------------------------------------------------------*/
|
||||
void
|
||||
/*
|
||||
* Timer cleanup routine at RTEMS exit. NOTE: This routine is
|
||||
* not really necessary, since there will be a reset at exit.
|
||||
*/ void
|
||||
i386_timer_exit(void)
|
||||
{
|
||||
i386_delete_idt_entry (&timer_raw_irq_data);
|
||||
} /* Timer_exit */
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------+
|
||||
| Function: benchmark_timer_initialize
|
||||
| Description: Timer initialization routine.
|
||||
| Global Variables: Ttimer_val.
|
||||
| Arguments: None.
|
||||
| Returns: Nothing.
|
||||
+--------------------------------------------------------------------------*/
|
||||
void
|
||||
i386_timer_initialize(void)
|
||||
extern void rtems_irq_prologue_0(void);
|
||||
void i386_timer_initialize(void)
|
||||
{
|
||||
static bool First = true;
|
||||
|
||||
if (First)
|
||||
{
|
||||
First = false;
|
||||
if (First) {
|
||||
rtems_raw_irq_connect_data raw_irq_data = {
|
||||
BSP_PERIODIC_TIMER + BSP_IRQ_VECTOR_BASE,
|
||||
rtems_irq_prologue_0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
atexit(Timer_exit); /* Try not to hose the system at exit. */
|
||||
First = false;
|
||||
i386_delete_idt_entry (&raw_irq_data);
|
||||
|
||||
atexit(Timer_exit); /* Try not to hose the system at exit. */
|
||||
if (!i386_set_idt_entry (&timer_raw_irq_data)) {
|
||||
printk("raw handler connexion failed\n");
|
||||
printk("raw handler connection failed\n");
|
||||
rtems_fatal_error_occurred(1);
|
||||
}
|
||||
}
|
||||
@@ -233,17 +189,12 @@ i386_timer_initialize(void)
|
||||
while (Ttimer_val == 0)
|
||||
continue;
|
||||
Ttimer_val = 0;
|
||||
} /* benchmark_timer_initialize */
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------+
|
||||
| Function: benchmark_timer_read
|
||||
| Description: Read hardware timer value.
|
||||
| Global Variables: Ttimer_val, benchmark_timer_find_average_overhead.
|
||||
| Arguments: None.
|
||||
| Returns: Nothing.
|
||||
+--------------------------------------------------------------------------*/
|
||||
uint32_t
|
||||
i386_read_timer(void)
|
||||
/*
|
||||
* Read hardware timer value.
|
||||
*/
|
||||
uint32_t i386_read_timer(void)
|
||||
{
|
||||
register uint32_t total, clicks;
|
||||
register uint8_t lsb, msb;
|
||||
@@ -256,10 +207,11 @@ i386_read_timer(void)
|
||||
|
||||
if (benchmark_timer_find_average_overhead)
|
||||
return total;
|
||||
else if (total < LEAST_VALID)
|
||||
return 0; /* below timer resolution */
|
||||
else
|
||||
return (total - AVG_OVERHEAD);
|
||||
|
||||
if (total < LEAST_VALID)
|
||||
return 0; /* below timer resolution */
|
||||
|
||||
return (total - AVG_OVERHEAD);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -267,64 +219,56 @@ i386_read_timer(void)
|
||||
* or interrupt-based implementation
|
||||
*/
|
||||
|
||||
void
|
||||
benchmark_timer_initialize(void)
|
||||
void benchmark_timer_initialize(void)
|
||||
{
|
||||
static bool First = true;
|
||||
static bool First = true;
|
||||
|
||||
if (First) {
|
||||
if (x86_has_tsc()) {
|
||||
if (First) {
|
||||
if (x86_has_tsc()) {
|
||||
#if defined(DEBUG)
|
||||
printk("TSC: timer initialization\n");
|
||||
printk("TSC: timer initialization\n");
|
||||
#endif /* DEBUG */
|
||||
benchmark_timer_initialize_function = &tsc_timer_initialize;
|
||||
benchmark_timer_read_function = &tsc_read_timer;
|
||||
Timer_exit_function = &tsc_timer_exit;
|
||||
}
|
||||
else {
|
||||
benchmark_timer_initialize_function = &tsc_timer_initialize;
|
||||
benchmark_timer_read_function = &tsc_read_timer;
|
||||
Timer_exit_function = &tsc_timer_exit;
|
||||
} else {
|
||||
#if defined(DEBUG)
|
||||
printk("ISR: timer initialization\n");
|
||||
printk("ISR: timer initialization\n");
|
||||
#endif /* DEBUG */
|
||||
benchmark_timer_initialize_function = &i386_timer_initialize;
|
||||
benchmark_timer_read_function = &i386_read_timer;
|
||||
Timer_exit_function = &i386_timer_exit;
|
||||
}
|
||||
First = false;
|
||||
benchmark_timer_initialize_function = &i386_timer_initialize;
|
||||
benchmark_timer_read_function = &i386_read_timer;
|
||||
Timer_exit_function = &i386_timer_exit;
|
||||
}
|
||||
(*benchmark_timer_initialize_function)();
|
||||
First = false;
|
||||
}
|
||||
(*benchmark_timer_initialize_function)();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
benchmark_timer_read(void)
|
||||
uint32_t benchmark_timer_read(void)
|
||||
{
|
||||
return (*benchmark_timer_read_function)();
|
||||
return (*benchmark_timer_read_function)();
|
||||
}
|
||||
|
||||
void
|
||||
Timer_exit(void)
|
||||
void Timer_exit(void)
|
||||
{
|
||||
return (*Timer_exit_function)();
|
||||
return (*Timer_exit_function)();
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------+
|
||||
| Function: benchmark_timer_disable_subtracting_average_overhead
|
||||
| Description: Set internal benchmark_timer_find_average_overhead flag value.
|
||||
| Global Variables: benchmark_timer_find_average_overhead.
|
||||
| Arguments: find_flag - new value of the flag.
|
||||
| Returns: Nothing.
|
||||
+--------------------------------------------------------------------------*/
|
||||
void
|
||||
benchmark_timer_disable_subtracting_average_overhead(bool find_flag)
|
||||
/*
|
||||
* Set internal benchmark_timer_find_average_overhead flag value.
|
||||
*/
|
||||
void benchmark_timer_disable_subtracting_average_overhead(bool find_flag)
|
||||
{
|
||||
benchmark_timer_find_average_overhead = find_flag;
|
||||
} /* benchmark_timer_disable_subtracting_average_overhead */
|
||||
}
|
||||
|
||||
static unsigned short lastLoadedValue;
|
||||
|
||||
/*-------------------------------------------------------------------------+
|
||||
| Description: Loads timer 0 with value passed as arguemnt.
|
||||
| Returns: Nothing. Loaded value must be a number of clock bits...
|
||||
+--------------------------------------------------------------------------*/
|
||||
/*
|
||||
* Loads timer 0 with value passed as arguemnt.
|
||||
*
|
||||
* Returns: Nothing. Loaded value must be a number of clock bits...
|
||||
*/
|
||||
void loadTimerValue( unsigned short loadedValue )
|
||||
{
|
||||
lastLoadedValue = loadedValue;
|
||||
@@ -333,24 +277,28 @@ void loadTimerValue( unsigned short loadedValue )
|
||||
outport_byte(TIMER_CNTR0, (loadedValue >> 8) & 0xff);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------+
|
||||
| Description: Reads the current value of the timer, and converts the
|
||||
| number of ticks to micro-seconds.
|
||||
| Returns: number of clock bits elapsed since last load.
|
||||
+--------------------------------------------------------------------------*/
|
||||
/*
|
||||
* Reads the current value of the timer, and converts the
|
||||
* number of ticks to micro-seconds.
|
||||
*
|
||||
* Returns: number of clock bits elapsed since last load.
|
||||
*/
|
||||
unsigned int readTimer0(void)
|
||||
{
|
||||
unsigned short lsb, msb;
|
||||
unsigned char status;
|
||||
unsigned int count;
|
||||
unsigned int count;
|
||||
|
||||
outport_byte(TIMER_MODE, (TIMER_RD_BACK | (RB_COUNT_0 & ~(RB_NOT_STATUS | RB_NOT_COUNT))));
|
||||
outport_byte(
|
||||
TIMER_MODE,
|
||||
(TIMER_RD_BACK | (RB_COUNT_0 & ~(RB_NOT_STATUS | RB_NOT_COUNT)))
|
||||
);
|
||||
inport_byte(TIMER_CNTR0, status);
|
||||
inport_byte(TIMER_CNTR0, lsb);
|
||||
inport_byte(TIMER_CNTR0, msb);
|
||||
count = ( msb << 8 ) | lsb ;
|
||||
if (status & RB_OUTPUT )
|
||||
count += lastLoadedValue;
|
||||
count += lastLoadedValue;
|
||||
|
||||
return (2*lastLoadedValue - count);
|
||||
}
|
||||
@@ -387,7 +335,7 @@ Calibrate_loop_1ms(void)
|
||||
rtems_interrupt_level level;
|
||||
|
||||
#ifdef DEBUG_CALIBRATE
|
||||
printk( "Calibrate_loop_1ms is starting, please wait ( but not too loooong. )\n" );
|
||||
printk("Calibrate_loop_1ms is starting, please wait (but not too long.)\n");
|
||||
#endif
|
||||
targetClockBits = US_TO_TICK(1000);
|
||||
|
||||
@@ -459,9 +407,9 @@ Calibrate_loop_1ms(void)
|
||||
targetClockBits += offset;
|
||||
#ifdef DEBUG_CALIBRATE
|
||||
printk("offset = %u, emptyCall = %u, targetClockBits = %u\n",
|
||||
offset, emptyCall, targetClockBits);
|
||||
offset, emptyCall, targetClockBits);
|
||||
printk("slowLoopGranularity = %u fastLoopGranularity = %u\n",
|
||||
slowLoopGranularity, fastLoopGranularity);
|
||||
slowLoopGranularity, fastLoopGranularity);
|
||||
#endif
|
||||
slowLoop1ms = (targetClockBits - emptyCall) / slowLoopGranularity;
|
||||
if (slowLoop1ms != 0) {
|
||||
@@ -478,33 +426,33 @@ Calibrate_loop_1ms(void)
|
||||
|
||||
while(1)
|
||||
{
|
||||
int previousSign = 0; /* 0 = unset, 1 = incrementing, 2 = decrementing */
|
||||
Timer0Reset();
|
||||
slowLoop(slowLoop1ms);
|
||||
currentClockBits = readTimer0();
|
||||
if (currentClockBits > targetClockBits) {
|
||||
if ((currentClockBits - targetClockBits) < slowLoopGranularity) {
|
||||
/* decrement loop counter anyway to be sure slowLoop(slowLoop1ms) < targetClockBits */
|
||||
--slowLoop1ms;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
--slowLoop1ms;
|
||||
if (slowLoop1ms == 0) break;
|
||||
if (previousSign == 0) previousSign = 2;
|
||||
if (previousSign == 1) break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ((targetClockBits - currentClockBits) < slowLoopGranularity) {
|
||||
break;
|
||||
}
|
||||
else {
|
||||
++slowLoop1ms;
|
||||
if (previousSign == 0) previousSign = 1;
|
||||
if (previousSign == 2) break;
|
||||
}
|
||||
}
|
||||
int previousSign = 0; /* 0 = unset, 1 = incrementing, 2 = decrementing */
|
||||
Timer0Reset();
|
||||
slowLoop(slowLoop1ms);
|
||||
currentClockBits = readTimer0();
|
||||
if (currentClockBits > targetClockBits) {
|
||||
if ((currentClockBits - targetClockBits) < slowLoopGranularity) {
|
||||
/* decrement loop counter anyway to be sure slowLoop(slowLoop1ms) < targetClockBits */
|
||||
--slowLoop1ms;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
--slowLoop1ms;
|
||||
if (slowLoop1ms == 0) break;
|
||||
if (previousSign == 0) previousSign = 2;
|
||||
if (previousSign == 1) break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ((targetClockBits - currentClockBits) < slowLoopGranularity) {
|
||||
break;
|
||||
}
|
||||
else {
|
||||
++slowLoop1ms;
|
||||
if (previousSign == 0) previousSign = 1;
|
||||
if (previousSign == 2) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
@@ -519,22 +467,22 @@ Calibrate_loop_1ms(void)
|
||||
fastLoop(fastLoop1ms);
|
||||
currentClockBits = readTimer0();
|
||||
if (currentClockBits > targetClockBits) {
|
||||
if ((currentClockBits - targetClockBits) < fastLoopGranularity)
|
||||
break;
|
||||
else {
|
||||
--fastLoop1ms;
|
||||
if (previousSign == 0) previousSign = 2;
|
||||
if (previousSign == 1) break;
|
||||
}
|
||||
if ((currentClockBits - targetClockBits) < fastLoopGranularity)
|
||||
break;
|
||||
else {
|
||||
--fastLoop1ms;
|
||||
if (previousSign == 0) previousSign = 2;
|
||||
if (previousSign == 1) break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ((targetClockBits - currentClockBits) < fastLoopGranularity)
|
||||
break;
|
||||
else {
|
||||
++fastLoop1ms;
|
||||
if (previousSign == 0) previousSign = 1;
|
||||
if (previousSign == 2) break;
|
||||
}
|
||||
if ((targetClockBits - currentClockBits) < fastLoopGranularity)
|
||||
break;
|
||||
else {
|
||||
++fastLoop1ms;
|
||||
if (previousSign == 0) previousSign = 1;
|
||||
if (previousSign == 2) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -545,21 +493,15 @@ Calibrate_loop_1ms(void)
|
||||
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------+
|
||||
| Function: Wait_X_1ms
|
||||
| Description: loop which waits at least timeToWait ms
|
||||
| Global Variables: loop1ms
|
||||
| Arguments: timeToWait
|
||||
| Returns: Nothing.
|
||||
+--------------------------------------------------------------------------*/
|
||||
void
|
||||
Wait_X_ms( unsigned int timeToWait){
|
||||
|
||||
/*
|
||||
* loop which waits at least timeToWait ms
|
||||
*/
|
||||
void Wait_X_ms( unsigned int timeToWait)
|
||||
{
|
||||
unsigned int j;
|
||||
|
||||
for (j=0; j<timeToWait ; j++) {
|
||||
if (slowLoop1ms != 0) slowLoop(slowLoop1ms);
|
||||
fastLoop(fastLoop1ms);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user