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

Last change on this file since c8f3e82 was 650a5397, checked in by Joel Sherrill <joel.sherrill@…>, on Oct 12, 2001 at 9:01:15 PM

2001-10-12 Joel Sherrill <joel@…>

  • clock/ckinit.c, delay/delay.c, include/iosh7032.h, include/ispsh7032.h, include/sci.h, include/sh7_pfc.h, include/sh7_sci.h, sci/sci.c, score/cpu_asm.c, score/ispsh7032.c, timer/timer.c: Fixed typo.
  • 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 *  Timer_initialize() and Read_timer().  Read_timer() usually returns
7 *  the number of microseconds since 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.OARcorp.com/rtems/license.html.
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
37#define I_CLK_PHI_1     0
38#define I_CLK_PHI_2     1
39#define I_CLK_PHI_4     2
40#define I_CLK_PHI_8     3
41
42/*
43 * Set I_CLK_PHI to one of the I_CLK_PHI_X values from above to choose
44 * a PHI/X clock rate. 
45 */
46   
47#define I_CLK_PHI       I_CLK_PHI_4
48#define CLOCK_SCALE     (1<<I_CLK_PHI)
49
50#define ITU1_STARTMASK  0xfd
51#define ITU1_SYNCMASK   0xfd
52#define ITU1_MODEMASK   0xfd
53#define ITU1_TCRMASK    (0x00 | I_CLK_PHI)
54#define ITU1_TIORMASK   0x88
55#define ITU1_STAT_MASK  0xf8
56#define ITU1_TIERMASK   0xfc
57#define IPRC_ITU1_MASK  0xfff0
58
59#ifndef ITU1_PRIO
60#define ITU1_PRIO 15
61#endif
62
63#define ITU1_VECTOR OVI1_ISP_V
64
65rtems_isr timerisr();
66
67static rtems_unsigned32 Timer_interrupts;
68
69rtems_boolean Timer_driver_Find_average_overhead;
70
71static rtems_unsigned32 Timer_HZ ;
72
73void Timer_initialize( void )
74{
75  rtems_unsigned8  temp8;
76  rtems_unsigned16 temp16;
77  rtems_unsigned32 level;
78  rtems_isr        *ignored;
79
80  Timer_HZ = rtems_cpu_configuration_get_clicks_per_second() / CLOCK_SCALE ;
81
82  /*
83   *  Timer has never overflowed.  This may not be necessary on some
84   *  implemenations of timer but ....
85   */
86
87  Timer_interrupts /* .i */ = 0;
88  _CPU_ISR_Disable( level);
89
90  /*
91   *  Somehow start the timer
92   */
93  /* stop Timer 1  */
94  temp8 = read8( ITU_TSTR) & ITU1_STARTMASK;
95  write8( temp8, ITU_TSTR);
96
97  /* initialize counter 1 */
98  write16( 0, ITU_TCNT1);
99
100  /* Timer 1 is independent of other timers */
101  temp8 = read8( ITU_TSNC) & ITU1_SYNCMASK;
102  write8( temp8, ITU_TSNC);
103
104  /* Timer 1, normal mode */
105  temp8 = read8( ITU_TMDR) & ITU1_MODEMASK;
106  write8( temp8, ITU_TMDR);
107
108  /* Use a Phi/X counter */
109  write8( ITU1_TCRMASK, ITU_TCR1);
110
111  /* gra and grb are not used */
112  write8( ITU1_TIORMASK, ITU_TIOR1);
113
114  /* reset all status flags */
115  temp8 = read8( ITU_TSR1) & ITU1_STAT_MASK;
116  write8( temp8, ITU_TSR1);
117
118  /* enable overflow interrupt */
119  write8( ITU1_TIERMASK, ITU_TIER1);
120
121  /* set interrupt priority */
122  temp16 = read16( INTC_IPRC) & IPRC_ITU1_MASK;
123  temp16 |= ITU1_PRIO;
124  write16( temp16, INTC_IPRC);
125
126  /* initialize ISR */
127  _CPU_ISR_install_raw_handler( ITU1_VECTOR, timerisr, &ignored );
128  _CPU_ISR_Enable( level);
129
130  /* start timer 1 */
131  temp8 = read8( ITU_TSTR) | ~ITU1_STARTMASK;
132  write8( temp8, ITU_TSTR);
133}
134
135/*
136 *  The following controls the behavior of Read_timer().
137 *
138 *  AVG_OVERHEAD is the overhead for starting and stopping the timer.  It
139 *  is usually deducted from the number returned.
140 *
141 *  LEAST_VALID is the lowest number this routine should trust.  Numbers
142 *  below this are "noise" and zero is returned.
143 */
144
145#define AVG_OVERHEAD      1  /* It typically takes X.X microseconds */
146                             /* (Y countdowns) to start/stop the timer. */
147                             /* This value is in microseconds. */
148#define LEAST_VALID       0 /* 20 */ /* Don't trust a clicks value lower than this */
149
150int Read_timer( void )
151{
152  rtems_unsigned32 cclicks;
153  rtems_unsigned32 total ;
154  /*
155   *  Read the timer and see how many clicks it has been since we started.
156   */
157 
158
159  cclicks = read16( ITU_TCNT1);   /* XXX: read some HW here */
160 
161  /*
162   *  Total is calculated by taking into account the number of timer overflow
163   *  interrupts since the timer was initialized and clicks since the last
164   *  interrupts.
165   */
166
167  total = cclicks + Timer_interrupts * 65536 ;
168
169  if ( Timer_driver_Find_average_overhead )
170    return total / CLOCK_SCALE;          /* in XXX microsecond units */
171  else 
172  {
173    if ( total < LEAST_VALID )
174      return 0;            /* below timer resolution */
175  /*
176   *  Somehow convert total into microseconds
177   */
178    return (total / CLOCK_SCALE - AVG_OVERHEAD) ;
179  }
180}
181
182/*
183 *  Empty function call used in loops to measure basic cost of looping
184 *  in Timing Test Suite.
185 */
186
187rtems_status_code Empty_function( void )
188{
189  return RTEMS_SUCCESSFUL;
190}
191
192void Set_find_average_overhead(
193  rtems_boolean find_flag
194)
195{
196  Timer_driver_Find_average_overhead = find_flag;
197}
198
199/* Timer 1 is used */
200
201#pragma interrupt
202void timerisr( void )
203{
204  unsigned8 temp8;
205
206  /* reset the flags of the status register */
207  temp8 = read8( ITU_TSR1) & ITU1_STAT_MASK;
208  write8( temp8, ITU_TSR1);
209
210  Timer_interrupts += 1;
211}
Note: See TracBrowser for help on using the repository browser.