source: rtems/c/src/lib/libcpu/a29k/clock/ckinit.c @ 948a069

Last change on this file since 948a069 was 948a069, checked in by Joel Sherrill <joel.sherrill@…>, on 09/04/03 at 17:32:05

2003-09-04 Joel Sherrill <joel@…>

  • clock/ckinit.c, timer/timer.c, timer/timerisr.c: Removed incorrect statement about copyright assignment.
  • Property mode set to 100644
File size: 4.1 KB
Line 
1/*  ckinit.c
2 *
3 *  This file provides a template for the clock device driver initialization.
4 *
5 *  COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
6 *  On-Line Applications Research Corporation (OAR).
7 *
8 *  $Id$
9 */
10
11#ifndef lint
12static char _sccsid[] = "@(#)ckinit.c 03/15/96     1.1\n";
13#endif
14
15#include <stdlib.h>
16
17#include <rtems.h>
18#include <rtems/libio.h>
19
20#include "clock.h"
21
22extern int CPU_CLOCK_RATE_MHZ; /* provided in bsp */
23
24#define CLOCKS_PER_MICROSECOND ( CPU_CLOCK_RATE_MHZ ) /* equivalent to CPU clock speed in MHz */
25
26void Clock_exit( void );
27rtems_isr Clock_isr( rtems_vector_number vector );
28
29
30/*
31 *  The interrupt vector number associated with the clock tick device
32 *  driver.
33 */
34
35#define CLOCK_VECTOR         14
36
37/*
38 *  Clock_driver_ticks is a monotonically increasing counter of the
39 *  number of clock ticks since the driver was initialized.
40 */
41
42volatile rtems_unsigned32 Clock_driver_ticks;
43
44
45/*
46 * These are set by clock driver during its init
47 */
48 
49rtems_device_major_number rtems_clock_major = ~0;
50rtems_device_minor_number rtems_clock_minor;
51
52/*
53 *  The previous ISR on this clock tick interrupt vector.
54 */
55
56rtems_isr_entry  Old_ticker;
57
58void Clock_exit( void );
59
60static unsigned32 a29k_timer_rate = 0;
61
62/*
63 *  Isr Handler
64 */
65
66rtems_isr Clock_isr(
67  rtems_vector_number vector
68)
69{
70/*
71 * bump the number of clock driver ticks since initialization
72 *
73 * determine if it is time to announce the passing of tick as configured
74 * to RTEMS through the rtems_clock_tick directive
75 *
76 * perform any timer dependent tasks
77 */
78
79  a29k_clear_timer();
80
81  Clock_driver_ticks += 1;
82
83  rtems_clock_tick();
84}
85
86/* User callback shell (set from Clock_Control) */
87static void (*user_callback)(void);
88
89rtems_isr User_Clock_isr(
90  rtems_vector_number vector
91)
92{
93   /* refresh the internal CPU timer */
94  a29k_clear_timer();
95
96   if (user_callback)
97      user_callback();
98}
99
100/*
101 *  Install_clock
102 *
103 *  Install a clock tick handler and reprograms the chip.  This
104 *  is used to initially establish the clock tick.
105 */
106
107void Install_clock(
108  rtems_isr_entry clock_isr
109)
110{
111  /*
112   *  Initialize the clock tick device driver variables
113   */
114
115  Clock_driver_ticks = 0;
116
117  /*
118   *  If ticks_per_timeslice is configured as non-zero, then the user
119   *  wants a clock tick.
120   */
121
122  if ( rtems_configuration_get_ticks_per_timeslice() ) {
123    Old_ticker = (rtems_isr_entry) set_vector( clock_isr, CLOCK_VECTOR, 1 );
124    /*
125     *  Hardware specific initialize goes here
126     */
127
128    a29k_timer_rate = rtems_configuration_get_microseconds_per_tick() * CLOCKS_PER_MICROSECOND;
129    a29k_init_timer( a29k_timer_rate );
130  }
131
132  /*
133   *  Schedule the clock cleanup routine to execute if the application exits.
134   */
135
136  atexit( Clock_exit );
137}
138
139/*
140 *  Clean up before the application exits
141 */
142
143void Clock_exit( void )
144{
145  if ( rtems_configuration_get_ticks_per_timeslice() ) {
146
147    /* a29k: turn off the timer interrupts */
148    a29k_disable_timer();
149
150  }
151}
152
153/*
154 *  Clock_initialize
155 *
156 *  Device driver entry point for clock tick driver initialization.
157 */
158
159rtems_device_driver Clock_initialize(
160  rtems_device_major_number major,
161  rtems_device_minor_number minor,
162  void *pargp
163)
164{
165  Install_clock( Clock_isr );
166 
167  /*
168   * make major/minor avail to others such as shared memory driver
169   */
170 
171  rtems_clock_major = major;
172  rtems_clock_minor = minor;
173 
174  return RTEMS_SUCCESSFUL;
175}
176
177rtems_device_driver Clock_control(
178  rtems_device_major_number major,
179  rtems_device_minor_number minor,
180  void *pargp
181)
182{
183    rtems_unsigned32 isrlevel;
184    rtems_libio_ioctl_args_t *args = pargp;
185 
186    if (args == 0)
187        goto done;
188 
189    /*
190     * This is hokey, but until we get a defined interface
191     * to do this, it will just be this simple...
192     */
193 
194    if (args->command == rtems_build_name('I', 'S', 'R', ' '))
195    {
196        Clock_isr(CLOCK_VECTOR);
197    }
198    else if (args->command == rtems_build_name('N', 'E', 'W', ' '))
199    {
200      rtems_interrupt_disable( isrlevel );
201      user_callback = (void (*)(void))args->buffer;
202      (void) set_vector( User_Clock_isr, CLOCK_VECTOR, 1 );
203      rtems_interrupt_enable( isrlevel );
204    }
205 
206done:
207    return RTEMS_SUCCESSFUL;
208}
Note: See TracBrowser for help on using the repository browser.