Exemple #1
0
/*
 * Application entry point.
 */
int main(void)
{
  /*
   * System initializations.
   * - HAL initialization, this also initializes the configured device drivers
   *   and performs the board-specific initializations.
   * - Kernel initialization, the main() function becomes a thread and the
   *   RTOS is active.
   */
  halInit();
  chSysInit();

  palSetPadMode(GPIOF, GPIOF_LED_RED, PAL_MODE_OUTPUT_PUSHPULL);

  /*
   * Start the gpt drivers with the custom configurations.
   */
  gptStart(&GPTD1, &gpt1cfg);
  gptStart(&GPTD7, &gpt7cfg);

  /*
   * Normal main() thread activity
   */
  while (TRUE) {
    gptStartContinuous(&GPTD7, 5000);
    chThdSleepMilliseconds(5000);
    gptStopTimer(&GPTD7);
    gptStartContinuous(&GPTD7, 2500);
    chThdSleepMilliseconds(5000);
    gptStopTimer(&GPTD7);
  }
  
  return 0;
}
Exemple #2
0
/*
 * Application entry point.
 */
int main(void) {

  /*
   * System initializations.
   * - HAL initialization, this also initializes the configured device drivers
   *   and performs the board-specific initializations.
   * - Kernel initialization, the main() function becomes a thread and the
   *   RTOS is active.
   */
  halInit();
  chSysInit();

  /*
   * Initializes the GPT drivers 2 and 3.
   */
  gptStart(&GPTD2, &gpt2cfg);
  gptPolledDelay(&GPTD2, 10); /* Small delay.*/
  gptStart(&GPTD3, &gpt3cfg);
  gptPolledDelay(&GPTD3, 10); /* Small delay.*/

  /*
   * Normal main() thread activity, it changes the GPT1 period every
   * five seconds.
   */
  while (TRUE) {
    palSetPad(GPIOD, GPIOD_LED4);
    gptStartContinuous(&GPTD2, 5000);
    chThdSleepMilliseconds(5000);
    gptStopTimer(&GPTD2);
    palClearPad(GPIOD, GPIOD_LED4);
    gptStartContinuous(&GPTD2, 2500);
    chThdSleepMilliseconds(5000);
    gptStopTimer(&GPTD2);
  }
}
void dcf_task(arg_t c)
{
	(void) c;
	static uint8_t machine = 0;

	// machine start
	if (machine == 0)
	{
		ma_disable(1);
		gptStartContinuous(timer, 100);
		machine++;
	}
	else if (machine == 1)
	{
		if (decode_finished)
		{
			decode_finished = 0;
			machine = 0;
			shUnregisterStruct(&del);
			gptStopTimer(timer);
			dcf_decode();
			ma_disable(0);
			rdy = 1;
		}
	}
}
void
vMBPortTimersDisable(  )
{
  if (bMBPortIsWithinException() == TRUE)
    gptStopTimerI (&GPTDRIVER);
  else
    gptStopTimer (&GPTDRIVER);
}
void
vMBPortTimersEnable(  )
{
#ifdef DEBUG_MB
  palClearPad (BOARD_LED2_P, BOARD_LED2);
  tmStartMeasurement (&tm);
#endif
  if (bMBPortIsWithinException() == TRUE) {
    gptStopTimerI (&GPTDRIVER);
    gptStartOneShotI(&GPTDRIVER, timerout);
  } else { 
    gptStopTimer (&GPTDRIVER);
    gptStartOneShot(&GPTDRIVER, timerout);
  }
}
Exemple #6
0
void setTimer(uint32_t delay)
{
	timer1_interval = delay / DIV;
	if (dbg_is_isr())
	{
		chSysLockFromIsr();
	  	gptStartOneShotI(&GPTD1, timer1_interval);
	   	chSysUnlockFromIsr();
	}
	else
	{
		gptStopTimer (&GPTD1);
		gptStartOneShot (&GPTD1, timer1_interval);
	}
}
Exemple #7
0
void stop_all_notes() {
    dprintf("audio stop all notes");

    if (!audio_initialized) {
        audio_init();
    }
    voices = 0;

    gptStopTimer(&GPTD6);
    gptStopTimer(&GPTD7);
    gptStopTimer(&GPTD8);

    playing_notes = false;
    playing_note = false;
    frequency = 0;
    frequency_alt = 0;
    volume = 0;

    for (uint8_t i = 0; i < 8; i++)
    {
        frequencies[i] = 0;
        volumes[i] = 0;
    }
}
Exemple #8
0
/*
 * Application entry point.
 */
