source: rtems/c/src/lib/libcpu/sh/sh7032/timer/timer.c @ 3942cce

4.104.114.95
Last change on this file since 3942cce was 3942cce, checked in by Ralf Corsepius <ralf.corsepius@…>, on 09/05/08 at 12:11:47

Convert to "bool".

  • Property mode set to 100644
File size: 5.2 KB
Line 
1/*
2 *  timer for the Hitachi SH 703X
3 *
4 *  This file manages the benchmark timer used by the RTEMS Timing Test
5 *  Suite.  Each measured time period is demarcated by calls to
6 *  benchmark_timer_initialize() and benchmark_timer_read().  benchmark_timer_read() usually returns
7 *  the number of microseconds since benchmark_timer_initialize() exitted.
8 *
9 *  NOTE: It is important that the timer start/stop overhead be
10 *        determined when porting or modifying this code.
11 *
12 *  Authors: Ralf Corsepius (corsepiu@faw.uni-ulm.de) and
13 *           Bernd Becker (becker@faw.uni-ulm.de)
14 *
15 *  COPYRIGHT (c) 1997-1998, FAW Ulm, Germany
16 *
17 *  This program is distributed in the hope that it will be useful,
18 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
19 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
20 *
21 *  COPYRIGHT (c) 1998.
22 *  On-Line Applications Research Corporation (OAR).
23 *
24 *  The license and distribution terms for this file may be
25 *  found in the file LICENSE in this distribution or at
26 *  http://www.rtems.com/license/LICENSE.
27 *
28 *  $Id$
29 */
30
31#include <rtems.h>
32
33#include <rtems/score/sh_io.h>
34#include <rtems/score/ispsh7032.h>
35#include <rtems/score/iosh7032.h>
36
37extern uint32_t bsp_clicks_per_second;
38
39#define I_CLK_PHI_1     0
40#define I_CLK_PHI_2     1
41#define I_CLK_PHI_4     2
42#define I_CLK_PHI_8     3
43
44/*
45 * Set I_CLK_PHI to one of the I_CLK_PHI_X values from above to choose
46 * a PHI/X clock rate.
47 */
48
49#define I_CLK_PHI       I_CLK_PHI_4
50#define CLOCK_SCALE     (1<<I_CLK_PHI)
51
52#define ITU1_STARTMASK  0xfd
53#define ITU1_SYNCMASK   0xfd
54#define ITU1_MODEMASK   0xfd
55#define ITU1_TCRMASK    (0x00 | I_CLK_PHI)
56#define ITU1_TIORMASK   0x88
57#define ITU1_STAT_MASK  0xf8
58#define ITU1_TIERMASK   0xfc
59#define IPRC_ITU1_MASK  0xfff0
60
61#ifndef ITU1_PRIO
62#define ITU1_PRIO 15
63#endif
64
65#define ITU1_VECTOR OVI1_ISP_V
66
67extern rtems_isr timerisr(void);
68
69static uint32_t   Timer_interrupts;
70
71bool benchmark_timer_find_average_overhead;
72
73static uint32_t   Timer_HZ ;
74
75void benchmark_timer_initialize( void )
76{
77  uint8_t                temp8;
78  uint16_t               temp16;
79  rtems_interrupt_level  level;
80  rtems_isr             *ignored;
81
82  Timer_HZ = bsp_clicks_per_second / CLOCK_SCALE ;
83
84  /*
85   *  Timer has never overflowed.  This may not be necessary on some
86   *  implemenations of timer but ....
87   */
88
89  Timer_interrupts /* .i */ = 0;
90  rtems_interrupt_disable( level );
91
92  /*
93   *  Somehow start the timer
94   */
95  /* stop Timer 1  */
96  temp8 = read8(ITU_TSTR) & ITU1_STARTMASK;
97  write8( temp8, ITU_TSTR );
98
99  /* initialize counter 1 */
100  write16( 0, ITU_TCNT1 );
101
102  /* Timer 1 is independent of other timers */
103  temp8 = read8(ITU_TSNC) & ITU1_SYNCMASK;
104  write8( temp8, ITU_TSNC );
105
106  /* Timer 1, normal mode */
107  temp8 = read8(ITU_TMDR) & ITU1_MODEMASK;
108  write8( temp8, ITU_TMDR );
109
110  /* Use a Phi/X counter */
111  write8( ITU1_TCRMASK, ITU_TCR1 );
112
113  /* gra and grb are not used */
114  write8( ITU1_TIORMASK, ITU_TIOR1 );
115
116  /* reset all status flags */
117  temp8 = read8(ITU_TSR1) & ITU1_STAT_MASK;
118  write8( temp8, ITU_TSR1 );
119
120  /* enable overflow interrupt */
121  write8( ITU1_TIERMASK, ITU_TIER1 );
122
123  /* set interrupt priority */
124  temp16 = read16(INTC_IPRC) & IPRC_ITU1_MASK;
125  temp16 |= ITU1_PRIO;
126  write16( temp16, INTC_IPRC );
127
128  /* initialize ISR */
129  _CPU_ISR_install_raw_handler( ITU1_VECTOR, timerisr, &ignored );
130  rtems_interrupt_enable( level );
131
132  /* start timer 1 */
133  temp8 = read8(ITU_TSTR) | ~ITU1_STARTMASK;
134  write8( temp8, ITU_TSTR );
135}
136
137/*
138 *  The following controls the behavior of benchmark_timer_read().
139 *
140 *  AVG_OVERHEAD is the overhead for starting and stopping the timer.  It
141 *  is usually deducted from the number returned.
142 *
143 *  LEAST_VALID is the lowest number this routine should trust.  Numbers
144 *  below this are "noise" and zero is returned.
145 */
146
147#define AVG_OVERHEAD      1  /* It typically takes X.X microseconds */
148                             /* (Y countdowns) to start/stop the timer. */
149                             /* This value is in microseconds. */
150#define LEAST_VALID       0 /* 20 */ /* Don't trust a clicks value lower than this */
151
152int benchmark_timer_read( void )
153{
154  uint32_t   cclicks;
155  uint32_t   total ;
156  /*
157   *  Read the timer and see how many clicks it has been since we started.
158   */
159
160
161  cclicks = read16( ITU_TCNT1 );    /* XXX: read some HW here */
162
163  /*
164   *  Total is calculated by taking into account the number of timer overflow
165   *  interrupts since the timer was initialized and clicks since the last
166   *  interrupts.
167   */
168
169  total = cclicks + Timer_interrupts * 65536;
170
171  if ( benchmark_timer_find_average_overhead )
172    return total / CLOCK_SCALE;          /* in XXX microsecond units */
173  else
174  {
175    if ( total < LEAST_VALID )
176      return 0;            /* below timer resolution */
177  /*
178   *  Somehow convert total into microseconds
179   */
180    return (total / CLOCK_SCALE - AVG_OVERHEAD);
181  }
182}
183
184void benchmark_timer_disable_subtracting_average_overhead(bool find_flag)
185{
186  benchmark_timer_find_average_overhead = find_flag;
187}
188
189/* Timer 1 is used */
190
191#pragma interrupt
192void timerisr( void )
193{
194  uint8_t   temp8;
195
196  /* reset the flags of the status register */
197  temp8 = read8(ITU_TSR1) & ITU1_STAT_MASK;
198  write8( temp8, ITU_TSR1 );
199
200  Timer_interrupts += 1;
201}
Note: See TracBrowser for help on using the repository browser.