Back to home page

LXR

 
 

    


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

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