int main(void) {

  /*
   * System initializations.
   * - HAL initialization, this also initializes the configured device drivers
   *   and performs the board-specific initializations.
   * - Kernel initialization, the main() function becomes a thread and the
   *   RTOS is active.
   */
  halInit();
  chSysInit();

  /*
   * Starting DAC1 driver, setting up the output pins as analog as suggested
   * by the Reference Manual.
   */
  palSetPadMode(GPIOA, 4, PAL_MODE_INPUT_ANALOG);
  palSetPadMode(GPIOA, 5, PAL_MODE_INPUT_ANALOG);
  dacStart(&DACD1, &dac1cfg1);

  /*
   * Starting GPT6 driver, it is used for triggering the DAC.
   */
  gptStart(&GPTD6, &gpt6cfg1);

  /*
   * Starting a continuous conversion.
   * Note, the buffer size is divided by two because two elements are fetched
   * for each transfer.
   */
  dacStartConversion(&DACD1, &dacgrpcfg1,
                     (dacsample_t *)dac_buffer, DAC_BUFFER_SIZE / 2U);
  gptStartContinuous(&GPTD6, 2U);

  /*
   * Normal main() thread activity, if the button is pressed then the DAC
   * transfer is stopped.
   */
  while (true) {
    if (palReadPad(GPIOA, GPIOA_BUTTON)) {
      gptStopTimer(&GPTD6);
      dacStopConversion(&DACD1);
    }
    chThdSleepMilliseconds(500);
  }
  return 0;
}
Exemple #9
0
void stop_note(float freq) {
  dprintf("audio stop note freq=%d", (int)freq);

  if (playing_note) {
    if (!audio_initialized) {
      audio_init();
    }
    for (int i = 7; i >= 0; i--) {
      if (frequencies[i] == freq) {
        frequencies[i] = 0;
        volumes[i] = 0;
        for (int j = i; (j < 7); j++) {
          frequencies[j] = frequencies[j+1];
          frequencies[j+1] = 0;
          volumes[j] = volumes[j+1];
          volumes[j+1] = 0;
        }
        break;
      }
    }
    voices--;
    if (voices < 0) {
      voices = 0;
    }
    if (voice_place >= voices) {
      voice_place = 0;
    }
    if (voices == 0) {
      STOP_CHANNEL_1();
      STOP_CHANNEL_2();
      gptStopTimer(&GPTD8);
      frequency = 0;
      frequency_alt = 0;
      volume = 0;
      playing_note = false;
    }
  }
}
Exemple #10
0
/*
 * Application entry point.
 */
