source: rtems/c/src/lib/libcpu/sh/sh7045/clock/ckinit.c @ ac815430

4.104.114.84.95
Last change on this file since ac815430 was 0dd1d44, checked in by Joel Sherrill <joel.sherrill@…>, on 01/11/00 at 17:34:20

Removed old hack of using Configuration Table entry ticks_per_timeslice
being set to 0 to indicate that there should be no Clock Tick. This
was used by the Timing Tests to avoid clock tick overhead perturbing
execution times. Now the Timing Tests simply leave the Clock Tick
Driver out of the Device Driver Table.

  • Property mode set to 100644
File size: 7.0 KB
Line 
1/*
2 *  This file contains the clock driver the Hitachi SH 704X
3 *
4 *  Authors: Ralf Corsepius (corsepiu@faw.uni-ulm.de) and
5 *           Bernd Becker (becker@faw.uni-ulm.de)
6 *
7 *  COPYRIGHT (c) 1997-1998, FAW Ulm, Germany
8 *
9 *  This program is distributed in the hope that it will be useful,
10 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 *
13 *
14 *  COPYRIGHT (c) 1998.
15 *  On-Line Applications Research Corporation (OAR).
16 *  Copyright assigned to U.S. Government, 1994.
17 *
18 *      Modified to reflect registers of sh7045 processor:
19 *      John M. Mills (jmills@tga.com)
20 *      TGA Technologies, Inc.
21 *      100 Pinnacle Way, Suite 140
22 *      Norcross, GA 30071 U.S.A.
23 *      August, 1999
24 *
25 *      This modified file may be copied and distributed in accordance
26 *      the above-referenced license. It is provided for critique and
27 *      developmental purposes without any warranty nor representation
28 *      by the authors or by TGA Technologies.
29 *
30 *  The license and distribution terms for this file may be
31 *  found in the file LICENSE in this distribution or at
32 *  http://www.OARcorp.com/rtems/license.html.
33 *
34 *  $Id$
35 */
36
37#include <rtems.h>
38
39#include <stdlib.h>
40
41#include <rtems/libio.h>
42#include <rtems/score/sh_io.h>
43#include <rtems/score/sh.h>
44#include <rtems/score/ispsh7045.h>
45#include <rtems/score/iosh7045.h>
46
47#define _MTU_COUNTER0_MICROSECOND (Clock_MHZ/4)
48
49#ifndef CLOCKPRIO
50#define CLOCKPRIO 10
51#endif
52
53#define MTU0_STARTMASK  0xfe
54#define MTU0_SYNCMASK   0xfe
55#define MTU0_MODEMASK   0xc0
56#define MTU0_TCRMASK    0x01 /* bit 7 also used, vs 703x */
57#define MTU0_STAT_MASK  0xc0
58#define MTU0_IRQMASK    0xfe
59#define MTU0_TIERMASK   0x01
60#define IPRC_MTU0_MASK  0xff0f
61#define MTU0_TIORVAL    0x08
62
63/*
64 *  The interrupt vector number associated with the clock tick device
65 *  driver.
66 */
67
68#define CLOCK_VECTOR MTUA0_ISP_V
69
70/*
71 *  Clock_driver_ticks is a monotonically increasing counter of the
72 *  number of clock ticks since the driver was initialized.
73 */
74
75volatile rtems_unsigned32 Clock_driver_ticks;
76
77static void Clock_exit( void );
78static rtems_isr Clock_isr( rtems_vector_number vector );
79static rtems_unsigned32 Clock_MHZ ;
80
81/*
82 *  Clock_isrs is the number of clock ISRs until the next invocation of
83 *  the RTEMS clock tick routine.  The clock tick device driver
84 *  gets an interrupt once a millisecond and counts down until the
85 *  length of time between the user configured microseconds per tick
86 *  has passed.
87 */
88
89rtems_unsigned32 Clock_isrs;              /* ISRs until next tick */
90static rtems_unsigned32 Clock_isrs_const;        /* only calculated once */
91
92/*
93 * These are set by clock driver during its init
94 */
95 
96rtems_device_major_number rtems_clock_major = ~0;
97rtems_device_minor_number rtems_clock_minor;
98
99/*
100 *  The previous ISR on this clock tick interrupt vector.
101 */
102
103rtems_isr_entry  Old_ticker;
104
105/*
106 *  Isr Handler
107 */
108
109rtems_isr Clock_isr(
110  rtems_vector_number vector
111)
112{
113  /*
114   * bump the number of clock driver ticks since initialization
115   *
116
117   * determine if it is time to announce the passing of tick as configured
118   * to RTEMS through the rtems_clock_tick directive
119   *
120   * perform any timer dependent tasks
121   */
122  unsigned8 temp;
123
124  /* reset the flags of the status register */
125  temp = read8( MTU_TSR0) & MTU0_STAT_MASK;
126  write8( temp, MTU_TSR0);
127
128  Clock_driver_ticks++ ;
129
130  if( Clock_isrs == 1)
131    {
132      rtems_clock_tick();
133      Clock_isrs = Clock_isrs_const;
134    }
135  else
136    {
137      Clock_isrs-- ;
138    }
139}
140
141/*
142 *  Install_clock
143 *
144 *  Install a clock tick handler and reprograms the chip.  This
145 *  is used to initially establish the clock tick.
146 */
147
148void Install_clock(
149  rtems_isr_entry clock_isr
150)
151{
152  unsigned8 temp8 = 0;
153 
154  /*
155   *  Initialize the clock tick device driver variables
156   */
157
158  Clock_driver_ticks = 0;
159  Clock_isrs_const = rtems_configuration_get_microseconds_per_tick() / 10000;
160  Clock_isrs = Clock_isrs_const;
161
162  Clock_MHZ = rtems_cpu_configuration_get_clicks_per_second() / 1000000 ;
163
164  rtems_interrupt_catch( Clock_isr, CLOCK_VECTOR, &Old_ticker );
165
166  /*
167   *  Hardware specific initialize goes here
168   */
169   
170  /* stop Timer 0 */
171  temp8 = read8( MTU_TSTR) & MTU0_STARTMASK;
172  write8( temp8, MTU_TSTR);
173
174  /* set initial counter value to 0 */
175  write16( 0, MTU_TCNT0);
176
177  /* Timer 0 runs independent */
178  temp8 = read8( MTU_TSYR) & MTU0_SYNCMASK;
179  write8( temp8, MTU_TSYR);
180
181  /* Timer 0 normal mode */
182  temp8 = read8( MTU_TMDR0) & MTU0_MODEMASK;
183  write8( temp8, MTU_TMDR0);
184
185  /* TCNT is cleared by GRA ; internal clock /4 */
186  write8( MTU0_TCRMASK , MTU_TCR0);
187
188  /* use GRA without I/O - pins  */
189  write8( MTU0_TIORVAL, MTU_TIORL0);
190   
191  /* reset flags of the status register */
192  temp8 = read8( MTU_TSR0) & MTU0_STAT_MASK;
193  write8( temp8, MTU_TSR0);
194
195  /* Irq if is equal GRA */
196  temp8 = read8( MTU_TIER0) | MTU0_TIERMASK;
197  write8( temp8, MTU_TIER0);
198
199  /* set interrupt priority */
200  if( sh_set_irq_priority( CLOCK_VECTOR, CLOCKPRIO ) != RTEMS_SUCCESSFUL)
201    rtems_fatal_error_occurred( RTEMS_NOT_CONFIGURED);
202
203  /* set counter limits */
204  write16( _MTU_COUNTER0_MICROSECOND *
205    rtems_configuration_get_microseconds_per_tick(), MTU_GR0A);
206   
207  /* start counter */
208  temp8 = read8( MTU_TSTR) |~MTU0_STARTMASK;
209  write8( temp8, MTU_TSTR);
210
211  /*
212   *  Schedule the clock cleanup routine to execute if the application exits.
213   */
214
215  atexit( Clock_exit );
216}
217
218/*
219 *  Clean up before the application exits
220 */
221
222void Clock_exit( void )
223{
224  unsigned8 temp8 = 0;
225
226  /* turn off the timer interrupts */
227  /* set interrupt priority to 0 */
228  if( sh_set_irq_priority( CLOCK_VECTOR, 0 ) != RTEMS_SUCCESSFUL)
229    rtems_fatal_error_occurred( RTEMS_UNSATISFIED);
230
231/*
232 *   temp16 = read16( MTU_TIER0) & IPRC_MTU0_IRQMASK;
233 *   write16( temp16, MTU_TIER0);
234 */
235
236  /* stop counter */
237  temp8 = read8( MTU_TSTR) & MTU0_STARTMASK;
238  write8( temp8, MTU_TSTR);
239
240  /* old vector shall not be installed */
241}
242
243/*
244 *  Clock_initialize
245 *
246 *  Device driver entry point for clock tick driver initialization.
247 */
248
249rtems_device_driver Clock_initialize(
250  rtems_device_major_number major,
251  rtems_device_minor_number minor,
252  void *pargp
253)
254{
255  Install_clock( Clock_isr );
256 
257  /*
258   * make major/minor avail to others such as shared memory driver
259   */
260 
261  rtems_clock_major = major;
262  rtems_clock_minor = minor;
263 
264  return RTEMS_SUCCESSFUL;
265}
266
267rtems_device_driver Clock_control(
268  rtems_device_major_number major,
269  rtems_device_minor_number minor,
270  void *pargp
271)
272{
273  rtems_unsigned32 isrlevel;
274  rtems_libio_ioctl_args_t *args = pargp;
275 
276  if (args != 0)
277    {
278      /*
279       * This is hokey, but until we get a defined interface
280       * to do this, it will just be this simple...
281       */
282     
283      if (args->command == rtems_build_name('I', 'S', 'R', ' '))
284        {
285          Clock_isr(CLOCK_VECTOR);
286        }
287      else if (args->command == rtems_build_name('N', 'E', 'W', ' '))
288        {
289          rtems_isr_entry       ignored ;
290          rtems_interrupt_disable( isrlevel );
291          rtems_interrupt_catch( args->buffer, CLOCK_VECTOR, &ignored );
292         
293          rtems_interrupt_enable( isrlevel );
294        }
295    }
296  return RTEMS_SUCCESSFUL;
297}
Note: See TracBrowser for help on using the repository browser.