source: rtems/c/src/lib/libcpu/m68k/mcf5206/clock/ckinit.c @ 62f48b3

4.104.114.84.95
Last change on this file since 62f48b3 was 00717a3, checked in by Joel Sherrill <joel.sherrill@…>, on 10/26/01 at 19:32:40

2001-10-26 Victor V. Vengerov <vvv@…>

  • New libcpu support for mcf5206e.
  • ChangeLog?, clock/ckinit.c, clock/.cvsignore, configure.ac, console/mcfuart.c, console/.cvsignore, include/mcf5206e.h, include/mcfmbus.h, include/mcfuart.h, include/.cvsignore, mbus/mcfmbus.c, mbus/.cvsignore, timer/timer.c, timer/timerisr.S, timer/.cvsignore, .cvsignore: New files.
  • Property mode set to 100644
File size: 5.9 KB
Line 
1/*
2 *  Clock Driver for MCF5206eLITE board
3 *
4 *  This driver initailizes timer1 on the MCF5206E as the
5 *  main system clock
6 *
7 *  Author: Victor V. Vengerov <vvv@oktet.ru>
8 *
9 *  Based on work:
10 *    David Fiddes, D.J@fiddes.surfaid.org
11 *    http://www.calm.hw.ac.uk/davidf/coldfire/
12 *
13 *  COPYRIGHT (c) 1989-1998.
14 *  On-Line Applications Research Corporation (OAR).
15 *  Copyright assigned to U.S. Government, 1994.
16 *
17 *  The license and distribution terms for this file may be
18 *  found in the file LICENSE in this distribution or at
19 *
20 *  http://www.OARcorp.com/rtems/license.html.
21 *
22 *  $Id$
23 */
24
25#include <stdlib.h>
26#include <bsp.h>
27#include <rtems/libio.h>
28#include "mcf5206/mcf5206e.h"
29
30/*
31 * Clock_driver_ticks is a monotonically increasing counter of the
32 * number of clock ticks since the driver was initialized.
33 */
34volatile rtems_unsigned32 Clock_driver_ticks;
35
36
37/*
38 * These are set by clock driver during its init
39 */
40 
41rtems_device_major_number rtems_clock_major = ~0;
42rtems_device_minor_number rtems_clock_minor;
43
44rtems_isr (*rtems_clock_hook)(rtems_vector_number) = NULL;
45
46/* Clock_isr --
47 *     This handles the timer interrupt by clearing the timer's interrupt
48 *     flag and announcing the clock tick to the system.
49 *
50 * PARAMETERS:
51 *     vector - timer interrupt vector number
52 *
53 * RETURNS:
54 *     none
55 */
56rtems_isr
57Clock_isr (rtems_vector_number vector)
58{
59  /* Clear pending interrupt... */
60  *MCF5206E_TER(MBAR,1) = MCF5206E_TER_REF | MCF5206E_TER_CAP;
61
62  /* Announce the clock tick */
63  Clock_driver_ticks++;
64  rtems_clock_tick();
65  if (rtems_clock_hook != NULL)
66      rtems_clock_hook(vector);
67}
68
69
70/* Clock_exit --
71 *     This shuts down the timer if it was enabled and removes it
72 *     from the MCF5206E interrupt mask.
73 *
74 * PARAMETERS:
75 *     none
76 *
77 * RETURNS:
78 *     none
79 */
80void
81Clock_exit(void)
82{
83    if (BSP_Configuration.ticks_per_timeslice)
84    {
85        /* disable all timer1 interrupts */
86        *MCF5206E_IMR(MBAR) |= MCF5206E_INTR_BIT(MCF5206E_INTR_TIMER_1);
87
88        /* reset timer1 */
89        *MCF5206E_TMR(MBAR,1) = MCF5206E_TMR_ICLK_STOP;
90
91        /* clear pending */
92        *MCF5206E_TER(MBAR,1) = MCF5206E_TER_REF | MCF5206E_TER_CAP;
93    }
94}
95
96
97/* Install_clock --
98 *     This initialises timer1 with the BSP timeslice config value
99 *     as a reference and sets up the interrupt handler for clock ticks.
100 *
101 * PARAMETERS:
102 *     clock_isr - clock interrupt handler routine
103 *
104 * RETURNS:
105 *     none.
106 */
107static void
108Install_clock(rtems_isr_entry clock_isr)
109{
110    Clock_driver_ticks = 0;
111    if (BSP_Configuration.ticks_per_timeslice)
112    {
113        /* Configure timer1 interrupts */
114        *MCF5206E_ICR(MBAR,MCF5206E_INTR_TIMER_1) =
115            MCF5206E_ICR_AVEC |
116            ((BSP_INTLVL_TIMER1 << MCF5206E_ICR_IL_S) & MCF5206E_ICR_IL) |
117            ((BSP_INTPRIO_TIMER1 << MCF5206E_ICR_IP_S) & MCF5206E_ICR_IP);
118       
119        /* Register the interrupt handler */
120        set_vector(clock_isr, BSP_INTVEC_TIMER1, 1);
121       
122        /* Reset timer 1 */
123        *MCF5206E_TMR(MBAR, 1) = MCF5206E_TMR_RST;
124        *MCF5206E_TMR(MBAR, 1) = MCF5206E_TMR_ICLK_STOP;
125        *MCF5206E_TMR(MBAR, 1) = MCF5206E_TMR_RST;
126        *MCF5206E_TCN(MBAR, 1) = 0; /* Reset counter */
127        *MCF5206E_TER(MBAR, 1) = MCF5206E_TER_REF | MCF5206E_TER_CAP;
128       
129        /* Set Timer 1 prescaler so that it counts in microseconds */
130        *MCF5206E_TMR(MBAR, 1) =
131            (((BSP_SYSTEM_FREQUENCY/1000000 - 1) << MCF5206E_TMR_PS_S) &
132             MCF5206E_TMR_PS) |
133            MCF5206E_TMR_CE_NONE | MCF5206E_TMR_ORI | MCF5206E_TMR_FRR |
134            MCF5206E_TMR_RST;
135           
136        /* Set the timer timeout value from the BSP config */     
137        *MCF5206E_TRR(MBAR, 1) = BSP_Configuration.microseconds_per_tick - 1;
138
139        /* Feed system frequency to the timer */
140        *MCF5206E_TMR(MBAR, 1) |= MCF5206E_TMR_ICLK_MSCLK;
141           
142        /* Enable timer 1 interrupts */
143        *MCF5206E_IMR(MBAR) &= ~MCF5206E_INTR_BIT(MCF5206E_INTR_TIMER_1);
144       
145        /* Register the driver exit procedure so we can shutdown */
146        atexit(Clock_exit);
147    }
148}
149
150
151/* Clock_initialize --
152 *     This is called to setup the clock driver. It calls the hardware
153 *     setup function and make the driver major/minor values available
154 *     for other.
155 *
156 * PARAMETERS:
157 *     major - clock device major number
158 *     minor - clock device minor number
159 *     pargp - device driver initialization argument (not used)
160 *
161 * RETURNS:
162 *     RTEMS status code
163 */
164rtems_device_driver
165Clock_initialize(rtems_device_major_number major,
166                 rtems_device_minor_number minor,
167                 void *pargp)
168{
169    Install_clock (Clock_isr);
170 
171    /* Make major/minor avail to others such as shared memory driver */
172    rtems_clock_major = major;
173    rtems_clock_minor = minor;
174 
175    return RTEMS_SUCCESSFUL;
176}
177 
178
179/* Clock_control --
180 *     I/O control (IOCTL) function for Clock driver. At this moment this
181 *     just runs the interrupt handler or re-registers the interrupt handler
182 *     on request.
183 *
184 * PARAMETERS:
185 *     major - clock major device number
186 *     minor - clock minor device number
187 *     pargp - pointer to IOCTL arguments
188 *
189 * RETURNS:
190 *     RTEMS status code
191 */
192rtems_device_driver
193Clock_control(rtems_device_major_number major,
194              rtems_device_minor_number minor,
195              void *pargp)
196{
197    rtems_unsigned32 isrlevel;
198    rtems_libio_ioctl_args_t *args = pargp;
199
200    if (args)
201    {
202        /*
203         * This is hokey, but until we get a defined interface
204         * to do this, it will just be this simple...
205         */
206        if (args->command == rtems_build_name('I', 'S', 'R', ' '))
207        {
208            Clock_isr(BSP_INTVEC_TIMER1);
209        }
210        else if (args->command == rtems_build_name('N', 'E', 'W', ' '))
211        {
212            rtems_interrupt_disable( isrlevel );
213            (void) set_vector( args->buffer, BSP_INTVEC_TIMER1, 1 );
214            rtems_interrupt_enable( isrlevel );
215        }
216    }
217    return RTEMS_SUCCESSFUL;
218}
Note: See TracBrowser for help on using the repository browser.