int main(void) {
  unsigned i;
  gptcnt_t interval, threshold, worst;

  /*
   * System initializations.
   * - HAL initialization, this also initializes the configured device drivers
   *   and performs the board-specific initializations.
   * - Kernel initialization, the main() function becomes a thread and the
   *   RTOS is active.
   */
  halInit();
  chSysInit();

  /*
   * Prepares the Serial driver 2 and GPT drivers 1 and 2.
   */
  sdStart(&SD1, NULL);          /* Default is 38400-8-N-1.*/
  gptStart(&GPTD1, &gpt1cfg);
  gptStart(&GPTD2, &gpt2cfg);

  /*
   * Initializes the mailboxes and creates the worker threads.
   */
  for (i = 0; i < NUM_THREADS; i++) {
    chMBInit(&mb[i], b[i], MAILBOX_SIZE);
    chThdCreateStatic(waWorkerThread[i], sizeof waWorkerThread[i],
                      NORMALPRIO - 20, WorkerThread, (void *)i);
  }

  /*
   * Test procedure.
   */
  println("");
  println("*** ChibiOS/RT IRQ-STORM long duration test");
  println("***");
  print("*** Kernel:       ");
  println(CH_KERNEL_VERSION);
#ifdef CH_COMPILER_NAME
  print("*** Compiler:     ");
  println(CH_COMPILER_NAME);
#endif
  print("*** Architecture: ");
  println(CH_ARCHITECTURE_NAME);
#ifdef CH_CORE_VARIANT_NAME
  print("*** Core Variant: ");
  println(CH_CORE_VARIANT_NAME);
#endif
#ifdef CH_PORT_INFO
  print("*** Port Info:    ");
  println(CH_PORT_INFO);
#endif
#ifdef PLATFORM_NAME
  print("*** Platform:     ");
  println(PLATFORM_NAME);
#endif
#ifdef BOARD_NAME
  print("*** Test Board:   ");
  println(BOARD_NAME);
#endif
  println("***");
  print("*** System Clock: ");
  printn(LPC13xx_SYSCLK);
  println("");
  print("*** Iterations:   ");
  printn(ITERATIONS);
  println("");
  print("*** Randomize:    ");
  printn(RANDOMIZE);
  println("");
  print("*** Threads:      ");
  printn(NUM_THREADS);
  println("");
  print("*** Mailbox size: ");
  printn(MAILBOX_SIZE);
  println("");

  println("");
  worst = 0;
  for (i = 1; i <= ITERATIONS; i++){
    print("Iteration ");
    printn(i);
    println("");
    saturated = FALSE;
    threshold = 0;
    for (interval = 2000; interval >= 20; interval -= interval / 10) {
      gptStartContinuous(&GPTD1, interval - 1); /* Slightly out of phase.*/
      gptStartContinuous(&GPTD2, interval + 1); /* Slightly out of phase.*/
      chThdSleepMilliseconds(1000);
      gptStopTimer(&GPTD1);
      gptStopTimer(&GPTD2);
      if (!saturated)
        print(".");
      else {
        print("#");
        if (threshold == 0)
          threshold = interval;
      }
    }
    /* Gives the worker threads a chance to empty the mailboxes before next
       cycle.*/
    chThdSleepMilliseconds(20);
    println("");
    print("Saturated at ");
    printn(threshold);
    println(" uS");
    println("");
    if (threshold > worst)
      worst = threshold;
  }
  gptStopTimer(&GPTD1);
  gptStopTimer(&GPTD2);

  print("Worst case at ");
  printn(worst);
  println(" uS");
  println("");
  println("Test Complete");

  /*
   * Normal main() thread activity, nothing in this test.
   */
  while (TRUE) {
    chThdSleepMilliseconds(5000);
  }
  return 0;
}
Exemple #11
0
/**
 * @brief   IRQ storm execution.
 *
 * @param[in] cfg       pointer to the test configuration structure
 *
 * @api
 */
