source: rtems/c/src/lib/libbsp/c4x/c4xsim/clock/clock.c @ 6128a4a

4.104.114.84.95
Last change on this file since 6128a4a was 6128a4a, checked in by Ralf Corsepius <ralf.corsepius@…>, on 04/21/04 at 10:43:04

Remove stray white spaces.

  • Property mode set to 100644
File size: 4.9 KB
Line 
1/*  ckinit.c
2 *
3 *  This file provides a template for the clock device driver initialization.
4 *
5 *  COPYRIGHT (c) 1989-1999.
6 *  On-Line Applications Research Corporation (OAR).
7 *
8 *  The license and distribution terms for this file may be
9 *  found in the file LICENSE in this distribution or at
10 *  http://www.rtems.com/license/LICENSE.
11 *
12 *  $Id$
13 */
14
15#include <stdlib.h>
16
17#include <rtems.h>
18#include <rtems/libio.h>
19#include <bsp.h>
20#include <rtems/c4x/c4xio.h>
21
22void Clock_exit( void );
23rtems_isr Clock_isr( rtems_vector_number vector );
24
25uint32_t         Clock_counter_register_value;
26
27/*
28 *  The interrupt vector number associated with the clock tick device
29 *  driver.
30 */
31
32#define CLOCK_VECTOR    9
33
34/*
35 *  Clock_driver_ticks is a monotonically increasing counter of the
36 *  number of clock ticks since the driver was initialized.
37 */
38
39volatile uint32_t         Clock_driver_ticks;
40
41/*
42 * These are set by clock driver during its init
43 */
44
45rtems_device_major_number rtems_clock_major = ~0;
46rtems_device_minor_number rtems_clock_minor;
47
48/*
49 *  The previous ISR on this clock tick interrupt vector.
50 */
51
52rtems_isr_entry  Old_ticker;
53
54void Clock_exit( void );
55
56
57/*
58 *  Isr Handler
59 */
60
61#define FAST_IDLE 1
62#if FAST_IDLE
63int Clock_in_fast_idle_mode = 0;
64#endif
65
66rtems_isr Clock_isr(
67  rtems_vector_number vector
68)
69{
70 /*
71  *  The counter register gets reset automatically as well as the
72  *  interrupt occurred flag so we should not have to do anything
73  *  with the hardware.
74  */
75
76 /*
77  *  Bump the number of clock driver ticks since initialization
78  */
79
80 Clock_driver_ticks += 1;
81
82 rtems_clock_tick();
83
84#if FAST_IDLE
85  if ( Clock_in_fast_idle_mode ) {
86    if ( _Thread_Executing == _Thread_Idle && _Thread_Heir != _Thread_Idle ) {
87      c4x_timer_stop( C4X_TIMER_0 );
88      c4x_timer_set_counter( C4X_TIMER_0, 0 );
89      c4x_timer_set_period( C4X_TIMER_0, Clock_counter_register_value );
90      c4x_timer_start( C4X_TIMER_0 );
91      Clock_in_fast_idle_mode = 0;
92    }
93  } else {
94    if ( _Thread_Executing == _Thread_Idle && _Thread_Heir == _Thread_Idle ) {
95      c4x_timer_stop( C4X_TIMER_0 );
96      c4x_timer_set_counter( C4X_TIMER_0, 0 );
97      c4x_timer_set_period( C4X_TIMER_0, Clock_counter_register_value >> 5 );
98      c4x_timer_start( C4X_TIMER_0 );
99    }
100  }
101#endif
102}
103
104/*
105 *  Install_clock
106 *
107 *  Install a clock tick handler and reprograms the chip.  This
108 *  is used to initially establish the clock tick.
109 */
110
111void Install_clock(
112  rtems_isr_entry clock_isr
113)
114{
115  extern int _ClockFrequency;
116  float tmp;
117  int tmpi;
118  /*
119   *  Initialize the clock tick device driver variables
120   */
121
122  Clock_driver_ticks = 0;
123
124  tmpi = ((int) &_ClockFrequency) * 1000000;  /* ClockFrequency is in Mhz */
125  tmp = (float) tmpi / 2.0;
126  tmp = ((float) BSP_Configuration.microseconds_per_tick / 1000000.0) * (tmp);
127
128  Clock_counter_register_value = (unsigned int) tmp;
129#if 0
130  Clock_counter_register_value =
131      (uint32_t) ((float) BSP_Configuration.microseconds_per_tick /
132       ((float)_ClockFrequency / 2.0)));
133#endif
134  c4x_timer_stop( C4X_TIMER_0 );
135  c4x_timer_set_counter( C4X_TIMER_0, 0 );
136  c4x_timer_set_period( C4X_TIMER_0, Clock_counter_register_value );
137  c4x_timer_start( C4X_TIMER_0 );
138
139#if defined(_C4x)
140  c4x_set_iee( c4x_get_iie() | 0x1 );  /* should be ETINT0 */
141#else
142  c3x_set_ie( c3x_get_ie() | 0x100 );
143#endif
144
145  /*
146   *  If ticks_per_timeslice is configured as non-zero, then the user
147   *  wants a clock tick.
148   */
149
150  Old_ticker = (rtems_isr_entry) set_vector( clock_isr, CLOCK_VECTOR, 1 );
151  /*
152   *  Hardware specific initialize goes here
153   */
154
155  /* XXX */
156
157  /*
158   *  Schedule the clock cleanup routine to execute if the application exits.
159   */
160
161  atexit( Clock_exit );
162}
163
164/*
165 *  Clean up before the application exits
166 */
167
168void Clock_exit( void )
169{
170  /* XXX: turn off the timer interrupts */
171
172  /* XXX: If necessary, restore the old vector */
173}
174
175/*
176 *  Clock_initialize
177 *
178 *  Device driver entry point for clock tick driver initialization.
179 */
180
181rtems_device_driver Clock_initialize(
182  rtems_device_major_number major,
183  rtems_device_minor_number minor,
184  void *pargp
185)
186{
187  Install_clock( Clock_isr );
188
189  /*
190   * make major/minor avail to others such as shared memory driver
191   */
192
193  rtems_clock_major = major;
194  rtems_clock_minor = minor;
195
196  return RTEMS_SUCCESSFUL;
197}
198
199rtems_device_driver Clock_control(
200  rtems_device_major_number major,
201  rtems_device_minor_number minor,
202  void *pargp
203)
204{
205    uint32_t         isrlevel;
206    rtems_libio_ioctl_args_t *args = pargp;
207
208    if (args == 0)
209        goto done;
210
211    /*
212     * This is hokey, but until we get a defined interface
213     * to do this, it will just be this simple...
214     */
215
216    if (args->command == rtems_build_name('I', 'S', 'R', ' '))
217    {
218        Clock_isr(CLOCK_VECTOR);
219    }
220    else if (args->command == rtems_build_name('N', 'E', 'W', ' '))
221    {
222      rtems_interrupt_disable( isrlevel );
223       (void) set_vector( args->buffer, CLOCK_VECTOR, 1 );
224      rtems_interrupt_enable( isrlevel );
225    }
226
227done:
228    return RTEMS_SUCCESSFUL;
229}
Note: See TracBrowser for help on using the repository browser.