Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:46

0001 /**
0002  *  @file
0003  *  @brief Timer Init
0004  *
0005  *  This module initializes TIMER 2 for on the MCF5206E for benchmarks.
0006  */
0007 
0008 /*
0009  *  Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russia
0010  *  Author: Victor V. Vengerov <vvv@oktet.ru>
0011  *
0012  *  Based on work:
0013  *  Author:
0014  *    David Fiddes, D.J@fiddes.surfaid.org
0015  *    http://www.calm.hw.ac.uk/davidf/coldfire/
0016  *
0017  *  COPYRIGHT (c) 1989-1998.
0018  *  On-Line Applications Research Corporation (OAR).
0019  *
0020  *  The license and distribution terms for this file may be
0021  *  found in the file LICENSE in this distribution or at
0022  *  http://www.rtems.org/license/LICENSE.
0023  */
0024 
0025 #include <rtems.h>
0026 #include <bsp.h>
0027 #include <rtems/btimer.h>
0028 #include "mcf5206/mcf5206e.h"
0029 
0030 #define TRR2_VAL 65530
0031 
0032 uint32_t   Timer_interrupts;
0033 
0034 bool benchmark_timer_find_average_overhead;
0035 
0036 /* External assembler interrupt handler routine */
0037 extern rtems_isr timerisr(rtems_vector_number vector);
0038 
0039 
0040 /* benchmark_timer_initialize --
0041  *     Initialize timer 2 for accurate time measurement.
0042  *
0043  * PARAMETERS:
0044  *     none
0045  *
0046  * RETURNS:
0047  *     none
0048  */
0049 void
0050 benchmark_timer_initialize(void)
0051 {
0052     /* Catch timer2 interrupts */
0053     set_vector(timerisr, BSP_INTVEC_TIMER2, 0);
0054 
0055     /* Initialize interrupts for timer2 */
0056     *MCF5206E_ICR(MBAR, MCF5206E_INTR_TIMER_2) =
0057         MCF5206E_ICR_AVEC |
0058         ((BSP_INTLVL_TIMER2 << MCF5206E_ICR_IL_S) & MCF5206E_ICR_IL) |
0059         ((BSP_INTPRIO_TIMER2 << MCF5206E_ICR_IP_S) & MCF5206E_ICR_IP);
0060 
0061     /* Enable interrupts from timer2 */
0062     *MCF5206E_IMR(MBAR) &= ~MCF5206E_INTR_BIT(MCF5206E_INTR_TIMER_2);
0063 
0064     /* Reset Timer */
0065     *MCF5206E_TMR(MBAR, 2) = MCF5206E_TMR_RST;
0066     *MCF5206E_TMR(MBAR, 2) = MCF5206E_TMR_ICLK_STOP;
0067     *MCF5206E_TMR(MBAR, 2) = MCF5206E_TMR_RST;
0068     *MCF5206E_TCN(MBAR, 2) = 0; /* Zero timer counter */
0069     Timer_interrupts = 0; /* Clear timer ISR counter */
0070     *MCF5206E_TER(MBAR, 2) = MCF5206E_TER_REF | MCF5206E_TER_CAP; /*clr pend*/
0071     *MCF5206E_TRR(MBAR, 2) = TRR2_VAL - 1;
0072     *MCF5206E_TMR(MBAR, 2) =
0073         (((BSP_SYSTEM_FREQUENCY / 1000000) << MCF5206E_TMR_PS_S) &
0074           MCF5206E_TMR_PS) |
0075         MCF5206E_TMR_CE_NONE | MCF5206E_TMR_ORI | MCF5206E_TMR_FRR |
0076         MCF5206E_TMR_RST;
0077     *MCF5206E_TMR(MBAR, 2) |= MCF5206E_TMR_ICLK_MSCLK;
0078 }
0079 
0080 /*
0081  *  The following controls the behavior of benchmark_timer_read().
0082  *
0083  *  FIND_AVG_OVERHEAD *  instructs the routine to return the "raw" count.
0084  *
0085  *  AVG_OVEREHAD is the overhead for starting and stopping the timer.  It
0086  *  is usually deducted from the number returned.
0087  *
0088  *  LEAST_VALID is the lowest number this routine should trust.  Numbers
0089  *  below this are "noise" and zero is returned.
0090  */
0091 
0092 #define AVG_OVERHEAD      0  /* It typically takes 2.0 microseconds */
0093                              /* (Y countdowns) to start/stop the timer. */
0094                              /* This value is in microseconds. */
0095 #define LEAST_VALID       1  /* Don't trust a clicks value lower than this */
0096 
0097 /* benchmark_timer_read --
0098  *     Read timer value in microsecond units since timer start.
0099  *
0100  * PARAMETERS:
0101  *     none
0102  *
0103  * RETURNS:
0104  *     number of microseconds since timer has been started
0105  */
0106 benchmark_timer_t
0107 benchmark_timer_read( void )
0108 {
0109     uint16_t   clicks;
0110     uint32_t   total;
0111 
0112     /*
0113      *  Read the timer and see how many clicks it has been since counter
0114      *  rolled over.
0115      */
0116     clicks = *MCF5206E_TCN(MBAR, 2);
0117 
0118     /* Stop Timer... */
0119     *MCF5206E_TMR(MBAR, 2) = MCF5206E_TMR_ICLK_STOP |
0120                              MCF5206E_TMR_RST;
0121 
0122     /*
0123      *  Total is calculated by taking into account the number of timer
0124      *  overflow interrupts since the timer was initialized and clicks
0125      *  since the last interrupts.
0126      */
0127 
0128     total = (Timer_interrupts * TRR2_VAL) + clicks;
0129 
0130     if ( benchmark_timer_find_average_overhead == 1 )
0131         return total;          /* in XXX microsecond units */
0132 
0133     if ( total < LEAST_VALID )
0134         return 0;            /* below timer resolution */
0135 
0136     /*
0137      *  Return the count in microseconds
0138      */
0139     return (total - AVG_OVERHEAD);
0140 }
0141 
0142 /* benchmark_timer_disable_subtracting_average_overhead --
0143  *     This routine is invoked by the "Check Timer" (tmck) test in the
0144  *     RTEMS Timing Test Suite. It makes the benchmark_timer_read routine not
0145  *     subtract the overhead required to initialize and read the benchmark
0146  *     timer.
0147  *
0148  * PARAMETERS:
0149  *     find_flag - boolean flag, true if overhead must not be subtracted.
0150  *
0151  * RETURNS:
0152  *     none
0153  */
0154 void
0155 benchmark_timer_disable_subtracting_average_overhead(bool find_flag)
0156 {
0157   benchmark_timer_find_average_overhead = find_flag;
0158 }