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

4.104.114.84.95
Last change on this file since 08311cc3 was f817b02, checked in by Joel Sherrill <joel.sherrill@…>, on 11/04/99 at 18:05:09

The files in libcpu should not be directly dependent on any BSP. In
particular, using bsp.h, or getting information from the BSP which
should properly be obtained from RTEMS is forbidden. This is
necessary to strengthen the division between the BSP independent
parts of RTEMS and the BSPs themselves. This started after
comments and analysis by Ralf Corsepius <corsepiu@…>.
The changes primarily eliminated the need to include bsp.h and
peeking at BSP_Configuration. The use of Cpu_table in each
BSP needs to be eliminated.

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