source: rtems/c/src/lib/libcpu/sh/sh7032/clock/ckinit.c @ 5503d75

4.104.114.84.95
Last change on this file since 5503d75 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: 6.7 KB
Line 
1/*
2 *  This file contains the clock driver the Hitachi SH 703X
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 *  The license and distribution terms for this file may be
19 *  found in the file LICENSE in this distribution or at
20 *  http://www.OARcorp.com/rtems/license.html.
21 *
22 *  $Id$
23 */
24
25#include <rtems.h>
26
27#include <stdlib.h>
28
29#include <rtems/libio.h>
30#include <rtems/score/sh_io.h>
31#include <rtems/score/sh.h>
32#include <rtems/score/cpu_isps.h>
33#include <rtems/score/iosh7030.h>
34
35#define _ITU_COUNTER0_MICROSECOND (MHZ/4)
36
37#ifndef CLOCKPRIO
38#define CLOCKPRIO 10
39#endif
40
41#define ITU0_STARTMASK  0xfe
42#define ITU0_SYNCMASK   0xfe
43#define ITU0_MODEMASK   0xfe
44#define ITU0_TCRMASK    0x22
45#define ITU_STAT_MASK   0xf8
46#define ITU0_IRQMASK    0xfe
47#define ITU0_TIERMASK   0x01
48#define IPRC_ITU0_MASK  0xff0f
49#define ITU0_TIORVAL    0x08
50
51/*
52 *  The interrupt vector number associated with the clock tick device
53 *  driver.
54 */
55
56#define CLOCK_VECTOR IMIA0_ISP_V
57
58/*
59 *  Clock_driver_ticks is a monotonically increasing counter of the
60 *  number of clock ticks since the driver was initialized.
61 */
62
63volatile rtems_unsigned32 Clock_driver_ticks;
64
65static void Clock_exit( void );
66static rtems_isr Clock_isr( rtems_vector_number vector );
67
68/*
69 *  Clock_isrs is the number of clock ISRs until the next invocation of
70 *  the RTEMS clock tick routine.  The clock tick device driver
71 *  gets an interrupt once a millisecond and counts down until the
72 *  length of time between the user configured microseconds per tick
73 *  has passed.
74 */
75
76rtems_unsigned32 Clock_isrs;              /* ISRs until next tick */
77static rtems_unsigned32 Clock_isrs_const;        /* only calculated once */
78
79/*
80 * These are set by clock driver during its init
81 */
82 
83rtems_device_major_number rtems_clock_major = ~0;
84rtems_device_minor_number rtems_clock_minor;
85
86/*
87 *  The previous ISR on this clock tick interrupt vector.
88 */
89
90rtems_isr_entry  Old_ticker;
91
92/*
93 *  Isr Handler
94 */
95
96rtems_isr Clock_isr(
97  rtems_vector_number vector
98)
99{
100  /*
101   * bump the number of clock driver ticks since initialization
102   *
103
104   * determine if it is time to announce the passing of tick as configured
105   * to RTEMS through the rtems_clock_tick directive
106   *
107   * perform any timer dependent tasks
108   */
109  unsigned8 temp;
110
111  /* reset the flags of the status register */
112  temp = read8( ITU_TSR0) & ITU_STAT_MASK;
113  write8( temp, ITU_TSR0);
114
115  Clock_driver_ticks++ ;
116
117  if( Clock_isrs == 1)
118    {
119      rtems_clock_tick();
120      Clock_isrs = Clock_isrs_const;
121    }
122  else
123    {
124      Clock_isrs-- ;
125    }
126}
127
128/*
129 *  Install_clock
130 *
131 *  Install a clock tick handler and reprograms the chip.  This
132 *  is used to initially establish the clock tick.
133 */
134
135void Install_clock(
136  rtems_isr_entry clock_isr
137)
138{
139  unsigned8 temp8 = 0;
140 
141  /*
142   *  Initialize the clock tick device driver variables
143   */
144
145  Clock_driver_ticks = 0;
146  Clock_isrs_const = rtems_configuration_get_microseconds_per_tick() / 10000;
147  Clock_isrs = Clock_isrs_const;
148
149  /*
150   *  If ticks_per_timeslice is configured as non-zero, then the user
151   *  wants a clock tick.
152   */
153
154  if ( rtems_configuration_get_ticks_per_timeslice() ) {
155    rtems_interrupt_catch( Clock_isr, CLOCK_VECTOR, &Old_ticker );
156    /*
157     *  Hardware specific initialize goes here
158     */
159   
160    /* stop Timer 0 */
161    temp8 = read8( ITU_TSTR) & ITU0_STARTMASK;
162    write8( temp8, ITU_TSTR);
163
164    /* set initial counter value to 0 */
165    write16( 0, ITU_TCNT0);
166
167    /* Timer 0 runs independent */
168    temp8 = read8( ITU_TSNC) & ITU0_SYNCMASK;
169    write8( temp8, ITU_TSNC);
170
171    /* Timer 0 normal mode */
172    temp8 = read8( ITU_TMDR) & ITU0_MODEMASK;
173    write8( temp8, ITU_TMDR);
174
175    /* TCNT is cleared by GRA ; internal clock /4 */
176    write8( ITU0_TCRMASK , ITU_TCR0);
177
178    /* use GRA without I/O - pins  */
179    write8( ITU0_TIORVAL, ITU_TIOR0);
180   
181    /* reset flags of the status register */
182    temp8 = read8( ITU_TSR0) & ITU_STAT_MASK;
183    write8( temp8, ITU_TSR0);
184
185    /* Irq if is equal GRA */
186    temp8 = read8( ITU_TIER0) | ITU0_TIERMASK;
187    write8( temp8, ITU_TIER0);
188
189    /* set interrupt priority */
190    if( sh_set_irq_priority( CLOCK_VECTOR, CLOCKPRIO ) != RTEMS_SUCCESSFUL)
191      rtems_fatal_error_occurred( RTEMS_NOT_CONFIGURED);
192
193    /* set counter limits */
194    write16( _ITU_COUNTER0_MICROSECOND * rtems_configuration_get_microseconds_per_tick(),
195             ITU_GRA0);
196   
197    /* start counter */
198    temp8 = read8( ITU_TSTR) |~ITU0_STARTMASK;
199    write8( temp8, ITU_TSTR);
200   
201  }
202
203  /*
204   *  Schedule the clock cleanup routine to execute if the application exits.
205   */
206
207  atexit( Clock_exit );
208}
209
210/*
211 *  Clean up before the application exits
212 */
213
214void Clock_exit( void )
215{
216  unsigned8 temp8 = 0;
217  if ( rtems_configuration_get_ticks_per_timeslice() ) {
218
219    /* turn off the timer interrupts */
220    /* set interrupt priority to 0 */
221    if( sh_set_irq_priority( CLOCK_VECTOR, 0 ) != RTEMS_SUCCESSFUL)
222      rtems_fatal_error_occurred( RTEMS_UNSATISFIED);
223
224/*
225 *   temp16 = read16( ITU_TIER0) & IPRC_ITU0_IRQMASK;
226 *   write16( temp16, ITU_TIER0);
227 */
228
229    /* stop counter */
230    temp8 = read8( ITU_TSTR) & ITU0_STARTMASK;
231    write8( temp8, ITU_TSTR);
232
233    /* old vector shall not be installed */
234  }
235}
236
237/*
238 *  Clock_initialize
239 *
240 *  Device driver entry point for clock tick driver initialization.
241 */
242
243rtems_device_driver Clock_initialize(
244  rtems_device_major_number major,
245  rtems_device_minor_number minor,
246  void *pargp
247)
248{
249  Install_clock( Clock_isr );
250 
251  /*
252   * make major/minor avail to others such as shared memory driver
253   */
254 
255  rtems_clock_major = major;
256  rtems_clock_minor = minor;
257 
258  return RTEMS_SUCCESSFUL;
259}
260
261rtems_device_driver Clock_control(
262  rtems_device_major_number major,
263  rtems_device_minor_number minor,
264  void *pargp
265)
266{
267  rtems_unsigned32 isrlevel;
268  rtems_libio_ioctl_args_t *args = pargp;
269 
270  if (args != 0)
271    {
272      /*
273       * This is hokey, but until we get a defined interface
274       * to do this, it will just be this simple...
275       */
276     
277      if (args->command == rtems_build_name('I', 'S', 'R', ' '))
278        {
279          Clock_isr(CLOCK_VECTOR);
280        }
281      else if (args->command == rtems_build_name('N', 'E', 'W', ' '))
282        {
283          rtems_isr_entry       ignored ;
284          rtems_interrupt_disable( isrlevel );
285          rtems_interrupt_catch( args->buffer, CLOCK_VECTOR, &ignored );
286         
287          rtems_interrupt_enable( isrlevel );
288        }
289    }
290  return RTEMS_SUCCESSFUL;
291}
Note: See TracBrowser for help on using the repository browser.