source: rtems/c/src/lib/libbsp/m68k/idp/clock/ckinit.c @ 60b791ad

4.104.114.84.95
Last change on this file since 60b791ad was 60b791ad, checked in by Joel Sherrill <joel.sherrill@…>, on Feb 17, 1998 at 11:46:28 PM

updated copyright to 1998

  • Property mode set to 100644
File size: 4.9 KB
Line 
1/*  Clock_init()
2 *
3 *
4 *  This is modified by Doug McBride to get it to work for the MC68EC040
5 *  IDP board.  The below comments are kept to show that some prior work
6 *  was done in the area and the modifications performed was application
7 *  specific for the IDP board to port it to.
8 *
9 *  This routine initializes the mc68230 on the MC68EC040 board.
10 *  The tick frequency is 40 milliseconds.
11 *
12 *  Input parameters:  NONE
13 *
14 *  Output parameters:  NONE
15 *
16 *  COPYRIGHT (c) 1989-1998.
17 *  On-Line Applications Research Corporation (OAR).
18 *  Copyright assigned to U.S. Government, 1994.
19 *
20 *  The license and distribution terms for this file may be
21 *  found in the file LICENSE in this distribution or at
22 *  http://www.OARcorp.com/rtems/license.html.
23 *
24 *  $Id$
25 */
26
27#include <stdlib.h>
28
29#include <bsp.h>
30#include <rtems/libio.h>
31
32rtems_unsigned32 Clock_isrs;        /* ISRs until next tick */
33volatile rtems_unsigned32 Clock_driver_ticks;
34                                    /* ticks since initialization */
35rtems_isr_entry  Old_ticker;
36
37extern rtems_configuration_table Configuration;
38extern void led_putnum();
39void Disable_clock();
40
41#define CLOCK_VECTOR 0x4D
42
43void Clock_exit( void );
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/*
54 *  ISR Handler
55 *
56 *
57 * ((1ms * 6.5 MHz) / 2^5) = 203.125) where 6.5 MHz is the clock rate of the
58 * MC68230, 2^5 is the prescaler factor, and 1ms is the common interrupt
59 * interval for the Clock_isr routine.
60 * Therefore, 203 (decimal) is the number to program into the CPRH-L registers
61 * of the MC68230 for countdown.  However, I have found that 193 instead of
62 * 203 provides greater accuracy -- why?  The crystal should be more accurate
63 * than that
64 */
65
66rtems_isr Clock_isr(
67  rtems_vector_number vector
68)
69{
70  Clock_driver_ticks += 1;
71  /* acknowledge interrupt
72        TSR = 1; */
73  MC68230_WRITE (TSR, 1);
74
75  if ( Clock_isrs == 1 ) {
76    rtems_clock_tick();
77        /* Cast to an integer so that 68EC040 IDP which doesn't have an FPU doesn't
78           have a heart attack -- if you use newlib1.6 or greater and get
79           libgcc.a for gcc with software floating point support, this is not
80           a problem */
81    Clock_isrs = 
82      (int)(BSP_Configuration.microseconds_per_tick / 1000);
83  }
84  else 
85    Clock_isrs -= 1;
86}
87
88void Disable_clock()
89{
90        /* Disable timer */
91        MC68230_WRITE (TCR, 0x00);
92}
93
94void Install_clock( clock_isr )
95rtems_isr_entry clock_isr;
96{
97  Clock_driver_ticks = 0;
98  Clock_isrs = (int)(Configuration.microseconds_per_tick / 1000);
99
100  if ( Configuration.ticks_per_timeslice ) {
101/*    led_putnum('c'); * for debugging purposes */
102    Old_ticker = (rtems_isr_entry) set_vector( clock_isr, CLOCK_VECTOR, 1 );
103
104        /* Disable timer for initialization */
105        MC68230_WRITE (TCR, 0x00);
106
107        /* some PI/T initialization stuff here -- see comment in the ckisr.c
108           file in this directory to understand why I use the values that I do */
109        /* Set up the interrupt vector on the MC68230 chip:
110                TIVR = CLOCK_VECTOR; */
111        MC68230_WRITE (TIVR, CLOCK_VECTOR);
112
113        /* Set CPRH through CPRL to 193 (not 203) decimal for countdown--see ckisr.c
114                CPRH = 0x00;
115                CPRM = 0x00;
116                CPRL = 0xC1; */
117        MC68230_WRITE (CPRH, 0x00);
118        MC68230_WRITE (CPRM, 0x00);
119        MC68230_WRITE (CPRL, 0xC1);
120
121        /* Enable timer and use it as an external periodic interrupt generator
122                TCR = 0xA1; */
123/*    led_putnum('a'); * for debugging purposes */
124        MC68230_WRITE (TCR, 0xA1);
125
126        /*
127         *  Schedule the clock cleanup routine to execute if the application exits.
128         */
129    atexit( Clock_exit );
130  } 
131}
132
133/* The following was added for debugging purposes */
134void Clock_exit( void )
135{
136  rtems_unsigned8 data;
137
138  if ( Configuration.ticks_per_timeslice ) {
139
140        /* disable timer
141                data = TCR;
142                TCR = (data & 0xFE); */
143        MC68230_READ (TCR, data);
144        MC68230_WRITE (TCR, (data & 0xFE));
145
146    /* do not restore old vector */
147  }
148}
149
150rtems_device_driver Clock_initialize(
151  rtems_device_major_number major,
152  rtems_device_minor_number minor,
153  void *pargp
154)
155{
156  Install_clock( Clock_isr );
157 
158  /*
159   * make major/minor avail to others such as shared memory driver
160   */
161 
162  rtems_clock_major = major;
163  rtems_clock_minor = minor;
164 
165  return RTEMS_SUCCESSFUL;
166}
167 
168rtems_device_driver Clock_control(
169  rtems_device_major_number major,
170  rtems_device_minor_number minor,
171  void *pargp
172)
173{
174    rtems_unsigned32 isrlevel;
175    rtems_libio_ioctl_args_t *args = pargp;
176 
177    if (args == 0)
178        goto done;
179 
180    /*
181     * This is hokey, but until we get a defined interface
182     * to do this, it will just be this simple...
183     */
184 
185    if (args->command == rtems_build_name('I', 'S', 'R', ' '))
186    {
187        Clock_isr(CLOCK_VECTOR);
188    }
189    else if (args->command == rtems_build_name('N', 'E', 'W', ' '))
190    {
191      rtems_interrupt_disable( isrlevel );
192       (void) set_vector( args->buffer, CLOCK_VECTOR, 1 );
193      rtems_interrupt_enable( isrlevel );
194    }
195 
196done:
197    return RTEMS_SUCCESSFUL;
198}
199
Note: See TracBrowser for help on using the repository browser.