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

4.104.114.84.95
Last change on this file since f8b27df9 was f8b27df9, checked in by Joel Sherrill <joel.sherrill@…>, on 03/20/98 at 17:20:45

New port from Ralf Corsepius <corsepiu@…>.

  • Property mode set to 100644
File size: 6.6 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 <bsp.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 = BSP_Configuration.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 ( BSP_Configuration.ticks_per_timeslice ) {
155    Old_ticker = (rtems_isr_entry) set_vector( Clock_isr, CLOCK_VECTOR, 1 );
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 * BSP_Configuration.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 ( BSP_Configuration.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_interrupt_disable( isrlevel );
284          (void) set_vector( args->buffer, CLOCK_VECTOR, 1 );
285          rtems_interrupt_enable( isrlevel );
286        }
287    }
288  return RTEMS_SUCCESSFUL;
289}
Note: See TracBrowser for help on using the repository browser.