source: rtems/c/src/lib/libbsp/m68k/idp/clock/ckinit.c @ 0dd1d44

4.104.114.84.95
Last change on this file since 0dd1d44 was 0dd1d44, checked in by Joel Sherrill <joel.sherrill@…>, on Jan 11, 2000 at 5:34:20 PM

Removed old hack of using Configuration Table entry ticks_per_timeslice
being set to 0 to indicate that there should be no Clock Tick. This
was used by the Timing Tests to avoid clock tick overhead perturbing
execution times. Now the Timing Tests simply leave the Clock Tick
Driver out of the Device Driver Table.

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