source: rtems/c/src/lib/libcpu/sh/sh7045/timer/timer.c @ 0312d81f

4.104.114.84.95
Last change on this file since 0312d81f was 4a238002, checked in by Joel Sherrill <joel.sherrill@…>, on 11/18/99 at 21:22:58

Patch from "John M. Mills" <jmills@…> with subsequent cleanup from
Ralf Corsepius <corsepiu@…> that adds initial Hitachi SH-2
support to RTEMS. Ralf's comments are:

Changes:
------

  1. SH-Port:
  • Many files renamed.
  • CONSOLE_DEVNAME and MHZ defines removed from libcpu.
  • console.c moved to libbsp/sh/shared, build in libbsp/sh/<BSP>/console applying VPATH.
  • CONSOLE_DEVNAME made BSP-specific, replacement is defined in bsp.h
  • MHZ define replaced with HZ (extendent resolution) in custom/*.cfg
  • -DHZ=HZ used in bspstart.c, only
  • Makefile variable HZ used in bsp-dependent directories only.
  1. SH1-Port
  • clock-driver rewritten to provide better resolution for odd CPU frequencies. This driver is only partially tested on hardware, ie. sightly experimental, but I don't expect severe problems with it.
  • Polling SCI-driver added. This driver is experimental and completly untested yet. Therefore it is not yet used for the console (/dev/console is still pointing to /dev/null, cf. gensh1/bsp.h).
  • minor changes to the timer driver
  • SH1 specific delay()/CPU_delay() now is implemented as a function
  1. SH2-Port
  • Merged
  • IMO, the code is still in its infancy. Therefore I have interspersed comments (FIXME) it for items which I think John should look after.
  • sci and console drivers partially rewritten and extended (John, I hope you don't mind).
  • Copyright notices are not yet adapted
  • Property mode set to 100644
File size: 5.1 KB
Line 
1/*
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$
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
57rtems_isr timerisr();
58
59static rtems_unsigned32 Timer_interrupts;
60
61rtems_boolean Timer_driver_Find_average_overhead;
62
63static rtems_unsigned32 Timer_MHZ ;
64
65void 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
147int 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
184rtems_status_code Empty_function( void )
185{
186  return RTEMS_SUCCESSFUL;
187}
188
189void 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
199void 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}
Note: See TracBrowser for help on using the repository browser.