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

4.104.114.84.95
Last change on this file since f05b2ac was f05b2ac, checked in by Ralf Corsepius <ralf.corsepius@…>, on 04/21/04 at 16:01:48

Remove duplicate white lines.

  • 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 *  Isr Handler
58 */
59
60#define FAST_IDLE 1
61#if FAST_IDLE
62int Clock_in_fast_idle_mode = 0;
63#endif
64
65rtems_isr Clock_isr(
66  rtems_vector_number vector
67)
68{
69 /*
70  *  The counter register gets reset automatically as well as the
71  *  interrupt occurred flag so we should not have to do anything
72  *  with the hardware.
73  */
74
75 /*
76  *  Bump the number of clock driver ticks since initialization
77  */
78
79 Clock_driver_ticks += 1;
80
81 rtems_clock_tick();
82
83#if FAST_IDLE
84  if ( Clock_in_fast_idle_mode ) {
85    if ( _Thread_Executing == _Thread_Idle && _Thread_Heir != _Thread_Idle ) {
86      c4x_timer_stop( C4X_TIMER_0 );
87      c4x_timer_set_counter( C4X_TIMER_0, 0 );
88      c4x_timer_set_period( C4X_TIMER_0, Clock_counter_register_value );
89      c4x_timer_start( C4X_TIMER_0 );
90      Clock_in_fast_idle_mode = 0;
91    }
92  } else {
93    if ( _Thread_Executing == _Thread_Idle && _Thread_Heir == _Thread_Idle ) {
94      c4x_timer_stop( C4X_TIMER_0 );
95      c4x_timer_set_counter( C4X_TIMER_0, 0 );
96      c4x_timer_set_period( C4X_TIMER_0, Clock_counter_register_value >> 5 );
97      c4x_timer_start( C4X_TIMER_0 );
98    }
99  }
100#endif
101}
102
103/*
104 *  Install_clock
105 *
106 *  Install a clock tick handler and reprograms the chip.  This
107 *  is used to initially establish the clock tick.
108 */
109
110void Install_clock(
111  rtems_isr_entry clock_isr
112)
113{
114  extern int _ClockFrequency;
115  float tmp;
116  int tmpi;
117  /*
118   *  Initialize the clock tick device driver variables
119   */
120
121  Clock_driver_ticks = 0;
122
123  tmpi = ((int) &_ClockFrequency) * 1000000;  /* ClockFrequency is in Mhz */
124  tmp = (float) tmpi / 2.0;
125  tmp = ((float) BSP_Configuration.microseconds_per_tick / 1000000.0) * (tmp);
126
127  Clock_counter_register_value = (unsigned int) tmp;
128#if 0
129  Clock_counter_register_value =
130      (uint32_t) ((float) BSP_Configuration.microseconds_per_tick /
131       ((float)_ClockFrequency / 2.0)));
132#endif
133  c4x_timer_stop( C4X_TIMER_0 );
134  c4x_timer_set_counter( C4X_TIMER_0, 0 );
135  c4x_timer_set_period( C4X_TIMER_0, Clock_counter_register_value );
136  c4x_timer_start( C4X_TIMER_0 );
137
138#if defined(_C4x)
139  c4x_set_iee( c4x_get_iie() | 0x1 );  /* should be ETINT0 */
140#else
141  c3x_set_ie( c3x_get_ie() | 0x100 );
142#endif
143
144  /*
145   *  If ticks_per_timeslice is configured as non-zero, then the user
146   *  wants a clock tick.
147   */
148
149  Old_ticker = (rtems_isr_entry) set_vector( clock_isr, CLOCK_VECTOR, 1 );
150  /*
151   *  Hardware specific initialize goes here
152   */
153
154  /* XXX */
155
156  /*
157   *  Schedule the clock cleanup routine to execute if the application exits.
158   */
159
160  atexit( Clock_exit );
161}
162
163/*
164 *  Clean up before the application exits
165 */
166
167void Clock_exit( void )
168{
169  /* XXX: turn off the timer interrupts */
170
171  /* XXX: If necessary, restore the old vector */
172}
173
174/*
175 *  Clock_initialize
176 *
177 *  Device driver entry point for clock tick driver initialization.
178 */
179
180rtems_device_driver Clock_initialize(
181  rtems_device_major_number major,
182  rtems_device_minor_number minor,
183  void *pargp
184)
185{
186  Install_clock( Clock_isr );
187
188  /*
189   * make major/minor avail to others such as shared memory driver
190   */
191
192  rtems_clock_major = major;
193  rtems_clock_minor = minor;
194
195  return RTEMS_SUCCESSFUL;
196}
197
198rtems_device_driver Clock_control(
199  rtems_device_major_number major,
200  rtems_device_minor_number minor,
201  void *pargp
202)
203{
204    uint32_t         isrlevel;
205    rtems_libio_ioctl_args_t *args = pargp;
206
207    if (args == 0)
208        goto done;
209
210    /*
211     * This is hokey, but until we get a defined interface
212     * to do this, it will just be this simple...
213     */
214
215    if (args->command == rtems_build_name('I', 'S', 'R', ' '))
216    {
217        Clock_isr(CLOCK_VECTOR);
218    }
219    else if (args->command == rtems_build_name('N', 'E', 'W', ' '))
220    {
221      rtems_interrupt_disable( isrlevel );
222       (void) set_vector( args->buffer, CLOCK_VECTOR, 1 );
223      rtems_interrupt_enable( isrlevel );
224    }
225
226done:
227    return RTEMS_SUCCESSFUL;
228}
Note: See TracBrowser for help on using the repository browser.