void irq_storm_execute(const irq_storm_config_t *cfg) {
  unsigned i;
  gptcnt_t interval, threshold, worst;

  /* Global configuration pointer.*/
  config = cfg;

  /* Starting timers using the stored configurations.*/
  gptStart(cfg->gpt1p, cfg->gptcfg1p);
  gptStart(cfg->gpt2p, cfg->gptcfg2p);

  /*
   * Initializes the mailboxes and creates the worker threads.
   */
  for (i = 0; i < IRQ_STORM_CFG_NUM_THREADS; i++) {
    chMBObjectInit(&mb[i], b[i], IRQ_STORM_CFG_MAILBOX_SIZE);
    threads[i] = chThdCreateStatic(irq_storm_thread_wa[i],
                                   sizeof irq_storm_thread_wa[i],
                                   IRQ_STORM_CFG_THREADS_PRIORITY,
                                   irq_storm_thread,
                                   (void *)i);
  }

  /* Printing environment information.*/
  chprintf(cfg->out, "");
  chprintf(cfg->out, "\r\n*** ChibiOS/RT IRQ-STORM long duration test\r\n***\r\n");
  chprintf(cfg->out, "*** Kernel:       %s\r\n", CH_KERNEL_VERSION);
  chprintf(cfg->out, "*** Compiled:     %s\r\n", __DATE__ " - " __TIME__);
#ifdef PORT_COMPILER_NAME
  chprintf(cfg->out, "*** Compiler:     %s\r\n", PORT_COMPILER_NAME);
#endif
  chprintf(cfg->out, "*** Architecture: %s\r\n", PORT_ARCHITECTURE_NAME);
#ifdef PORT_CORE_VARIANT_NAME
  chprintf(cfg->out, "*** Core Variant: %s\r\n", PORT_CORE_VARIANT_NAME);
#endif
  chprintf(cfg->out, "*** System Clock: %d\r\n", cfg->sysclk);
#ifdef PORT_INFO
  chprintf(cfg->out, "*** Port Info:    %s\r\n", PORT_INFO);
#endif
#ifdef PLATFORM_NAME
  chprintf(cfg->out, "*** Platform:     %s\r\n", PLATFORM_NAME);
#endif
#ifdef BOARD_NAME
  chprintf(cfg->out, "*** Test Board:   %s\r\n", BOARD_NAME);
#endif
  chprintf(cfg->out, "***\r\n");
  chprintf(cfg->out, "*** Iterations:   %d\r\n", IRQ_STORM_CFG_ITERATIONS);
  chprintf(cfg->out, "*** Randomize:    %d\r\n", IRQ_STORM_CFG_RANDOMIZE);
  chprintf(cfg->out, "*** Threads:      %d\r\n", IRQ_STORM_CFG_NUM_THREADS);
  chprintf(cfg->out, "*** Mailbox size: %d\r\n\r\n", IRQ_STORM_CFG_MAILBOX_SIZE);

  /* Test loop.*/
  worst = 0;
  for (i = 1; i <= IRQ_STORM_CFG_ITERATIONS; i++){

    chprintf(cfg->out, "Iteration %d\r\n", i);
    saturated = false;
    threshold = 0;

    /* Timer intervals starting at 2mS then decreased by 10% after each
       cycle.*/
    for (interval = 2000; interval >= 2; interval -= (interval + 9) / 10) {

      /* Timers programmed slightly out of phase each other.*/
      gptStartContinuous(cfg->gpt1p, interval - 1); /* Slightly out of phase.*/
      gptStartContinuous(cfg->gpt2p, interval + 1); /* Slightly out of phase.*/

      /* Storming for one second.*/
      chThdSleepMilliseconds(1000);

      /* Timers stopped.*/
      gptStopTimer(cfg->gpt1p);
      gptStopTimer(cfg->gpt2p);

      /* Did the storm saturate the threads chain?*/
      if (!saturated)
        chprintf(cfg->out, ".");
      else {
        chprintf(cfg->out, "#");
        if (threshold == 0)
          threshold = interval;
        break;
      }
    }
    /* Gives threads a chance to empty the mailboxes before next cycle.*/
    chThdSleepMilliseconds(20);
    chprintf(cfg->out, "\r\nSaturated at %d uS\r\n\r\n", threshold);
    if (threshold > worst)
      worst = threshold;
  }
  gptStopTimer(cfg->gpt1p);
  gptStopTimer(cfg->gpt2p);

  chprintf(cfg->out, "Worst case at %d uS\r\n", worst);
  chprintf(cfg->out, "\r\nTest Complete\r\n");

  /* Terminating threads and cleaning up.*/
  for (i = 0; i < IRQ_STORM_CFG_NUM_THREADS; i++) {
    chThdTerminate(threads[i]);
    chThdWait(threads[i]);
    threads[i] = NULL;
  }
}
Exemple #12
0
/*
 * Application entry point.
 */
