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

Last change on this file since b160bf9 was b160bf9, checked in by Joel Sherrill <joel.sherrill@…>, on Sep 4, 2003 at 5:32:14 PM

2003-09-04 Joel Sherrill <joel@…>

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