summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2010-05-10 00:29:30 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2010-05-10 00:29:30 +0000
commit171f8346c68079c5420ecd28ac03ed3ee2502b2a (patch)
tree6bbffb81f2169a20ac3503b5b2adf08b65317f1c
parent2010-05-09 Joel Sherrill <joel.sherrill@oarcorp.com> (diff)
downloadrtems-171f8346c68079c5420ecd28ac03ed3ee2502b2a.tar.bz2
2010-05-09 Joel Sherrill <joel.sherrill@oarcorp.com>
* timer/timer.c: Now runs on 486 and below again. Reformatted.
-rw-r--r--c/src/lib/libbsp/i386/pc386/ChangeLog4
-rw-r--r--c/src/lib/libbsp/i386/pc386/timer/timer.c496
2 files changed, 223 insertions, 277 deletions
diff --git a/c/src/lib/libbsp/i386/pc386/ChangeLog b/c/src/lib/libbsp/i386/pc386/ChangeLog
index bfa0fee9af..8d914d5bfa 100644
--- a/c/src/lib/libbsp/i386/pc386/ChangeLog
+++ b/c/src/lib/libbsp/i386/pc386/ChangeLog
@@ -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
diff --git a/c/src/lib/libbsp/i386/pc386/timer/timer.c b/c/src/lib/libbsp/i386/pc386/timer/timer.c
index 534813e789..ff3eb0040e 100644
--- a/c/src/lib/libbsp/i386/pc386/timer/timer.c
+++ b/c/src/lib/libbsp/i386/pc386/timer/timer.c
@@ -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') */
+
+void Timer_exit(void);
/*
- * forward declarations
+ * Pentium optimized timer handling.
*/
-void Timer_exit(void);
+/*
+ * Timer cleanup routine at RTEMS exit. NOTE: This routine is
+ * not really necessary, since there will be a reset at exit.
+ */
-/*-------------------------------------------------------------------------+
-| 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)
+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.
-+--------------------------------------------------------------------------*/
+ if (total < LEAST_VALID)
+ return 0; /* below timer resolution */
+
+ return (total - AVG_OVERHEAD);
+}
+
+/*
+ * Non-Pentium timer handling.
+ */
#define US_PER_ISR 250 /* Number of micro-seconds per timer interruption */
-/*-------------------------------------------------------------------------+
-| 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)
+/*
+ * 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)
{
- /*
- * 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)
+ /*
+ * 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);
+ /* 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)
+static int timerIsOn(const rtems_raw_irq_connect_data *used)
{
- return BSP_irq_enabled_at_i8259s(used->idtIndex - BSP_IRQ_VECTOR_BASE);
+ 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)
- {
+ if (First) {
+ rtems_raw_irq_connect_data raw_irq_data = {
+ BSP_PERIODIC_TIMER + BSP_IRQ_VECTOR_BASE,
+ rtems_irq_prologue_0,
+ NULL,
+ NULL,
+ NULL
+ };
+
First = false;
+ i386_delete_idt_entry (&raw_irq_data);
- atexit(Timer_exit); /* Try not to hose the system at exit. */
+ 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);
}
-
}