int main(void) {
  unsigned i;
  gptcnt_t interval, threshold, worst;

  /* Enables FPU exceptions.*/
  nvicEnableVector(FPU_IRQn, 1);

  /*
   * System initializations.
   * - HAL initialization, this also initializes the configured device drivers
   *   and performs the board-specific initializations.
   * - Kernel initialization, the main() function becomes a thread and the
   *   RTOS is active.
   */
  halInit();
  chSysInit();

  /*
   * Prepares the Serial driver 2 and GPT drivers 4 and 3.
   */
  sdStart(&SD2, NULL);          /* Default is 38400-8-N-1.*/
  palSetPadMode(GPIOA, 2, PAL_MODE_ALTERNATE(7));
  palSetPadMode(GPIOA, 3, PAL_MODE_ALTERNATE(7));
  gptStart(&GPTD4, &gpt4cfg);
  gptStart(&GPTD3, &gpt3cfg);

  /*
   * Enabling TIM1 as a fast interrupts source.
   */
  rccEnableTIM1(false);
  nvicEnableVector(STM32_TIM1_UP_NUMBER, 0);
  TIM1->ARR  = 10000;
  TIM1->PSC  = 0;
  TIM1->CNT  = 0;
  TIM1->DIER = TIM_DIER_UIE;
  TIM1->CR1  = TIM_CR1_CEN;

  /*
   * Initializes the worker threads.
   */
  chThdCreateStatic(waWorkerThread, sizeof waWorkerThread,
                    NORMALPRIO - 20, WorkerThread, NULL);
  chThdCreateStatic(waPeriodicThread, sizeof waPeriodicThread,
                    NORMALPRIO - 10, PeriodicThread, NULL);

  /*
   * Test procedure.
   */
  println("");
  println("*** ChibiOS/RT IRQ-STORM-FPU long duration test");
  println("***");
  print("*** Kernel:       ");
  println(CH_KERNEL_VERSION);
  print("*** Compiled:     ");
  println(__DATE__ " - " __TIME__);
#ifdef PORT_COMPILER_NAME
  print("*** Compiler:     ");
  println(PORT_COMPILER_NAME);
#endif
  print("*** Architecture: ");
  println(PORT_ARCHITECTURE_NAME);
#ifdef PORT_CORE_VARIANT_NAME
  print("*** Core Variant: ");
  println(PORT_CORE_VARIANT_NAME);
#endif
#ifdef PORT_INFO
  print("*** Port Info:    ");
  println(PORT_INFO);
#endif
#ifdef PLATFORM_NAME
  print("*** Platform:     ");
  println(PLATFORM_NAME);
#endif
#ifdef BOARD_NAME
  print("*** Test Board:   ");
  println(BOARD_NAME);
#endif
  println("***");
  print("*** System Clock: ");
  printn(STM32_SYSCLK);
  println("");
  print("*** Iterations:   ");
  printn(ITERATIONS);
  println("");
  print("*** Randomize:    ");
  printn(RANDOMIZE);
  println("");

  println("");
  worst = 0;
  for (i = 1; i <= ITERATIONS; i++){
    print("Iteration ");
    printn(i);
    println("");
    saturated = FALSE;
    threshold = 0;
    for (interval = 2000; interval >= 10; interval -= interval / 10) {
      gptStartContinuous(&GPTD4, interval - 1); /* Slightly out of phase.*/
      gptStartContinuous(&GPTD3, interval + 1); /* Slightly out of phase.*/
      chThdSleepMilliseconds(1000);
      gptStopTimer(&GPTD4);
      gptStopTimer(&GPTD3);
      if (!saturated)
        print(".");
      else {
        print("#");
        if (threshold == 0)
          threshold = interval;
      }
    }
    /* Gives the worker threads a chance to empty the mailboxes before next
       cycle.*/
    chThdSleepMilliseconds(20);
    println("");
    print("Saturated at ");
    printn(threshold);
    println(" uS");
    println("");
    if (threshold > worst)
      worst = threshold;
  }
  gptStopTimer(&GPTD4);
  gptStopTimer(&GPTD3);

  print("Worst case at ");
  printn(worst);
  println(" uS");
  println("");
  println("Test Complete");

  /*
   * Normal main() thread activity, nothing in this test.
   */
  while (true) {
    chThdSleepMilliseconds(5000);
  }
}
Exemple #13
0
static void buzzer_stop() {
   gptStopTimer(&BUZZER_GPT);
   clearPin(BUZZER);
//   gptStop(&AFSK_TONEGEN_GPT);
}
Exemple #14
0
static void timer_stop(){
	gptStopTimer(timer_driver);
}
Exemple #15
0
//-----------------------------------------------------------------------------
static void
cmd_tcxo_test(BaseSequentialStream * chp, int argc, char * argv[])
{
    uint32_t passes = 0;
    if ( argc == 0 )
    {
        passes = PASSES;
    }
    else
    {
        passes = atoi(argv[0]);
        if ( passes > PASSES )
        {
            chprintf(chp, "WARNING: you asked for too many passes (%d), doing just (%d)\n",
                     passes, PASSES);
            passes = PASSES;
        }
    }

    //--------------------------------------------------------------------------
    gptStart(&GPTD2, &one_sec_cfg);
    gptStartContinuous(&GPTD2, 84000000-(factory_config.tcxo_compensation/2));

    // wait X seconds to make sure the GPS has started up...
    pps = 0;
    while (pps < 5)
    {
        st7565_clear(&ST7565D1);
        st7565_drawstring(&ST7565D1, 0, 0, "TCXO vs GPS TEST");
        INIT_CBUF();
        chprintf(bss, "Waiting on GPS: %d", 5-pps);
        st7565_drawstring(&ST7565D1, 0, 1, charbuf);
        st7565_display(&ST7565D1);
        chThdSleepMilliseconds(50);
    }

    kbg_setLED2(0);

    st7565_clear(&ST7565D1);
    chprintf(chp, "pass,PASSES,pps_diff\n");

    for ( uint32_t pass = 0 ; pass < passes ; )
    {
        chThdSleepMilliseconds(50);
        if ( one_sec_pps_changed )
        {
            kbg_setLED3(1);
            times[pass] = one_sec_pps_diff;
            int32_t diff_from_parity = 168000000 - pps_diff;
            chprintf(chp, "%6d,%6d,%14d,%6d,%14d\n", pass+1, passes,
                     one_sec_pps_diff, one_sec_pps_diff_diff, diff_from_parity);
            one_sec_pps_changed = FALSE;
            pass++;

            st7565_drawstring(&ST7565D1, 0, 0, "TCXO vs GPS CONF");

            INIT_CBUF();
            chprintf(bss,"Doing %d passes", passes);
            st7565_drawstring(&ST7565D1, 0, 1, charbuf);

            INIT_CBUF();
            chprintf(bss,"Pass: %d", pass);
            st7565_drawstring(&ST7565D1, 0, 2, charbuf);

            INIT_CBUF();
            chprintf(bss,"Time diff: %d", one_sec_pps_diff);
            st7565_drawstring(&ST7565D1, 0, 3, charbuf);

            st7565_display(&ST7565D1);
            st7565_clear(&ST7565D1);

            chThdSleepMilliseconds(10);
            kbg_setLED3(0);
        }
    }
    gptStopTimer(&GPTD2);
    gptStop(&GPTD2);
}
Exemple #16
0
/*
 * Application entry point.
 */
