OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [lib/] [libcpu/] [sh/] [sh7032/] [timer/] [timer.c] - Blame information for rev 173

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.