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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [lib/] [libcpu/] [sh/] [sh7045/] [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 704X
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:39 chris Exp $
30
 */
31
 
32
#include <rtems.h>
33
 
34
#include <rtems/score/sh_io.h>
35
#include <rtems/score/iosh7045.h>
36
 
37
/*
38
 *  We use a Phi/4 timer
39
 */
40
#define SCALE (Timer_MHZ/4)
41
 
42
#define MTU1_STARTMASK  0xfd
43
#define MTU1_SYNCMASK   0xfd
44
#define MTU1_MODEMASK   0xc0
45
#define MTU1_TCRMASK    0x01
46
#define MTU1_TIORMASK   0x88
47
#define MTU1_STAT_MASK  0xf8
48
#define MTU1_TIERMASK   0xfc
49
#define IPRC_MTU1_MASK  0xfff0
50
 
51
#ifndef MTU1_PRIO
52
#define MTU1_PRIO 15
53
#endif
54
 
55
#define MTU1_VECTOR 86
56
 
57
rtems_isr timerisr();
58
 
59
static rtems_unsigned32 Timer_interrupts;
60
 
61
rtems_boolean Timer_driver_Find_average_overhead;
62
 
63
static rtems_unsigned32 Timer_MHZ ;
64
 
65
void Timer_initialize( void )
66
{
67
  rtems_unsigned8  temp8;
68
  rtems_unsigned16 temp16;
69
  rtems_unsigned32 level;
70
  rtems_isr        *ignored;
71
 
72
  Timer_MHZ = rtems_cpu_configuration_get_clicks_per_second() / 1000000 ;
73
 
74
  /*
75
   *  Timer has never overflowed.  This may not be necessary on some
76
   *  implemenations of timer but ....
77
   */
78
 
79
  Timer_interrupts /* .i */ = 0;
80
  _CPU_ISR_Disable( level);
81
 
82
  /*
83
   *  Somehow start the timer
84
   */
85
  /* stop Timer 1  */
86
  temp8 = read8( MTU_TSTR) & MTU1_STARTMASK;
87
  write8( temp8, MTU_TSTR);
88
 
89
  /* initialize counter 1 */
90
  write16( 0, MTU_TCNT1);
91
 
92
  /* Timer 1 is independent of other timers */
93
  temp8 = read8( MTU_TSYR) & MTU1_SYNCMASK;
94
  write8( temp8, MTU_TSYR);
95
 
96
  /* Timer 1, normal mode */
97
  temp8 = read8( MTU_TMDR1) & MTU1_MODEMASK;
98
  write8( temp8, MTU_TMDR1);
99
 
100
  /* x0000000
101
   * |||||+++--- Internal Clock
102
   * |||++------ Count on rising edge
103
   * |++-------- disable TCNT clear
104
   * +---------- don`t care
105
   */
106
  write8( MTU1_TCRMASK, MTU_TCR1);
107
 
108
  /* gra and grb are not used */
109
  write8( MTU1_TIORMASK, MTU_TIOR1);
110
 
111
  /* reset all status flags */
112
  temp8 = read8( MTU_TSR1) & MTU1_STAT_MASK;
113
  write8( temp8, MTU_TSR1);
114
 
115
  /* enable overflow interrupt */
116
  write8( MTU1_TIERMASK, MTU_TIER1);
117
 
118
  /* set interrupt priority */
119
  temp16 = read16( INTC_IPRC) & IPRC_MTU1_MASK;
120
  temp16 |= MTU1_PRIO;
121
  write16( temp16, INTC_IPRC);
122
 
123
  /* initialize ISR */
124
  _CPU_ISR_install_raw_handler( MTU1_VECTOR, timerisr, &ignored );
125
  _CPU_ISR_Enable( level);
126
 
127
  /* start timer 1 */
128
  temp8 = read8( MTU_TSTR) | ~MTU1_STARTMASK;
129
  write8( temp8, MTU_TSTR);
130
}
131
 
132
/*
133
 *  The following controls the behavior of Read_timer().
134
 *
135
 *  AVG_OVERHEAD is the overhead for starting and stopping the timer.  It
136
 *  is usually deducted from the number returned.
137
 *
138
 *  LEAST_VALID is the lowest number this routine should trust.  Numbers
139
 *  below this are "noise" and zero is returned.
140
 */
141
 
142
#define AVG_OVERHEAD      1  /* It typically takes X.X microseconds */
143
                             /* (Y countdowns) to start/stop the timer. */
144
                             /* This value is in microseconds. */
145
#define LEAST_VALID       0 /* 20 */ /* Don't trust a clicks value lower than this */
146
 
147
int Read_timer( void )
148
{
149
  rtems_unsigned32 clicks;
150
  rtems_unsigned32 total ;
151
  /*
152
   *  Read the timer and see how many clicks it has been since we started.
153
   */
154
 
155
 
156
  clicks = read16( MTU_TCNT1);   /* XXX: read some HW here */
157
 
158
  /*
159
   *  Total is calculated by taking into account the number of timer overflow
160
   *  interrupts since the timer was initialized and clicks since the last
161
   *  interrupts.
162
   */
163
 
164
  total = clicks + Timer_interrupts * 65536 ;
165
 
166
  if ( Timer_driver_Find_average_overhead )
167
    return total / SCALE;          /* in XXX microsecond units */
168
  else
169
  {
170
    if ( total < LEAST_VALID )
171
      return 0;            /* below timer resolution */
172
  /*
173
   *  Somehow convert total into microseconds
174
   */
175
    return (total / SCALE - AVG_OVERHEAD) ;
176
  }
177
}
178
 
179
/*
180
 *  Empty function call used in loops to measure basic cost of looping
181
 *  in Timing Test Suite.
182
 */
183
 
184
rtems_status_code Empty_function( void )
185
{
186
  return RTEMS_SUCCESSFUL;
187
}
188
 
189
void Set_find_average_overhead(
190
  rtems_boolean find_flag
191
)
192
{
193
  Timer_driver_Find_average_overhead = find_flag;
194
}
195
 
196
/* Timer 1 is used */
197
 
198
#pragma interrupt
199
void timerisr( void )
200
{
201
  unsigned8 temp8;
202
 
203
  /* reset the flags of the status register */
204
  temp8 = read8( MTU_TSR1) & MTU1_STAT_MASK;
205
  write8( temp8, MTU_TSR1);
206
 
207
  Timer_interrupts += 1;
208
}

powered by: WebSVN 2.1.0

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