int main(void) {
  unsigned i;
  gptcnt_t interval, threshold, worst;

  /*
   * System initializations.
   * - HAL initialization, this also initializes the configured device drivers
   *   and performs the board-specific initializations.
   * - Kernel initialization, the main() function becomes a thread and the
   *   RTOS is active.
   */
  halInit();
  chSysInit();

  /*
   * Activates the serial driver 1, PA9 and PA10 are routed to USART1.
   */
  sdStart(&SD1, NULL);
  palSetPadMode(GPIOA, 9, PAL_MODE_ALTERNATE(7));       /* USART1 TX.       */
  palSetPadMode(GPIOA, 10, PAL_MODE_ALTERNATE(7));      /* USART1 RX.       */

  /*
   * Activates GPTs.
   */
  gptStart(&GPTD4, &gpt4cfg);
  gptStart(&GPTD3, &gpt3cfg);

  /*
   * Initializes the mailboxes and creates the worker threads.
   */
  for (i = 0; i < NUM_THREADS; i++) {
    chMBObjectInit(&mb[i], b[i], MAILBOX_SIZE);
    chThdCreateStatic(waWorkerThread[i], sizeof waWorkerThread[i],
                      NORMALPRIO - 20, WorkerThread, (void *)i);
  }

  /*
   * Test procedure.
   */
  println("");
  println("*** ChibiOS/RT IRQ-STORM long duration test");
  println("***");
  print("*** Kernel:       ");
  println(CH_KERNEL_VERSION);
  print("*** Compiled:     ");
  println(__DATE__ " - " __TIME__);
#ifdef PORT_COMPILER_NAME
  print("*** Compiler:     ");
  println(PORT_COMPILER_NAME);
#endif
  print("*** Architecture: ");
  println(PORT_ARCHITECTURE_NAME);
#ifdef PORT_CORE_VARIANT_NAME
  print("*** Core Variant: ");
  println(PORT_CORE_VARIANT_NAME);
#endif
#ifdef PORT_INFO
  print("*** Port Info:    ");
  println(PORT_INFO);
#endif
#ifdef PLATFORM_NAME
  print("*** Platform:     ");
  println(PLATFORM_NAME);
#endif
#ifdef BOARD_NAME
  print("*** Test Board:   ");
  println(BOARD_NAME);
#endif
  println("***");
  print("*** System Clock: ");
  printn(STM32_SYSCLK);
  println("");
  print("*** Iterations:   ");
  printn(ITERATIONS);
  println("");
  print("*** Randomize:    ");
  printn(RANDOMIZE);
  println("");
  print("*** Threads:      ");
  printn(NUM_THREADS);
  println("");
  print("*** Mailbox size: ");
  printn(MAILBOX_SIZE);
  println("");

  println("");
  worst = 0;
  for (i = 1; i <= ITERATIONS; i++){
    print("Iteration ");
    printn(i);
    println("");
    saturated = FALSE;
    threshold = 0;
    for (interval = 2000; interval >= 10; interval -= interval / 10) {
      gptStartContinuous(&GPTD4, interval - 1); /* Slightly out of phase.*/
      gptStartContinuous(&GPTD3, interval + 1); /* Slightly out of phase.*/
      chThdSleepMilliseconds(1000);
      gptStopTimer(&GPTD4);
      gptStopTimer(&GPTD3);
      if (!saturated)
        print(".");
      else {
        print("#");
        if (threshold == 0)
          threshold = interval;
      }
    }
    /* Gives the worker threads a chance to empty the mailboxes before next
       cycle.*/
    chThdSleepMilliseconds(20);
    println("");
    print("Saturated at ");
    printn(threshold);
    println(" uS");
    println("");
    if (threshold > worst)
      worst = threshold;
  }
  gptStopTimer(&GPTD4);
  gptStopTimer(&GPTD3);

  print("Worst case at ");
  printn(worst);
  println(" uS");
  println("");
  println("Test Complete");

  /*
   * Normal main() thread activity, nothing in this test.
   */
  while (TRUE) {
    chThdSleepMilliseconds(5000);
  }
}